Merge tag 'jdk-11.0.15-ga' Added tag jdk-11.0.15-ga for changeset 224e1a3fcb2c Bug: 228249482 Test: treehugger Change-Id: I43553f34c2903f9285283ecb6e88b8f18e3c78eb
diff --git a/.github/workflows/submit.yml b/.github/workflows/submit.yml index 5c5bbed..2bf641d 100644 --- a/.github/workflows/submit.yml +++ b/.github/workflows/submit.yml
@@ -174,7 +174,7 @@ - name: Install dependencies run: | sudo apt-get update - sudo apt-get install gcc-9=9.3.0-17ubuntu1~20.04 g++-9=9.3.0-17ubuntu1~20.04 libxrandr-dev libxtst-dev libcups2-dev libasound2-dev + sudo apt-get install gcc-9=9.4.0-1ubuntu1~20.04.1 g++-9=9.4.0-1ubuntu1~20.04.1 libxrandr-dev libxtst-dev libcups2-dev libasound2-dev sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 100 --slave /usr/bin/g++ g++ /usr/bin/g++-9 - name: Configure @@ -341,6 +341,7 @@ run: > if ! grep --include=test-summary.txt -lqr build/*/test-results -e "TEST SUCCESS" ; then cat build/*/test-results/*/text/newfailures.txt ; + cat build/*/test-results/*/text/other_errors.txt ; exit 1 ; fi @@ -495,12 +496,12 @@ - name: Install native host dependencies run: | - sudo apt-get install gcc-9=9.3.0-17ubuntu1~20.04 g++-9=9.3.0-17ubuntu1~20.04 libxrandr-dev libxtst-dev libcups2-dev libasound2-dev + sudo apt-get install gcc-9=9.4.0-1ubuntu1~20.04.1 g++-9=9.4.0-1ubuntu1~20.04.1 libxrandr-dev libxtst-dev libcups2-dev libasound2-dev sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 100 --slave /usr/bin/g++ g++ /usr/bin/g++-9 if: matrix.debian-arch == '' - name: Install cross-compilation host dependencies - run: sudo apt-get install gcc-9-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-flavor}}=9.3.0-17ubuntu1~20.04cross2 g++-9-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-flavor}}=9.3.0-17ubuntu1~20.04cross2 + run: sudo apt-get install gcc-9-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-flavor}}=9.4.0-1ubuntu1~20.04.1cross2 g++-9-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-flavor}}=9.4.0-1ubuntu1~20.04.1cross2 if: matrix.debian-arch != '' - name: Cache sysroot @@ -809,6 +810,7 @@ run: > if ! grep --include=test-summary.txt -lqr build/*/test-results -e "TEST SUCCESS" ; then cat build/*/test-results/*/text/newfailures.txt ; + cat build/*/test-results/*/text/other_errors.txt ; exit 1 ; fi @@ -887,7 +889,7 @@ run: | New-Item -Force -ItemType directory -Path "$HOME\cygwin" & curl -L "https://www.cygwin.com/setup-x86_64.exe" -o "$HOME/cygwin/setup-x86_64.exe" - Start-Process -FilePath "$HOME\cygwin\setup-x86_64.exe" -ArgumentList "--quiet-mode --packages autoconf,make,zip,unzip --root $HOME\cygwin\cygwin64 --local-package-dir $HOME\cygwin\packages --site http://mirrors.kernel.org/sourceware/cygwin --no-desktop --no-shortcuts --no-startmenu --no-admin" -Wait -NoNewWindow + Start-Process -FilePath "$HOME\cygwin\setup-x86_64.exe" -ArgumentList "--quiet-mode --packages cygwin=3.2.0-1,autoconf,make,zip,unzip --root $HOME\cygwin\cygwin64 --local-package-dir $HOME\cygwin\packages --site http://mirrors.kernel.org/sourceware/cygwin --no-desktop --no-shortcuts --no-startmenu --no-admin" -Wait -NoNewWindow - name: Checkout the source uses: actions/checkout@v2 @@ -1051,7 +1053,7 @@ run: | New-Item -Force -ItemType directory -Path "$HOME\cygwin" & curl -L "https://www.cygwin.com/setup-x86_64.exe" -o "$HOME/cygwin/setup-x86_64.exe" - Start-Process -FilePath "$HOME\cygwin\setup-x86_64.exe" -ArgumentList "--quiet-mode --packages autoconf,make,zip,unzip --root $HOME\cygwin\cygwin64 --local-package-dir $HOME\cygwin\packages --site http://mirrors.kernel.org/sourceware/cygwin --no-desktop --no-shortcuts --no-startmenu --no-admin" -Wait -NoNewWindow + Start-Process -FilePath "$HOME\cygwin\setup-x86_64.exe" -ArgumentList "--quiet-mode --packages cygwin=3.2.0-1,autoconf,make,zip,unzip --root $HOME\cygwin\cygwin64 --local-package-dir $HOME\cygwin\packages --site http://mirrors.kernel.org/sourceware/cygwin --no-desktop --no-shortcuts --no-startmenu --no-admin" -Wait -NoNewWindow - name: Restore jtreg artifact id: jtreg_restore @@ -1124,6 +1126,7 @@ run: > if ((Get-ChildItem -Path build\*\test-results\test-summary.txt -Recurse | Select-String -Pattern "TEST SUCCESS" ).Count -eq 0) { Get-Content -Path build\*\test-results\*\*\newfailures.txt ; + Get-Content -Path build\*\test-results\*\*\other_errors.txt ; exit 1 } @@ -1409,6 +1412,7 @@ run: > if ! grep --include=test-summary.txt -lqr build/*/test-results -e "TEST SUCCESS" ; then cat build/*/test-results/*/text/newfailures.txt ; + cat build/*/test-results/*/text/other_errors.txt ; exit 1 ; fi
diff --git a/.jcheck/conf b/.jcheck/conf index 887b27d..0dd4c39 100644 --- a/.jcheck/conf +++ b/.jcheck/conf
@@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=11.0.13 +version=11.0.15 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace
diff --git a/doc/building.html b/doc/building.html index 0310d90..345fbb6 100644 --- a/doc/building.html +++ b/doc/building.html
@@ -686,11 +686,24 @@ <li><p>Install cross-compiler on the <em>build</em> system:</p> <pre><code>apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu</code></pre></li> <li><p>Create chroot on the <em>build</em> system, configuring it for <em>target</em> system:</p> -<pre><code>sudo qemu-debootstrap --arch=arm64 --verbose \ - --include=fakeroot,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng12-dev \ - --resolve-deps jessie /chroots/arm64 http://httpredir.debian.org/debian/</code></pre></li> +<pre><code>sudo qemu-debootstrap \ + --arch=arm64 \ + --verbose \ + --include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev \ + --resolve-deps \ + buster \ + ~/sysroot-arm64 \ + http://httpredir.debian.org/debian/</code></pre></li> +<li><p>Make sure the symlinks inside the newly created chroot point to proper locations:</p> +<pre><code>sudo chroot ~/sysroot-arm64 symlinks -cr .</code></pre></li> <li><p>Configure and build with newly created chroot as sysroot/toolchain-path:</p> -<pre><code>CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ sh ./configure --openjdk-target=aarch64-linux-gnu --with-sysroot=/chroots/arm64/ --with-toolchain-path=/chroots/arm64/ +<pre><code>CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ sh ./configure \ + --openjdk-target=aarch64-linux-gnu \ + --with-sysroot=~/sysroot-arm64 \ + --with-toolchain-path=~/sysroot-arm64 \ + --with-freetype-lib=~/sysroot-arm64/usr/lib/aarch64-linux-gnu/ \ + --with-freetype-include=~/sysroot-arm64/usr/include/freetype2/ \ + --x-libraries=~/sysroot-arm64/usr/lib/aarch64-linux-gnu/ make images ls build/linux-aarch64-normal-server-release/</code></pre></li> </ul>
diff --git a/doc/building.md b/doc/building.md index c15389b..e40378e 100644 --- a/doc/building.md +++ b/doc/building.md
@@ -1100,23 +1100,39 @@ For example, cross-compiling to AArch64 from x86_64 could be done like this: * Install cross-compiler on the *build* system: -``` -apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu -``` + ``` + apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu + ``` * Create chroot on the *build* system, configuring it for *target* system: -``` -sudo qemu-debootstrap --arch=arm64 --verbose \ - --include=fakeroot,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng12-dev \ - --resolve-deps jessie /chroots/arm64 http://httpredir.debian.org/debian/ -``` + ``` + sudo qemu-debootstrap \ + --arch=arm64 \ + --verbose \ + --include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev \ + --resolve-deps \ + buster \ + ~/sysroot-arm64 \ + http://httpredir.debian.org/debian/ + ``` + + * Make sure the symlinks inside the newly created chroot point to proper locations: + ``` + sudo chroot ~/sysroot-arm64 symlinks -cr . + ``` * Configure and build with newly created chroot as sysroot/toolchain-path: -``` -CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ sh ./configure --openjdk-target=aarch64-linux-gnu --with-sysroot=/chroots/arm64/ --with-toolchain-path=/chroots/arm64/ -make images -ls build/linux-aarch64-normal-server-release/ -``` + ``` + CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ sh ./configure \ + --openjdk-target=aarch64-linux-gnu \ + --with-sysroot=~/sysroot-arm64 \ + --with-toolchain-path=~/sysroot-arm64 \ + --with-freetype-lib=~/sysroot-arm64/usr/lib/aarch64-linux-gnu/ \ + --with-freetype-include=~/sysroot-arm64/usr/include/freetype2/ \ + --x-libraries=~/sysroot-arm64/usr/lib/aarch64-linux-gnu/ + make images + ls build/linux-aarch64-normal-server-release/ + ``` The build does not create new files in that chroot, so it can be reused for multiple builds without additional cleanup.
diff --git a/doc/testing.html b/doc/testing.html index 6c8cc32..e77ac0e 100644 --- a/doc/testing.html +++ b/doc/testing.html
@@ -27,6 +27,7 @@ <li><a href="#configuration">Configuration</a></li> </ul></li> <li><a href="#test-selection">Test selection</a><ul> +<li><a href="#common-test-groups">Common Test Groups</a></li> <li><a href="#jtreg">JTReg</a></li> <li><a href="#gtest">Gtest</a></li> </ul></li> @@ -59,6 +60,19 @@ <p>All functionality is available using the run-test make target. In this use case, the test or tests to be executed is controlled using the <code>TEST</code> variable. To speed up subsequent test runs with no source code changes, run-test-only can be used instead, which do not depend on the source and test image build.</p> <p>For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that <code>make run-test-tier1</code> is equivalent to <code>make run-test TEST="tier1"</code>, but the latter is more tab-completion friendly. For more complex test runs, the <code>run-test TEST="x"</code> solution needs to be used.</p> <p>The test specifications given in <code>TEST</code> is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an example, <code>:tier1</code> will expand to <code>jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1</code>. You can always submit a list of fully qualified test descriptors in the <code>TEST</code> variable if you want to shortcut the parser.</p> +<h3 id="common-test-groups">Common Test Groups</h3> +<p>Ideally, all tests are run for every change but this may not be practical due to the limited testing resources, the scope of the change, etc.</p> +<p>The source tree currently defines a few common test groups in the relevant <code>TEST.groups</code> files. There are test groups that cover a specific component, for example <code>hotspot_gc</code>. It is a good idea to look into <code>TEST.groups</code> files to get a sense what tests are relevant to a particular JDK component.</p> +<p>Component-specific tests may miss some unintended consequences of a change, so other tests should also be run. Again, it might be impractical to run all tests, and therefore <em>tiered</em> test groups exist. Tiered test groups are not component-specific, but rather cover the significant parts of the entire JDK.</p> +<p>Multiple tiers allow balancing test coverage and testing costs. Lower test tiers are supposed to contain the simpler, quicker and more stable tests. Higher tiers are supposed to contain progressively more thorough, slower, and sometimes less stable tests, or the tests that require special configuration.</p> +<p>Contributors are expected to run the tests for the areas that are changed, and the first N tiers they can afford to run, but at least tier1.</p> +<p>A brief description of the tiered test groups:</p> +<ul> +<li><p><code>tier1</code>: This is the lowest test tier. Multiple developers run these tests every day. Because of the widespread use, the tests in <code>tier1</code> are carefully selected and optimized to run fast, and to run in the most stable manner. The test failures in <code>tier1</code> are usually followed up on quickly, either with fixes, or adding relevant tests to problem list. GitHub Actions workflows, if enabled, run <code>tier1</code> tests.</p></li> +<li><p><code>tier2</code>: This test group covers even more ground. These contain, among other things, tests that either run for too long to be at <code>tier1</code>, or may require special configuration, or tests that are less stable, or cover the broader range of non-core JVM and JDK features/components (for example, XML).</p></li> +<li><p><code>tier3</code>: This test group includes more stressful tests, the tests for corner cases not covered by previous tiers, plus the tests that require GUIs. As such, this suite should either be run with low concurrency (<code>TEST_JOBS=1</code>), or without headful tests (<code>JTREG_KEYWORDS=\!headful</code>), or both.</p></li> +<li><p><code>tier4</code>: This test group includes every other test not covered by previous tiers. It includes, for example, <code>vmTestbase</code> suites for Hotspot, which run for many hours even on large machines. It also runs GUI tests, so the same <code>TEST_JOBS</code> and <code>JTREG_KEYWORDS</code> caveats apply.</p></li> +</ul> <h3 id="jtreg">JTReg</h3> <p>JTReg tests can be selected either by picking a JTReg test group, or a selection of files or directories containing JTReg tests.</p> <p>JTReg test groups can be specified either without a test root, e.g. <code>:tier1</code> (or <code>tier1</code>, the initial colon is optional), or with, e.g. <code>hotspot:tier1</code>, <code>test/jdk:jdk_util</code> or <code>$(TOPDIR)/test/hotspot/jtreg:hotspot_all</code>. The test root can be specified either as an absolute path, or a path relative to the JDK top directory, or the <code>test</code> directory. For simplicity, the hotspot JTReg test root, which really is <code>hotspot/jtreg</code> can be abbreviated as just <code>hotspot</code>.</p> @@ -142,6 +156,8 @@ <p>Additional VM options to JTReg (<code>-vmoption</code>).</p> <h4 id="aot_modules-1">AOT_MODULES</h4> <p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p> +<h4 id="retry_count">RETRY_COUNT</h4> +<p>Retry failed tests up to a set number of times. Defaults to 0.</p> <h3 id="gtest-keywords">Gtest keywords</h3> <h4 id="repeat">REPEAT</h4> <p>The number of times to repeat the tests (<code>--gtest_repeat</code>).</p>
diff --git a/doc/testing.md b/doc/testing.md index fe2b1c7..34b5b8e 100644 --- a/doc/testing.md +++ b/doc/testing.md
@@ -52,6 +52,52 @@ always submit a list of fully qualified test descriptors in the `TEST` variable if you want to shortcut the parser. +### Common Test Groups + +Ideally, all tests are run for every change but this may not be practical due to the limited +testing resources, the scope of the change, etc. + +The source tree currently defines a few common test groups in the relevant `TEST.groups` +files. There are test groups that cover a specific component, for example `hotspot_gc`. +It is a good idea to look into `TEST.groups` files to get a sense what tests are relevant +to a particular JDK component. + +Component-specific tests may miss some unintended consequences of a change, so other +tests should also be run. Again, it might be impractical to run all tests, and therefore +_tiered_ test groups exist. Tiered test groups are not component-specific, but rather cover +the significant parts of the entire JDK. + +Multiple tiers allow balancing test coverage and testing costs. Lower test tiers are supposed to +contain the simpler, quicker and more stable tests. Higher tiers are supposed to contain +progressively more thorough, slower, and sometimes less stable tests, or the tests that require +special configuration. + +Contributors are expected to run the tests for the areas that are changed, and the first N tiers +they can afford to run, but at least tier1. + +A brief description of the tiered test groups: + +- `tier1`: This is the lowest test tier. Multiple developers run these tests every day. +Because of the widespread use, the tests in `tier1` are carefully selected and optimized to run +fast, and to run in the most stable manner. The test failures in `tier1` are usually followed up +on quickly, either with fixes, or adding relevant tests to problem list. GitHub Actions workflows, +if enabled, run `tier1` tests. + +- `tier2`: This test group covers even more ground. These contain, among other things, +tests that either run for too long to be at `tier1`, or may require special configuration, +or tests that are less stable, or cover the broader range of non-core JVM and JDK features/components +(for example, XML). + +- `tier3`: This test group includes more stressful tests, the tests for corner cases +not covered by previous tiers, plus the tests that require GUIs. As such, this suite +should either be run with low concurrency (`TEST_JOBS=1`), or without headful tests +(`JTREG_KEYWORDS=\!headful`), or both. + +- `tier4`: This test group includes every other test not covered by previous tiers. It includes, +for example, `vmTestbase` suites for Hotspot, which run for many hours even on large +machines. It also runs GUI tests, so the same `TEST_JOBS` and `JTREG_KEYWORDS` caveats +apply. + ### JTReg JTReg tests can be selected either by picking a JTReg test group, or a selection @@ -269,6 +315,10 @@ modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value `%20`). +#### RETRY_COUNT + +Retry failed tests up to a set number of times. Defaults to 0. + ### Gtest keywords #### REPEAT
diff --git a/make/RunTests.gmk b/make/RunTests.gmk index 05153cb..7fa66ea 100644 --- a/make/RunTests.gmk +++ b/make/RunTests.gmk
@@ -276,7 +276,7 @@ $(eval $(call ParseKeywordVariable, JTREG, \ SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR TEST_MODE ASSERT VERBOSE RETAIN \ - MAX_MEM, \ + MAX_MEM RETRY_COUNT, \ STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS KEYWORDS \ EXTRA_PROBLEM_LISTS AOT_MODULES, \ )) @@ -312,8 +312,6 @@ nashorn_JTREG_PROBLEM_LIST += $(TOPDIR)/test/nashorn/ProblemList.txt hotspot_JTREG_PROBLEM_LIST += $(TOPDIR)/test/hotspot/jtreg/ProblemList.txt -langtools_JTREG_MAX_MEM := 768m - ################################################################################ # Parse test selection # @@ -627,7 +625,7 @@ # Convert JTREG_foo into $1_JTREG_foo with a suitable value. $$(eval $$(call SetJtregValue,$1,JTREG_TEST_MODE,agentvm)) $$(eval $$(call SetJtregValue,$1,JTREG_ASSERT,true)) - $$(eval $$(call SetJtregValue,$1,JTREG_MAX_MEM,512m)) + $$(eval $$(call SetJtregValue,$1,JTREG_MAX_MEM,768m)) $$(eval $$(call SetJtregValue,$1,JTREG_NATIVEPATH)) $$(eval $$(call SetJtregValue,$1,JTREG_BASIC_OPTIONS)) $$(eval $$(call SetJtregValue,$1,JTREG_PROBLEM_LIST)) @@ -643,7 +641,7 @@ # Make sure MaxRAMPercentage is high enough to not cause OOM or swapping since # we may end up with a lot of JVM's - $1_JTREG_MAX_RAM_PERCENTAGE := $$(shell $$(EXPR) 25 / $$($1_JTREG_JOBS)) + $1_JTREG_MAX_RAM_PERCENTAGE := $$(shell $(AWK) 'BEGIN { print 25 / $$($1_JTREG_JOBS); }') # SPARC is in general slower per core so need to scale up timeouts a bit. ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) @@ -653,6 +651,7 @@ endif JTREG_VERBOSE ?= fail,error,summary JTREG_RETAIN ?= fail,error + JTREG_RETRY_COUNT ?= 0 ifneq ($$($1_JTREG_MAX_MEM), 0) $1_JTREG_BASIC_OPTIONS += -vmoption:-Xmx$$($1_JTREG_MAX_MEM) @@ -742,24 +741,43 @@ clean-workdir-$1: $$(RM) -r $$($1_TEST_SUPPORT_DIR) + $1_COMMAND_LINE := \ + $$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \ + -Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \ + $$($1_JTREG_BASIC_OPTIONS) \ + -testjdk:$$(JDK_IMAGE_DIR) \ + -dir:$$(JTREG_TOPDIR) \ + -reportDir:$$($1_TEST_RESULTS_DIR) \ + -workDir:$$($1_TEST_SUPPORT_DIR) \ + -status:$$$${JTREG_STATUS} \ + $$(JTREG_OPTIONS) \ + $$(JTREG_FAILURE_HANDLER_OPTIONS) \ + $$($1_TEST_NAME) \ + && $$(ECHO) $$$$? > $$($1_EXITCODE) \ + || $$(ECHO) $$$$? > $$($1_EXITCODE) + + + ifneq ($$(JTREG_RETRY_COUNT), 0) + $1_COMMAND_LINE := \ + for i in {0..$$(JTREG_RETRY_COUNT)}; do \ + if [ "$$$$i" != 0 ]; then \ + $$(PRINTF) "\nRetrying Jtreg run. Attempt: $$$$i\n"; \ + fi; \ + $$($1_COMMAND_LINE); \ + if [ "`$$(CAT) $$($1_EXITCODE)`" = "0" ]; then \ + break; \ + fi; \ + export JTREG_STATUS="-status:error,fail"; \ + done + endif + run-test-$1: clean-workdir-$1 $$($1_AOT_TARGETS) $$(call LogWarn) $$(call LogWarn, Running test '$$($1_TEST)') $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR) \ $$($1_TEST_TMP_DIR)) $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/jtreg, ( \ - $$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \ - -Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \ - $$($1_JTREG_BASIC_OPTIONS) \ - -testjdk:$$(JDK_IMAGE_DIR) \ - -dir:$$(JTREG_TOPDIR) \ - -reportDir:$$($1_TEST_RESULTS_DIR) \ - -workDir:$$($1_TEST_SUPPORT_DIR) \ - $$(JTREG_OPTIONS) \ - $$(JTREG_FAILURE_HANDLER_OPTIONS) \ - $$($1_TEST_NAME) \ - && $$(ECHO) $$$$? > $$($1_EXITCODE) \ - || $$(ECHO) $$$$? > $$($1_EXITCODE) \ + $$($1_COMMAND_LINE) \ )) $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt
diff --git a/make/RunTestsPrebuilt.gmk b/make/RunTestsPrebuilt.gmk index 737f9ce..63af249 100644 --- a/make/RunTestsPrebuilt.gmk +++ b/make/RunTestsPrebuilt.gmk
@@ -230,7 +230,7 @@ NUM_CORES := $(shell /usr/sbin/sysctl -n hw.ncpu) MEMORY_SIZE := $(shell $(EXPR) `/usr/sbin/sysctl -n hw.memsize` / 1024 / 1024) else ifeq ($(OPENJDK_TARGET_OS), solaris) - NUM_CORES := $(shell LC_MESSAGES=C /usr/sbin/psrinfo -v | $(GREP) -c on-line) + NUM_CORES := $(shell /usr/sbin/psrinfo -v | $(GREP) -c on-line) MEMORY_SIZE := $(shell \ /usr/sbin/prtconf 2> /dev/null | $(GREP) "^Memory [Ss]ize" | $(AWK) '{print $$3}' \ )
diff --git a/make/RunTestsPrebuiltSpec.gmk b/make/RunTestsPrebuiltSpec.gmk index 6d07505..c8ac271 100644 --- a/make/RunTestsPrebuiltSpec.gmk +++ b/make/RunTestsPrebuiltSpec.gmk
@@ -27,6 +27,9 @@ # Fake minimalistic spec file for RunTestsPrebuilt.gmk. ################################################################################ +# Make sure all shell commands are executed with the C locale +export LC_ALL := C + define VerifyVariable ifeq ($$($1), ) $$(info Error: Variable $1 is missing, needed by RunTestPrebuiltSpec.gmk)
diff --git a/make/ToolsJdk.gmk b/make/ToolsJdk.gmk index 3c87cb3..8a442fd 100644 --- a/make/ToolsJdk.gmk +++ b/make/ToolsJdk.gmk
@@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -73,9 +73,9 @@ TOOL_TZDB = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ build.tools.tzdb.TzdbZoneRulesCompiler -TOOL_BLACKLISTED_CERTS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ +TOOL_BLOCKED_CERTS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ --add-exports java.base/sun.security.util=ALL-UNNAMED \ - build.tools.blacklistedcertsconverter.BlacklistedCertsConverter + build.tools.blockedcertsconverter.BlockedCertsConverter TOOL_MAKEJAVASECURITY = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ build.tools.makejavasecurity.MakeJavaSecurity
diff --git a/make/autoconf/basics.m4 b/make/autoconf/basics.m4 index 1b793d7..3761c7e 100644 --- a/make/autoconf/basics.m4 +++ b/make/autoconf/basics.m4
@@ -405,7 +405,7 @@ # Save the path variable before it gets changed ORIGINAL_PATH="$PATH" AC_SUBST(ORIGINAL_PATH) - DATE_WHEN_CONFIGURED=`LANG=C date` + DATE_WHEN_CONFIGURED=`date` AC_SUBST(DATE_WHEN_CONFIGURED) AC_MSG_NOTICE([Configuration created at $DATE_WHEN_CONFIGURED.]) ]) @@ -673,6 +673,16 @@ ]) ############################################################################### +# Evaluates platform specific overrides for build devkit variables. +# $1: Name of variable +AC_DEFUN([BASIC_EVAL_BUILD_DEVKIT_VARIABLE], +[ + if test "x[$]$1" = x; then + eval $1="\${$1_${OPENJDK_BUILD_CPU}}" + fi +]) + +############################################################################### AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT], [ AC_ARG_WITH([devkit], [AS_HELP_STRING([--with-devkit],
diff --git a/make/autoconf/basics_windows.m4 b/make/autoconf/basics_windows.m4 index e8b51e4..c1cc7a6 100644 --- a/make/autoconf/basics_windows.m4 +++ b/make/autoconf/basics_windows.m4
@@ -381,10 +381,44 @@ # called fixpath. FIXPATH= if test "x$OPENJDK_BUILD_OS" = xwindows; then - AC_MSG_CHECKING([if fixpath can be created]) FIXPATH_SRC="$TOPDIR/make/src/native/fixpath.c" - FIXPATH_BIN="$CONFIGURESUPPORT_OUTPUTDIR/bin/fixpath.exe" FIXPATH_DIR="$CONFIGURESUPPORT_OUTPUTDIR/fixpath" + + if test "x$OPENJDK_TARGET_CPU" != "xaarch64"; then + AC_MSG_CHECKING([if fixpath can be created]) + + FIXPATH_BIN="$CONFIGURESUPPORT_OUTPUTDIR/bin/fixpath.exe" + FIXPATH_SRC_W="$FIXPATH_SRC" + FIXPATH_BIN_W="$FIXPATH_BIN" + BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_SRC_W]) + BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_BIN_W]) + $RM -rf $FIXPATH_BIN $FIXPATH_DIR + $MKDIR -p $FIXPATH_DIR $CONFIGURESUPPORT_OUTPUTDIR/bin + cd $FIXPATH_DIR + $CC $FIXPATH_SRC_W -Fe$FIXPATH_BIN_W > $FIXPATH_DIR/fixpath1.log 2>&1 + cd $CURDIR + + if test ! -x $FIXPATH_BIN; then + AC_MSG_RESULT([no]) + cat $FIXPATH_DIR/fixpath1.log + AC_MSG_ERROR([Could not create $FIXPATH_BIN]) + fi + AC_MSG_RESULT([yes]) + + else # OPENJDK_TARGET_CPU is aarch64 + AC_MSG_CHECKING([if fixpath is in place]) + + FIXPATH_BIN="$TOPDIR/fixpath.exe" + $RM -rf $FIXPATH_DIR + $MKDIR -p $FIXPATH_DIR + + if test ! -x $FIXPATH_BIN; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([Could not find fixpath.exe under $TOPDIR]) + fi + AC_MSG_RESULT([yes]) + fi + if test "x$OPENJDK_BUILD_OS_ENV" = xwindows.cygwin; then # Important to keep the .exe suffix on Cygwin for Hotspot makefiles FIXPATH="$FIXPATH_BIN -c" @@ -396,22 +430,7 @@ fixpath_argument_list=`echo $all_unique_prefixes | tr ' ' '@'` FIXPATH="$FIXPATH_BIN -m$fixpath_argument_list" fi - FIXPATH_SRC_W="$FIXPATH_SRC" - FIXPATH_BIN_W="$FIXPATH_BIN" - BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_SRC_W]) - BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_BIN_W]) - $RM -rf $FIXPATH_BIN $FIXPATH_DIR - $MKDIR -p $FIXPATH_DIR $CONFIGURESUPPORT_OUTPUTDIR/bin - cd $FIXPATH_DIR - $CC $FIXPATH_SRC_W -Fe$FIXPATH_BIN_W > $FIXPATH_DIR/fixpath1.log 2>&1 - cd $CURDIR - if test ! -x $FIXPATH_BIN; then - AC_MSG_RESULT([no]) - cat $FIXPATH_DIR/fixpath1.log - AC_MSG_ERROR([Could not create $FIXPATH_BIN]) - fi - AC_MSG_RESULT([yes]) AC_MSG_CHECKING([if fixpath.exe works]) cd $FIXPATH_DIR $FIXPATH $CC $FIXPATH_SRC -Fe$FIXPATH_DIR/fixpath2.exe \
diff --git a/make/autoconf/build-aux/config.guess b/make/autoconf/build-aux/config.guess index ec17740..6c027dc 100644 --- a/make/autoconf/build-aux/config.guess +++ b/make/autoconf/build-aux/config.guess
@@ -1,6 +1,7 @@ #!/bin/sh # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, Azul Systems, 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 @@ -97,6 +98,23 @@ fi fi +# Test and fix LoongArch64. +if [ "x$OUT" = x ]; then + if [ `uname -s` = Linux ]; then + if [ `uname -m` = loongarch64 ]; then + OUT=loongarch64-unknown-linux-gnu + fi + fi +fi + +# Test and fix cpu on macos-aarch64, uname -p reports arm, buildsys expects aarch64 +echo $OUT | grep arm-apple-darwin > /dev/null 2> /dev/null +if test $? = 0; then + if [ `uname -m` = arm64 ]; then + OUT=aarch64`echo $OUT | sed -e 's/[^-]*//'` + fi +fi + # Test and fix cpu on Macosx when C preprocessor is not on the path echo $OUT | grep i386-apple-darwin > /dev/null 2> /dev/null if test $? = 0; then
diff --git a/make/autoconf/build-performance.m4 b/make/autoconf/build-performance.m4 index 0731da2..dbda3ab 100644 --- a/make/autoconf/build-performance.m4 +++ b/make/autoconf/build-performance.m4
@@ -35,7 +35,7 @@ FOUND_CORES=yes elif test -x /usr/sbin/psrinfo; then # Looks like a Solaris system - NUM_CORES=`LC_MESSAGES=C /usr/sbin/psrinfo -v | grep -c on-line` + NUM_CORES=`/usr/sbin/psrinfo -v | grep -c on-line` FOUND_CORES=yes elif test -x /usr/sbin/sysctl; then # Looks like a MacOSX system
diff --git a/make/autoconf/configure b/make/autoconf/configure index f1b7e63..abd4f18 100644 --- a/make/autoconf/configure +++ b/make/autoconf/configure
@@ -43,6 +43,9 @@ export CONFIG_SHELL=$BASH export _as_can_reexec=no +# Make sure all shell commands are executed with the C locale +export LC_ALL=C + if test "x$CUSTOM_CONFIG_DIR" != x; then custom_hook=$CUSTOM_CONFIG_DIR/custom-hook.m4 if test ! -e $custom_hook; then
diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index a5c91ea..d326585 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4
@@ -391,16 +391,6 @@ CFLAGS="$CFLAGS_OLD" CXXFLAGS="$CXXFLAGS_OLD" - # Tests are only ever compiled for TARGET - CFLAGS_TESTLIB="$CFLAGS_JDKLIB" - CXXFLAGS_TESTLIB="$CXXFLAGS_JDKLIB" - CFLAGS_TESTEXE="$CFLAGS_JDKEXE" - CXXFLAGS_TESTEXE="$CXXFLAGS_JDKEXE" - - AC_SUBST(CFLAGS_TESTLIB) - AC_SUBST(CFLAGS_TESTEXE) - AC_SUBST(CXXFLAGS_TESTLIB) - AC_SUBST(CXXFLAGS_TESTEXE) ]) ################################################################################ @@ -705,7 +695,9 @@ $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -DcpuIntel -Di586 -D$FLAGS_CPU_LEGACY_LIB" fi elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then - if test "x$FLAGS_CPU" = xx86_64; then + if test "x$FLAGS_CPU" = xaarch64; then + $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_ARM64_ -Darm64" + elif test "x$FLAGS_CPU" = xx86_64; then $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_AMD64_ -Damd64" else $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_X86_ -Dx86"
diff --git a/make/autoconf/flags-ldflags.m4 b/make/autoconf/flags-ldflags.m4 index 8d2bf89..0ef152b 100644 --- a/make/autoconf/flags-ldflags.m4 +++ b/make/autoconf/flags-ldflags.m4
@@ -51,9 +51,7 @@ FLAGS_SETUP_LDFLAGS_CPU_DEP([BUILD], [OPENJDK_BUILD_]) - LDFLAGS_TESTLIB="$LDFLAGS_JDKLIB" - LDFLAGS_TESTEXE="$LDFLAGS_JDKEXE ${TARGET_LDFLAGS_JDK_LIBPATH}" - AC_SUBST(LDFLAGS_TESTLIB) + LDFLAGS_TESTEXE="${TARGET_LDFLAGS_JDK_LIBPATH}" AC_SUBST(LDFLAGS_TESTEXE) ]) @@ -194,12 +192,14 @@ $1_CPU_LDFLAGS_JVM_ONLY="-xarch=sparc" fi - elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then if test "x${OPENJDK_$1_CPU}" = "xx86"; then $1_CPU_LDFLAGS="-safeseh" # NOTE: Old build added -machine. Probably not needed. $1_CPU_LDFLAGS_JVM_ONLY="-machine:I386" $1_CPU_EXECUTABLE_LDFLAGS="-stack:327680" + elif test "x${OPENJDK_$1_CPU}" = "xaarch64"; then + $1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576" else $1_CPU_LDFLAGS_JVM_ONLY="-machine:AMD64" $1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576"
diff --git a/make/autoconf/flags.m4 b/make/autoconf/flags.m4 index 6f55353..e9d440b 100644 --- a/make/autoconf/flags.m4 +++ b/make/autoconf/flags.m4
@@ -111,19 +111,25 @@ [ # Additional macosx handling if test "x$OPENJDK_TARGET_OS" = xmacosx; then + # The expected format for <version> is either nn.n.n or nn.nn.nn. See + # /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/AvailabilityVersions.h + # MACOSX_VERSION_MIN specifies the lowest version of Macosx that the built # binaries should be compatible with, even if compiled on a newer version # of the OS. It currently has a hard coded value. Setting this also limits # exposure to API changes in header files. Bumping this is likely to # require code changes to build. - MACOSX_VERSION_MIN=10.9.0 + if test "x$OPENJDK_TARGET_CPU_ARCH" = xaarch64; then + MACOSX_VERSION_MIN=11.00.00 + else + MACOSX_VERSION_MIN=10.9.0 + fi MACOSX_VERSION_MIN_NODOTS=${MACOSX_VERSION_MIN//\./} AC_SUBST(MACOSX_VERSION_MIN) # Setting --with-macosx-version-max=<version> makes it an error to build or - # link to macosx APIs that are newer than the given OS version. The expected - # format for <version> is either nn.n.n or nn.nn.nn. See /usr/include/AvailabilityMacros.h. + # link to macosx APIs that are newer than the given OS version. AC_ARG_WITH([macosx-version-max], [AS_HELP_STRING([--with-macosx-version-max], [error on use of newer functionality. @<:@macosx@:>@])], [ @@ -258,6 +264,14 @@ fi fi + if test "x$OPENJDK_TARGET_OS" = xmacosx; then + if test "x$OPENJDK_TARGET_CPU" = xaarch64; then + MACHINE_FLAG="$MACHINE_FLAG -arch arm64" + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then + MACHINE_FLAG="$MACHINE_FLAG -arch x86_64" + fi + fi + # FIXME: global flags are not used yet... # The "global" flags will *always* be set. Without them, it is not possible to # get a working compilation.
diff --git a/make/autoconf/help.m4 b/make/autoconf/help.m4 index bc05fc8..447f293 100644 --- a/make/autoconf/help.m4 +++ b/make/autoconf/help.m4
@@ -90,7 +90,7 @@ devkit) PKGHANDLER_COMMAND="sudo apt-get install build-essential" ;; openjdk) - PKGHANDLER_COMMAND="sudo apt-get install openjdk-8-jdk" ;; + PKGHANDLER_COMMAND="sudo apt-get install openjdk-11-jdk" ;; alsa) PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;; cups) @@ -117,7 +117,7 @@ devkit) PKGHANDLER_COMMAND="sudo yum groupinstall \"Development Tools\"" ;; openjdk) - PKGHANDLER_COMMAND="sudo yum install java-1.8.0-openjdk-devel" ;; + PKGHANDLER_COMMAND="sudo yum install java-11-openjdk-devel" ;; alsa) PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;; cups)
diff --git a/make/autoconf/hotspot.m4 b/make/autoconf/hotspot.m4 index d598b98..5a3adf6 100644 --- a/make/autoconf/hotspot.m4 +++ b/make/autoconf/hotspot.m4
@@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -221,7 +221,7 @@ if test "x$ENABLE_AOT" = "xtrue"; then # Only enable AOT on X64 platforms. - if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then + if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64" ; then if test -e "${TOPDIR}/src/jdk.aot"; then if test -e "${TOPDIR}/src/jdk.internal.vm.compiler"; then ENABLE_AOT="true" @@ -240,7 +240,7 @@ else ENABLE_AOT="false" if test "x$enable_aot" = "xyes"; then - AC_MSG_ERROR([AOT is currently only supported on x86_64 and aarch64. Remove --enable-aot.]) + AC_MSG_ERROR([AOT is currently only supported on x86_64 and linux-aarch64. Remove --enable-aot.]) fi fi fi @@ -274,6 +274,14 @@ fi fi + # Disable CDS on macos-aarch64 + if test "x$OPENJDK_TARGET_OS" = "xmacosx" && test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then + ENABLE_CDS="false" + if test "x$enable_cds" = "xyes"; then + AC_MSG_ERROR([CDS is currently not supported on macOS/aarch64. Remove --enable-cds.]) + fi + fi + AC_SUBST(ENABLE_CDS) ]) @@ -355,7 +363,8 @@ # Only enable Shenandoah on supported arches, and only if requested AC_MSG_CHECKING([if shenandoah can be built]) if HOTSPOT_CHECK_JVM_FEATURE(shenandoahgc); then - if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86" || test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then + if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86" || \ + test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then AC_MSG_RESULT([yes]) else DISABLED_JVM_FEATURES="$DISABLED_JVM_FEATURES shenandoahgc" @@ -443,10 +452,11 @@ JVM_FEATURES_graal="graal" INCLUDE_GRAAL="true" else - # By default enable graal build on x64 or where AOT is available. + # By default enable graal build on x64/aarch64 or where AOT is available. # graal build requires jvmci. if test "x$JVM_FEATURES_jvmci" = "xjvmci" && \ (test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \ + test "x$OPENJDK_TARGET_CPU" = "xaarch64" || \ test "x$ENABLE_AOT" = "xtrue") ; then AC_MSG_RESULT([yes]) JVM_FEATURES_graal="graal"
diff --git a/make/autoconf/platform.m4 b/make/autoconf/platform.m4 index edbb54d..95bdbb2 100644 --- a/make/autoconf/platform.m4 +++ b/make/autoconf/platform.m4
@@ -66,6 +66,12 @@ VAR_CPU_BITS=64 VAR_CPU_ENDIAN=little ;; + loongarch64) + VAR_CPU=loongarch64 + VAR_CPU_ARCH=loongarch + VAR_CPU_BITS=64 + VAR_CPU_ENDIAN=little + ;; m68k) VAR_CPU=m68k VAR_CPU_ARCH=m68k @@ -114,6 +120,12 @@ VAR_CPU_BITS=64 VAR_CPU_ENDIAN=little ;; + riscv64) + VAR_CPU=riscv64 + VAR_CPU_ARCH=riscv + VAR_CPU_BITS=64 + VAR_CPU_ENDIAN=little + ;; s390) VAR_CPU=s390 VAR_CPU_ARCH=s390 @@ -510,6 +522,8 @@ HOTSPOT_$1_CPU_DEFINE=S390 elif test "x$OPENJDK_$1_CPU" = xs390x; then HOTSPOT_$1_CPU_DEFINE=S390 + elif test "x$OPENJDK_$1_CPU" = xriscv64; then + HOTSPOT_$1_CPU_DEFINE=RISCV elif test "x$OPENJDK_$1_CPU" != x; then HOTSPOT_$1_CPU_DEFINE=$(echo $OPENJDK_$1_CPU | tr a-z A-Z) fi
diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index 39b4439..0ae23b9 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in
@@ -46,6 +46,9 @@ # What make to use for main processing, after bootstrapping top-level Makefile. MAKE := @MAKE@ +# Make sure all shell commands are executed with the C locale +export LC_ALL := C + # The default make arguments MAKE_ARGS = $(MAKE_LOG_FLAGS) -r -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \ MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" $(MAKE_LOG_VARS) @@ -508,11 +511,6 @@ LIBCXX:=@LIBCXX@ # Compiler and linker flags used when building native tests -CFLAGS_TESTLIB:=@CFLAGS_TESTLIB@ -CXXFLAGS_TESTLIB:=@CXXFLAGS_TESTLIB@ -CFLAGS_TESTEXE:=@CFLAGS_TESTEXE@ -CXXFLAGS_TESTEXE:=@CXXFLAGS_TESTEXE@ -LDFLAGS_TESTLIB:=@LDFLAGS_TESTLIB@ LDFLAGS_TESTEXE:=@LDFLAGS_TESTEXE@ # BUILD_CC/BUILD_LD is a compiler/linker that generates code that is runnable on the
diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4 index 3c0286d..24c9d37 100644 --- a/make/autoconf/toolchain.m4 +++ b/make/autoconf/toolchain.m4
@@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -229,7 +229,7 @@ if test "x$OPENJDK_TARGET_OS" = xmacosx; then if test -n "$XCODEBUILD"; then # On Mac OS X, default toolchain to clang after Xcode 5 - XCODE_VERSION_OUTPUT=`"$XCODEBUILD" -version 2>&1 | $HEAD -n 1` + XCODE_VERSION_OUTPUT=`"$XCODEBUILD" -version | $HEAD -n 1` $ECHO "$XCODE_VERSION_OUTPUT" | $GREP "Xcode " > /dev/null if test $? -ne 0; then AC_MSG_ERROR([Failed to determine Xcode version.]) @@ -918,14 +918,18 @@ . $CONFIGURESUPPORT_OUTPUTDIR/build-devkit.info # This potentially sets the following: # A descriptive name of the devkit - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_NAME]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_NAME]) # Corresponds to --with-extra-path - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_EXTRA_PATH]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_EXTRA_PATH]) # Corresponds to --with-toolchain-path - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_TOOLCHAIN_PATH]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_TOOLCHAIN_PATH]) # Corresponds to --with-sysroot - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_SYSROOT]) - # Skip the Window specific parts + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_SYSROOT]) + + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_VS_INCLUDE]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_VS_LIB]) + fi fi AC_MSG_CHECKING([for build platform devkit]) @@ -935,13 +939,22 @@ AC_MSG_RESULT([$BUILD_DEVKIT_ROOT]) fi - BUILD_SYSROOT="$BUILD_DEVKIT_SYSROOT" + PATH="$BUILD_DEVKIT_EXTRA_PATH:$PATH" - # Fallback default of just /bin if DEVKIT_PATH is not defined + # Fallback default of just /bin if DEVKIT_PATH is not defined if test "x$BUILD_DEVKIT_TOOLCHAIN_PATH" = x; then BUILD_DEVKIT_TOOLCHAIN_PATH="$BUILD_DEVKIT_ROOT/bin" fi - PATH="$BUILD_DEVKIT_TOOLCHAIN_PATH:$BUILD_DEVKIT_EXTRA_PATH" + PATH="$BUILD_DEVKIT_TOOLCHAIN_PATH:$PATH" + + BUILD_SYSROOT="$BUILD_DEVKIT_SYSROOT" + + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + BUILD_VS_INCLUDE="$BUILD_DEVKIT_VS_INCLUDE" + BUILD_VS_LIB="$BUILD_DEVKIT_VS_LIB" + + TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS([BUILD_]) + fi fi fi @@ -967,9 +980,37 @@ BASIC_FIXUP_EXECUTABLE(BUILD_STRIP) # Assume the C compiler is the assembler BUILD_AS="$BUILD_CC -c" - # Just like for the target compiler, use the compiler as linker - BUILD_LD="$BUILD_CC" - BUILD_LDCXX="$BUILD_CXX" + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + # In the Microsoft toolchain we have a separate LD command "link". + # Make sure we reject /usr/bin/link (as determined in CYGWIN_LINK), which is + # a cygwin program for something completely different. + AC_CHECK_PROG([BUILD_LD], [link$EXE_SUFFIX],[link$EXE_SUFFIX],,, [$CYGWIN_LINK]) + BASIC_FIXUP_EXECUTABLE(BUILD_LD) + # Verify that we indeed succeeded with this trick. + AC_MSG_CHECKING([if the found link.exe is actually the Visual Studio linker]) + + # Reset PATH since it can contain a mix of WSL/linux paths and Windows paths from VS, + # which, in combination with WSLENV, will make the WSL layer complain + old_path="$PATH" + PATH= + + "$BUILD_LD" --version > /dev/null + + if test $? -eq 0 ; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([This is the Cygwin link tool. Please check your PATH and rerun configure.]) + else + AC_MSG_RESULT([yes]) + fi + + PATH="$old_path" + + BUILD_LDCXX="$BUILD_LD" + else + # Just like for the target compiler, use the compiler as linker + BUILD_LD="$BUILD_CC" + BUILD_LDCXX="$BUILD_CXX" + fi PATH="$OLDPATH" @@ -1025,6 +1066,10 @@ if test "x$COMPILER_CPU_TEST" != "xx64"; then AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "x64".]) fi + elif test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then + if test "x$COMPILER_CPU_TEST" != "xARM64"; then + AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "arm64".]) + fi fi fi
diff --git a/make/autoconf/toolchain_windows.m4 b/make/autoconf/toolchain_windows.m4 index 0fafb09..4fe760b 100644 --- a/make/autoconf/toolchain_windows.m4 +++ b/make/autoconf/toolchain_windows.m4
@@ -126,11 +126,15 @@ if test -d "$VS_BASE"; then AC_MSG_NOTICE([Found Visual Studio installation at $VS_BASE using $METHOD]) - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + if test "x$OPENJDK_TARGET_CPU" = xx86; then VCVARSFILES="vc/bin/vcvars32.bat vc/auxiliary/build/vcvars32.bat" - else + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then VCVARSFILES="vc/bin/amd64/vcvars64.bat vc/bin/x86_amd64/vcvarsx86_amd64.bat \ vc/auxiliary/build/vcvarsx86_amd64.bat vc/auxiliary/build/vcvars64.bat" + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + # for host x86-64, target aarch64 + VCVARSFILES="vc/auxiliary/build/vcvarsamd64_arm64.bat \ + vc/auxiliary/build/vcvarsx86_arm64.bat" fi for VCVARSFILE in $VCVARSFILES; do @@ -170,10 +174,12 @@ elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then AC_MSG_NOTICE([Found Windows SDK installation at $WIN_SDK_BASE using $METHOD]) VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + if test "x$OPENJDK_TARGET_CPU" = xx86; then VS_ENV_ARGS="/x86" - else + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then VS_ENV_ARGS="/x64" + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + VS_ENV_ARGS="/arm64" fi # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK @@ -489,41 +495,7 @@ AC_SUBST(VS_INCLUDE) AC_SUBST(VS_LIB) - # Convert VS_INCLUDE into SYSROOT_CFLAGS - OLDIFS="$IFS" - IFS=";" - for i in $VS_INCLUDE; do - ipath=$i - # Only process non-empty elements - if test "x$ipath" != x; then - IFS="$OLDIFS" - # Check that directory exists before calling fixup_path - testpath=$ipath - BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) - if test -d "$testpath"; then - BASIC_FIXUP_PATH([ipath]) - SYSROOT_CFLAGS="$SYSROOT_CFLAGS -I$ipath" - fi - IFS=";" - fi - done - # Convert VS_LIB into SYSROOT_LDFLAGS - for i in $VS_LIB; do - libpath=$i - # Only process non-empty elements - if test "x$libpath" != x; then - IFS="$OLDIFS" - # Check that directory exists before calling fixup_path - testpath=$libpath - BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) - if test -d "$testpath"; then - BASIC_FIXUP_PATH([libpath]) - SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS -libpath:$libpath" - fi - IFS=";" - fi - done - IFS="$OLDIFS" + TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS fi else AC_MSG_RESULT([not found]) @@ -560,10 +532,15 @@ CORRECT_MSVCR_ARCH="PE32+ executable" fi else - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + if test "x$OPENJDK_TARGET_CPU" = xx86; then CORRECT_MSVCR_ARCH=386 - else + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then CORRECT_MSVCR_ARCH=x86-64 + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + # The cygwin 'file' command only returns "PE32+ executable (DLL) (console), for MS Windows", + # without specifying which architecture it is for specifically. This has been fixed upstream. + # https://github.com/file/file/commit/b849b1af098ddd530094bf779b58431395db2e10#diff-ff2eced09e6860de75057dd731d092aeR142 + CORRECT_MSVCR_ARCH="PE32+ executable" fi fi if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then @@ -583,26 +560,26 @@ DLL_NAME="$1" MSVC_DLL= + if test "x$OPENJDK_TARGET_CPU" = xx86; then + vs_target_cpu=x86 + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then + vs_target_cpu=x64 + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + vs_target_cpu=arm64 + fi + if test "x$MSVC_DLL" = x; then if test "x$VCINSTALLDIR" != x; then CYGWIN_VC_INSTALL_DIR="$VCINSTALLDIR" BASIC_FIXUP_PATH(CYGWIN_VC_INSTALL_DIR) if test "$VS_VERSION" -lt 2017; then # Probe: Using well-known location from Visual Studio 12.0 and older - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" - else - POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" - fi + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/$vs_target_cpu/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" else CYGWIN_VC_TOOLS_REDIST_DIR="$VCToolsRedistDir" BASIC_FIXUP_PATH(CYGWIN_VC_TOOLS_REDIST_DIR) # Probe: Using well-known location from VS 2017 and VS 2019 - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`" - else - POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`" - fi + POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/$vs_target_cpu/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`" fi # In case any of the above finds more than one file, loop over them. for possible_msvc_dll in $POSSIBLE_MSVC_DLL; do @@ -634,13 +611,8 @@ if test "x$VS100COMNTOOLS" != x; then CYGWIN_VS_TOOLS_DIR="$VS100COMNTOOLS/.." BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_VS_TOOLS_DIR) - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ - | $GREP -i /x64/ | $HEAD --lines 1` - else - POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ - | $GREP -i /x86/ | $HEAD --lines 1` - fi + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /$vs_target_cpu/ | $HEAD --lines 1` TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], [search of VS100COMNTOOLS]) fi @@ -650,17 +622,17 @@ # Probe: Search wildly in the VCINSTALLDIR. We've probably lost by now. # (This was the original behaviour; kept since it might turn something up) if test "x$CYGWIN_VC_INSTALL_DIR" != x; then - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + if test "x$OPENJDK_TARGET_CPU" = xx86; then POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ - | $GREP x64 | $HEAD --lines 1` - else - POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ - | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1` + | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $GREP -v arm64 | $HEAD --lines 1` if test "x$POSSIBLE_MSVC_DLL" = x; then # We're grasping at straws now... POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ | $HEAD --lines 1` fi + else + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP $vs_target_cpu | $HEAD --lines 1` fi TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], @@ -744,8 +716,12 @@ CYGWIN_WINDOWSSDKDIR="${WINDOWSSDKDIR}" BASIC_FIXUP_PATH([CYGWIN_WINDOWSSDKDIR]) dll_subdir=$OPENJDK_TARGET_CPU - if test "x$dll_subdir" = "xx86_64"; then + if test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then + dll_subdir="arm64" + elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then dll_subdir="x64" + elif test "x$OPENJDK_TARGET_CPU" = "xx86"; then + dll_subdir="x86" fi UCRT_DLL_DIR="$CYGWIN_WINDOWSSDKDIR/Redist/ucrt/DLLs/$dll_subdir" if test -z "$(ls -d "$UCRT_DLL_DIR/"*.dll 2> /dev/null)"; then @@ -768,3 +744,49 @@ fi AC_SUBST(UCRT_DLL_DIR) ]) + +# Setup the sysroot flags and add them to global CFLAGS and LDFLAGS so +# that configure can use them while detecting compilers. +# TOOLCHAIN_TYPE is available here. +# Param 1 - Optional prefix to all variables. (e.g BUILD_) +AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS], +[ + # Convert $1VS_INCLUDE into $1SYSROOT_CFLAGS + OLDIFS="$IFS" + IFS=";" + for i in [$]$1VS_INCLUDE; do + ipath=$i + # Only process non-empty elements + if test "x$ipath" != x; then + IFS="$OLDIFS" + # Check that directory exists before calling fixup_path + testpath=$ipath + BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) + if test -d "$testpath"; then + BASIC_FIXUP_PATH([ipath]) + $1SYSROOT_CFLAGS="[$]$1SYSROOT_CFLAGS -I$ipath" + fi + IFS=";" + fi + done + # Convert $1VS_LIB into $1SYSROOT_LDFLAGS + for i in [$]$1VS_LIB; do + libpath=$i + # Only process non-empty elements + if test "x$libpath" != x; then + IFS="$OLDIFS" + # Check that directory exists before calling fixup_path + testpath=$libpath + BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) + if test -d "$testpath"; then + BASIC_FIXUP_PATH([libpath]) + $1SYSROOT_LDFLAGS="[$]$1SYSROOT_LDFLAGS -libpath:$libpath" + fi + IFS=";" + fi + done + IFS="$OLDIFS" + + AC_SUBST($1SYSROOT_CFLAGS) + AC_SUBST($1SYSROOT_LDFLAGS) +])
diff --git a/make/autoconf/version-numbers b/make/autoconf/version-numbers index 0b32476..7cf5a91 100644 --- a/make/autoconf/version-numbers +++ b/make/autoconf/version-numbers
@@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=11 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=13 +DEFAULT_VERSION_UPDATE=15 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2021-10-19 +DEFAULT_VERSION_DATE=2022-04-19 DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="10 11"
diff --git a/make/common/JavaCompilation.gmk b/make/common/JavaCompilation.gmk index aed23b1..515d4bb 100644 --- a/make/common/JavaCompilation.gmk +++ b/make/common/JavaCompilation.gmk
@@ -121,7 +121,7 @@ $1_CLEAN_$$($2_TARGET) := 1 $$($1_BIN)$$($1_MODULE_SUBDIR)$$($2_TARGET) : $2 $(MKDIR) -p $$(@D) - export LC_ALL=C ; ( $(CAT) $$< && $(ECHO) "" ) \ + ( $(CAT) $$< && $(ECHO) "" ) \ | $(SED) -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' \ -e 's/\([^\\]\)!/\1\\!/g' -e 's/^[ ]*#.*/#/g' \ | $(SED) -f "$(TOPDIR)/make/common/support/unicode2x.sed" \
diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index 490a7f4..e040d3a 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk
@@ -1213,7 +1213,7 @@ # This only works if the openjdk_codesign identity is present on the system. Let # silently fail otherwise. ifneq ($(CODESIGN), ) - $(CODESIGN) -s "$(MACOSX_CODESIGN_IDENTITY)" --timestamp --options runtime \ + $(CODESIGN) -f -s "$(MACOSX_CODESIGN_IDENTITY)" --timestamp --options runtime \ --entitlements $$(call GetEntitlementsFile, $$@) $$@ endif endif
diff --git a/make/common/TestFilesCompilation.gmk b/make/common/TestFilesCompilation.gmk index d4d9c6f..74d2058 100644 --- a/make/common/TestFilesCompilation.gmk +++ b/make/common/TestFilesCompilation.gmk
@@ -60,14 +60,16 @@ ifeq ($$($1_TYPE), LIBRARY) $1_PREFIX = lib $1_OUTPUT_SUBDIR := lib - $1_CFLAGS := $(CFLAGS_TESTLIB) - $1_LDFLAGS := $(LDFLAGS_TESTLIB) $(call SET_SHARED_LIBRARY_ORIGIN) + $1_BASE_CFLAGS := $(CFLAGS_JDKLIB) + $1_BASE_CXXFLAGS := $(CXXFLAGS_JDKLIB) + $1_LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN) $1_COMPILATION_TYPE := LIBRARY else ifeq ($$($1_TYPE), PROGRAM) $1_PREFIX = exe $1_OUTPUT_SUBDIR := bin - $1_CFLAGS := $(CFLAGS_TESTEXE) - $1_LDFLAGS := $(LDFLAGS_TESTEXE) + $1_BASE_CFLAGS := $(CFLAGS_JDKEXE) + $1_BASE_CXXFLAGS := $(CXXFLAGS_JDKEXE) + $1_LDFLAGS := $(LDFLAGS_JDKEXE) $(LDFLAGS_TESTEXE) $1_COMPILATION_TYPE := EXECUTABLE else $$(error Unknown type: $$($1_TYPE)) @@ -75,7 +77,7 @@ # Locate all files with the matching prefix $1_FILE_LIST := \ - $$(call FindFiles, $$($1_SOURCE_DIRS), $$($1_PREFIX)*.c $$($1_PREFIX)*.m) + $$(call FindFiles, $$($1_SOURCE_DIRS), $$($1_PREFIX)*.c $$($1_PREFIX)*.cpp $$($1_PREFIX)*.m) $1_EXCLUDE_PATTERN := $$(addprefix %/, $$($1_EXCLUDE)) $1_FILTERED_FILE_LIST := $$(filter-out $$($1_EXCLUDE_PATTERN), $$($1_FILE_LIST)) @@ -91,9 +93,13 @@ INCLUDE_FILES := $$(notdir $$(file)), \ OBJECT_DIR := $$($1_OUTPUT_DIR)/support/$$(name), \ OUTPUT_DIR := $$($1_OUTPUT_DIR)/$$($1_OUTPUT_SUBDIR), \ - CFLAGS := $$($1_CFLAGS) $$($1_CFLAGS_$$(name)), \ + CFLAGS := $$($1_BASE_CFLAGS) $$($1_CFLAGS) $$($1_CFLAGS_$$(name)), \ + CXXFLAGS := $$($1_BASE_CXXFLAGS) $$($1_CFLAGS) $$($1_CFLAGS_$$(name)), \ LDFLAGS := $$($1_LDFLAGS) $$($1_LDFLAGS_$$(name)), \ + DISABLED_WARNINGS_CXX_solstudio := wvarhidenmem, \ + DISABLED_WARNINGS_CXX_gcc := format, \ LIBS := $$($1_LIBS_$$(name)), \ + TOOLCHAIN := $(if $$(filter %.cpp, $$(file)), TOOLCHAIN_LINK_CXX, TOOLCHAIN_DEFAULT), \ OPTIMIZATION := $$(if $$($1_OPTIMIZATION_$$(name)),$$($1_OPTIMIZATION_$$(name)),LOW), \ COPY_DEBUG_SYMBOLS := false, \ STRIP_SYMBOLS := false, \
diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index f5a77ab..958ccb8 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js
@@ -242,7 +242,7 @@ dependencies: ["boot_jdk", "gnumake", "jtreg", "jib", "autoconf"], default_make_targets: ["product-bundles", "test-bundles", "static-libs-bundles"], configure_args: concat(["--enable-jtreg-failure-handler"], - "--with-exclude-translations=de,es,fr,it,ko,pt_BR,sv,ca,tr,cs,sk,ja_JP_A,ja_JP_HA,ja_JP_HI,ja_JP_I,zh_TW,zh_HK", + "--with-exclude-translations=es,fr,it,ko,pt_BR,sv,ca,tr,cs,sk,ja_JP_A,ja_JP_HA,ja_JP_HI,ja_JP_I,zh_TW,zh_HK", "--disable-manpages", versionArgs(input, common)) }; @@ -854,7 +854,7 @@ var devkit_platform_revisions = { linux_x64: "gcc7.3.0-OEL6.4+1.1", - macosx_x64: "Xcode9.4-MacOSX10.13+1.0", + macosx_x64: "Xcode11.3.1-MacOSX10.15+1.0", solaris_x64: "SS12u4-Solaris11u1+1.0", solaris_sparcv9: "SS12u4-Solaris11u1+1.1", windows_x64: "VS2017-15.9.16+1.0",
diff --git a/make/data/blacklistedcertsconverter/blacklisted.certs.pem b/make/data/blacklistedcertsconverter/blacklisted.certs.pem deleted file mode 100644 index 688becb..0000000 --- a/make/data/blacklistedcertsconverter/blacklisted.certs.pem +++ /dev/null
@@ -1,749 +0,0 @@ -#! java BlacklistedCertsConverter SHA-256 - -# The line above must be the first line of this file. Do not -# remove it. - -// Subject: CN=Digisign Server ID (Enrich), -// OU=457608-K, -// O=Digicert Sdn. Bhd., -// C=MY -// Issuer: CN=GTE CyberTrust Global Root, -// OU=GTE CyberTrust Solutions, Inc., -// O=GTE Corporation, -// C=US -// Serial: 120001705 (07:27:14:a9) ------BEGIN CERTIFICATE----- -MIIDyzCCAzSgAwIBAgIEBycUqTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MB4XDTA3MDcxNzE1MTc0OFoXDTEyMDcxNzE1MTY1NFowYzELMAkG -A1UEBhMCTVkxGzAZBgNVBAoTEkRpZ2ljZXJ0IFNkbi4gQmhkLjERMA8GA1UECxMI -NDU3NjA4LUsxJDAiBgNVBAMTG0RpZ2lzaWduIFNlcnZlciBJRCAoRW5yaWNoKTCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArahkS02Hx4RZufuQRqCmicDx/tXa -VII3DZkrRSYK6Fawf8qo9I5HhAGCKeOzarWR8/uVhbxyqGToCkCcxfRxrnt7agfq -kBRPjYmvlKuyBtQCanuYH1m5Os1U+iDfsioK6bjdaZDAKdNO0JftZszFGUkGf/pe -LHx7hRsyQt97lSUCAwEAAaOCAXgwggF0MBIGA1UdEwEB/wQIMAYBAf8CAQAwXAYD -VR0gBFUwUzBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy -dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMAcGBWCDSgEBMA4GA1Ud -DwEB/wQEAwIB5jCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYTAlVTMRgwFgYD -VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv -bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv -b3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVibGljLXRydXN0 -LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYDVR0OBBYEFMYWk04WF+wW -royUdvOGbcV0boR3MA0GCSqGSIb3DQEBBQUAA4GBAHYAe6Z4K2Ydjl42xqSOBfIj -knyTZ9P0wAp9iy3Z6tVvGvPhSilaIoRNUC9LDPL/hcJ7VdREgr5trGeOvLQfkpxR -gBoU9m6rYYgLrRx/90tQUdZlG6ZHcRVesHHzNRTyN71jyNXwk1o0X9g96F33xR7A -5c8fhiSpPAdmzcHSNmNZ ------END CERTIFICATE----- - -// Subject: CN=Digisign Server ID - (Enrich), -// OU=457608-K, -// O=Digicert Sdn. Bhd., -// C=MY -// Issuer: CN=Entrust.net Certification Authority (2048) -// OU=(c) 1999 Entrust.net Limited, -// OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), -// O=Entrust.net -// Serial: 1184644297 (4c:0e:63:6a) ------BEGIN CERTIFICATE----- -MIIEzjCCA7agAwIBAgIETA5jajANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0xMDA3MTYxNzIzMzdaFw0xNTA3 -MTYxNzUzMzdaMGUxCzAJBgNVBAYTAk1ZMRswGQYDVQQKExJEaWdpY2VydCBTZG4u -IEJoZC4xETAPBgNVBAsTCDQ1NzYwOC1LMSYwJAYDVQQDEx1EaWdpc2lnbiBTZXJ2 -ZXIgSUQgLSAoRW5yaWNoKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AMWJ5PQNBkCSWccaszXRDkwqM/n4r8qef+65p21g9FTob9Wb8xtjMQRoctE0Foy0 -FyyX3nPF2JAVoBor9cuzSIZE8B2ITM5BQhrv9Qze/kDaOSD3BlU6ap1GwdJvpbLI -Vz4po5zg6YV3ZuiYpyR+vsBZIOVEb7ZX2L7OwmV3WMZhQdF0BMh/SULFcqlyFu6M -3RJdtErU0a9Qt9iqdXZorT5dqjBtYairEFs+E78z4K9EnTgiW+9ML6ZxJhUmyiiM -2fqOjqmiFDXimySItPR/hZ2DTwehthSQNsQ0HI0mYW0Tb3i+6I8nx0uElqOGaAwj -vgvsjJQAqQSKE5D334VsDLECAwEAAaOCATQwggEwMA4GA1UdDwEB/wQEAwIBBjAS -BgNVHRMBAf8ECDAGAQH/AgEAMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcD -AgYIKwYBBQUHAwQwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8v -b2NzcC5lbnRydXN0Lm5ldDBEBgNVHSAEPTA7MDkGBWCDSgEBMDAwLgYIKwYBBQUH -AgEWImh0dHA6Ly93d3cuZGlnaWNlcnQuY29tLm15L2Nwcy5odG0wMgYDVR0fBCsw -KTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3JsMBEGA1Ud -DgQKBAhMTswlKAMpgTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDAN -BgkqhkiG9w0BAQUFAAOCAQEAl0zvSjpJrHL8MCBrtClbp8WVBJD5MtXChWreA6E3 -+YkAsFqsVX7bQzX/yQH4Ub7MJsrIaqTEVD4mHucMo82XZ5TdpkLrXM2POXlrM3kh -Bnn6gkQVmczBtznTRmJ8snDrb84gqj4Zt+l0gpy0pUtNYQA35IfS8hQ6ZHy4qXth -4JMi59WfPkfmNnagU9gAAzoPtTP+lsrT0oI6Lt3XSOHkp2nMHOmZSufKcEXXCwcO -mnUb0C+Sb/akB8O9HEumhLZ9qJqp0qcp8QtXaR6XVybsK0Os1EWDBQDp4/BGQAf6 -6rFRc5Mcpd1TETfIKqcVJx20qsx/qjEw/LhFn0gJ7RDixQ== ------END CERTIFICATE----- - -// Subject: CN=Java Media APIs, -// OU=Java Signed Extensions, -// OU=Corporate Object Signing, -// O=Sun Microsystems Inc -// Issuer: CN=Object Signing CA, -// OU=Class 2 OnSite Subscriber CA, -// OU=VeriSign Trust Network, -// O=Sun Microsystems Inc -// Serial: 6a:8b:99:91:37:59:4f:89:53:e2:97:18:9f:19:1e:4e ------BEGIN CERTIFICATE----- -MIIFdzCCBF+gAwIBAgIQaouZkTdZT4lT4pcYnxkeTjANBgkqhkiG9w0BAQUFADCB -gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj -cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDUxMjAw -MDAwMFoXDTEyMDUxMTIzNTk1OVowfTEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt -cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE -CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEYMBYGA1UEAxQPSmF2YSBNZWRpYSBB -UElzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl5blzoKTVE8y4Hpz -q6E15RZz1bF5HnYEyYqgHkZXnAKedmYCoMzm1XK8s+gQWShLEvGEAvs5yqarx9gE -nnC21N28aEZgIJMa2/arKxCUkS4pxdGPYGexL9UzSRkUpoBShCZKEGdmX7gfJE2K -/sd9MFvGV5/yZtWXrADzvm0Kd/9mg1KRv1gfrZIq0TJbupoXPYYqb73AkI9eT2ZD -q9MdwD4E5+oojsDFXt8GU/D00fUhtXpYwuplU7D667WHYdJhIah0ST6JywyqcLXG -XSuFTXOgITT2idSHluZVmx3dqJ72u9kPkO4JdJTMDfaK8zgNLaRkiU8Qcj+qhLYH -ytaqcwIDAQABo4IB6jCCAeYwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwfwYD -VR0fBHgwdjB0oHKgcIZuaHR0cDovL29uc2l0ZWNybC52ZXJpc2lnbi5jb20vU3Vu -TWljcm9zeXN0ZW1zSW5jQ29ycG9yYXRlT2JqZWN0U2lnbmluZ0phdmFTaWduZWRF -eHRlbnNpb25zQ2xhc3NCL0xhdGVzdENSTC5jcmwwHwYDVR0jBBgwFoAUs0crgn5T -tHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFKS32mVx0gNWTeS4ProHEaeSpvvIMDsG -CCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3NwLnZl -cmlzaWduLmNvbTCBtQYDVR0gBIGtMIGqMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYB -BQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwbQYLYIZIAYb3AIN9 -nD8wXjAnBggrBgEFBQcCARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDMG -CCsGAQUFBwICMCcaJVZhbGlkYXRlZCBGb3IgU3VuIEJ1c2luZXNzIE9wZXJhdGlv -bnMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQEFBQADggEBAAe6BO4W -3TSNWfezyelJs6kE3HfulT6Bdyz4UUoh9ykXcV8nRwT+kh25I5MdyG2GfkJoADPR -VhC5DYo13UFpIsTNVjq+hGYe2hML93bN7ad9SxCCyjHUo3yMz2qgBbHZI3VA9ZHA -aWM4Tx0saMwbcnVvlbuGh+PXvStfypJqYT6lzcdFfjNVX4FI/QQNGhBswMY51tC8 -GTBCL2qhJon0gSCU4zaawDOf7+XxJWirLamYL1Aal1/h2z2sFrvA/1ftxtU3kZ6I -7De8DyoHeZg7pYGdrj7g+lPhCga/WvEhN152I+aP08YbFcJHYmK05ngl/Ye4c6Bd -cdrdfbw6QzEUIYY= ------END CERTIFICATE----- - -// Subject: CN=JavaFX 1.0 Runtime, -// OU=Java Signed Extensions, -// OU=Corporate Object Signing, -// O=Sun Microsystems Inc -// Issuer: CN=Object Signing CA, -// OU=Class 2 OnSite Subscriber CA, -// OU=VeriSign Trust Network, -// O=Sun Microsystems Inc -// Serial: 55:c0:e6:44:59:59:79:9e:d9:26:f1:b0:4a:1e:f0:27 ------BEGIN CERTIFICATE----- -MIIFezCCBGOgAwIBAgIQVcDmRFlZeZ7ZJvGwSh7wJzANBgkqhkiG9w0BAQUFADCB -gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj -cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA4MTAwOTAw -MDAwMFoXDTExMTAwOTIzNTk1OVowgYAxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl -bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxHzAdBgNV -BAsUFkphdmEgU2lnbmVkIEV4dGVuc2lvbnMxGzAZBgNVBAMUEkphdmFGWCAxLjAg -UnVudGltZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM+WDc6+bu+4 -tmAcS/lBtUc02WOt9QZpVsXg9cG2pu/8bUtmDELa8iiYBVFpIs8DU58HLrGQtCUY -SIAGOVPsOJoN29UKCDWfY9j5JeVhfhMGqk9DwrWhzgsjy4cpZ1pIp+k/fJ8zT8Ul -aYLpow1vg3UNddsmwz02tN7cOrMw9WYIG4CRYnY1OrtJSfe2pYzheC4zyvR+aiVl -nang2OtqikSQsNFOFHsLOJFxngy9LrO8evDSu25VTKI6zlWU6/bMeqtztJPN0VOn -NyUrJZvkxZ207Jg0T693BGSxNC1n+ihztXogql8950M/pEuUbDjylv5FFvlp6DSB -dDT2MkutmyMCAwEAAaOCAeowggHmMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeA -MH8GA1UdHwR4MHYwdKByoHCGbmh0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29t -L1N1bk1pY3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdKYXZhU2ln -bmVkRXh0ZW5zaW9uc0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaAFLNH -K4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBTjgufVi3XJ3gx1ewsA6Rr7BR4Z -zjA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUtb2Nz -cC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAqMCgG -CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CGSAGG -9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtpL2Nw -czAzBggrBgEFBQcCAjAnGiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVy -YXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IBAQAB -YVJTTVe7rzyTO4jc3zajErOT/COkdQTfNo0eIX1QbNynFieJvwY/jRzUZwjktIFR -2p4JtbpHGAtKtjOAOTieQ8xdDOoC1djzpE7/AbMvuvlTavtUKT+F7tPdhfXgWXJV -6Wbt8jryKyk3zZGiEhauIwZUkfjRkEtffEmZWLUd8c8rURJjfC/XHH2oyurscoxc -CjX29c9ynxSiS/VvQp1an0HvErGh69N48wj7cj8mtZ1yHzd2XCzSSR1OfTPfk0Pt -yg51p7yJaFiH21PTZegEL6zyVNOYBTKwwIi2OzpwYalD3uvK6e3OKDrfFCOxu17u -4PveESbrdyrmvLe7IVez ------END CERTIFICATE----- - -// Subject: CN=JavaFX Runtime, -// OU=Java Signed Extensions, -// OU=Corporate Object Signing, -// O=Sun Microsystems Inc -// Issuer: CN=Object Signing CA, -// OU=Class 2 OnSite Subscriber CA, -// OU=VeriSign Trust Network, -// O=Sun Microsystems Inc -// Serial: 47:f4:55:f1:da:4a:5e:f9:e3:f7:a8:03:62:17:c0:ff ------BEGIN CERTIFICATE----- -MIIFdjCCBF6gAwIBAgIQR/RV8dpKXvnj96gDYhfA/zANBgkqhkiG9w0BAQUFADCB -gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj -cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDEyOTAw -MDAwMFoXDTEyMDEyOTIzNTk1OVowfDEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt -cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE -CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEXMBUGA1UEAxQOSmF2YUZYIFJ1bnRp -bWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIzd0fAk8mI9ONc6RJ -aGieioK2FLdXEwj8zL3vdGDVmBwyR1zwYkaOIFFgF9IW/8qc4iAYA5sGUY+0g8q3 -5DuYAxfTzBB5KdaYvbuq6GGnoHIWmTirXY+1friFp8lyXSvtuEaGB1VHaBoZchEg -k+UgeVDA43dHwcT1Ov3DePczJRUes8T/QHzLX+BxUDG43vjyncCEO/AjqLZxXEz2 -xrNbKLcH3lGMJK7hdbfssUfF5BjC38Hn71HauYlA43b2no+2y0Sjulwzez2YPbDC -0GLR3TnKtA8dqOrnl5t3DniDbfOBNtBE3VOydJO0XW57Ng1HRXD023nm9ECPY2xp -0N/pAgMBAAGjggHqMIIB5jAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDB/BgNV -HR8EeDB2MHSgcqBwhm5odHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9TdW5N -aWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nSmF2YVNpZ25lZEV4 -dGVuc2lvbnNDbGFzc0IvTGF0ZXN0Q1JMLmNybDAfBgNVHSMEGDAWgBSzRyuCflO0 -c8q4uxm3voFNB5XH7TAdBgNVHQ4EFgQUvOdd0cKPj+Yik/iOBwTdphh5A+gwOwYI -KwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb25zaXRlLW9jc3AudmVy -aXNpZ24uY29tMIG1BgNVHSAEga0wgaowOQYLYIZIAYb4RQEHFwIwKjAoBggrBgEF -BQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTBtBgtghkgBhvcAg32c -PzBeMCcGCCsGAQUFBwIBFhtodHRwczovL3d3dy5zdW4uY29tL3BraS9jcHMwMwYI -KwYBBQUHAgIwJxolVmFsaWRhdGVkIEZvciBTdW4gQnVzaW5lc3MgT3BlcmF0aW9u -czATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAbGcf2NjL -AI93HG6ny2BbepaZA1a8xa/R6uUc7xV+Qw6MgLwFD4Q4i6LWUztQDvg9l68MM2/i -Y9LEi1KM4lcNbK5+D+t9x98wXBiuojXhVdp5ZmC03EyEBbriopdBsmXVLDSu/Y3+ -zowOO5xwpMK3dbgsSDs2Vt0UosD3FTcRaD3GNfOhXMp+o1grHNiXF9YgkmdQbPPZ -DQ2KBhFPCRJXBGvyKOqno/DTg0sQ3crGH/C4/4t7mnQXWldZotmJUZ0ONc9oD+Q1 -JAaguUKqIwn9yZ093ie+JWHbYNid9IIIPXYgtRxmf9a376WBhqhu56uJftBJ7x9g -eQ7Lot6CSWCiFw== ------END CERTIFICATE----- - -// Subject: CN=Solaris INTERNAL DEVELOPMENT USE ONLY, -// OU=Solaris Cryptographic Framework, -// OU=Corporate Object Signing, -// O=Sun Microsystems Inc -// Issuer: CN=Object Signing CA, -// OU=Class 2 OnSite Subscriber CA, -// OU=VeriSign Trust Network, -// O=Sun Microsystems Inc -// Serial: 77:29:77:52:6a:19:7b:9a:a6:a2:c7:99:a0:e1:cd:8c ------BEGIN CERTIFICATE----- -MIIFHjCCBAagAwIBAgIQdyl3UmoZe5qmoseZoOHNjDANBgkqhkiG9w0BAQUFADCB -gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj -cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA3MDEwNDAw -MDAwMFoXDTEwMDEwMzIzNTk1OVowgZwxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl -bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxKDAmBgNV -BAsUH1NvbGFyaXMgQ3J5cHRvZ3JhcGhpYyBGcmFtZXdvcmsxLjAsBgNVBAMUJVNv -bGFyaXMgSU5URVJOQUwgREVWRUxPUE1FTlQgVVNFIE9OTFkwgZ8wDQYJKoZIhvcN -AQEBBQADgY0AMIGJAoGBALbNU4hf3mD5ArDI9pjgioAyvV3bjMPRQdCZniIeGJBp -odFlSEH+Mh64W1DsY8coeZ7FvvGJkx9IpTMJW9k8w1oJK9UNqHyAQfaYjQyXi3xQ -LJp62EvYdGfDlwOZejEcR/MbzZG+GOPMMvQj5+xyFDvLXNGfQNTnxw2qnBgCJXjj -AgMBAAGjggH1MIIB8TAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDCBiQYDVR0f -BIGBMH8wfaB7oHmGd2h0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29tL1N1bk1p -Y3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdTb2xhcmlzQ3J5cHRv -Z3JhcGhpY0ZyYW1ld29ya0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaA -FLNHK4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBRpfiGYkehTnsIzuN2H6AFb -VCZG8jA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUt -b2NzcC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAq -MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CG -SAGG9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtp -L2NwczAzBggrBgEFBQcCAjAnFiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBP -cGVyYXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IB -AQCG5soy3LFHTFbA8/5SzDRhQoJkHUnOP0t3b6nvX6vZYRp649fje7TQOPRm1pFd -CZ17J+tggdZwgzTqY4aYpJ00jZaK6pV37q/vgFC/ia6jDs8Q+ly9cEcadBZ5loYg -cmxp9p57W2MNWx8VA8oFdNtKfF0jUNXbLNtvwGHmgR6YcwLrGN1b6/9Lt9bO3ODl -FO+ZDwkfQz5ClUVrTx2dGBvKRYFqSG5S8JAfsgYhPvcacUQkA7ExyKvfRXLWVrce -ZiPpcElbx+819H2sAPvVvparVeAruZGMAtejHZp9NFoowKen5drJp9VxePS4eM49 -3DepB6lKRrNRw66LNQol4ZBz ------END CERTIFICATE----- - -// Subject: EMAILADDRESS=info@diginotar.nl, CN=DigiNotar Cyber CA, -// O=DigiNotar, C=NL -// Issuer: CN=GTE CyberTrust Global Root, -// OU=GTE CyberTrust Solutions, Inc., -// O=GTE Corporation, -// C=US -// Serial: 120000525 (07:27:10:0D) ------BEGIN CERTIFICATE----- -MIIFWjCCBMOgAwIBAgIEBycQDTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MB4XDTA2MTAwNDEwNTQxMVoXDTExMTAwNDEwNTMxMVowYDELMAkG -A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy -IEN5YmVyIENBMSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANLOFQotqF6EZ639vu9Gx8i5z3P8 -9DS5+SxD52ATPXrjss87Z2yQrcC5P4RS8DVC3HTcKDu9UrSnrHJFF8bwieu0qiXy -XUte0dmHutZ9fPXOMp8QM8WxSrtekTHC0OlBwpFkfglBO9uLCDdqqspS3rU5HsCI -A6U/i5kTYUO1m4Kz7iBvz6FEouova0CfjytXraFTwoUiaZ2gP1HfC0GRDaXhqKpc -SQhdvd5wQbEPyWNr0380dAIvNFp4dRxoeoFnivPaQPBgY/SSINcDpj2jHmfEhBtB -pcmM5r3qSLYFFgizNxJa92E89zhvLpfgb1Y4VNMota0Ubi5LZLUnZbd1JQm2Bz2V -VgIKgmCyc0XgMyZRdJq51FAc9k1bW1JSE1qmf6cO4ehBVGeYjIfVydNsy9NUkgYJ -NEH3gW8/nsl8dVWw58Gzd+jDxAA1lUBwEEoF3iW7n1mlZLxHYL9g43aLE1Xd4XR6 -uc8kpmp/3mQiRFhogmoQ+T3lPhu5vfwi9GAEibtVbShV+t6OjRshFNc3izR7Tfay -shDPM7F9HGKZSMsrbHaWVb8ZDR0fu2WqG46ZtcYokOWCLXhQIJr9eS8kf/CJKWn0 -fc1zvrPtTsHR7VJej/e4142HrbLZG1ES/1az4a80fVykeIgQnp0DxqWqoiRR90kU -xbHuWUOV36toKDA/AgMBAAGjggGGMIIBgjASBgNVHRMBAf8ECDAGAQH/AgEBMFMG -A1UdIARMMEowSAYJKwYBBAGxPgEAMDswOQYIKwYBBQUHAgEWLWh0dHA6Ly93d3cu -cHVibGljLXRydXN0LmNvbS9DUFMvT21uaVJvb3QuaHRtbDAOBgNVHQ8BAf8EBAMC -AQYwgaAGA1UdIwSBmDCBlYAUpgwdn2H/Bxe1vzhG20Mw1Y6wUgaheaR3MHUxCzAJ -BgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdU -RSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVy -VHJ1c3QgR2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93 -d3cucHVibGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYD -VR0OBBYEFKv5aN/PSjfXe0WMX3LeQETDZbvCMA0GCSqGSIb3DQEBBQUAA4GBAI9o -a6VbB7pEZg4cqFwwezPkCiYE/O+eGjjWLqEf0JlHwnVkJP2eOyh2uSYoYZEMbSz4 -BJ98UAHV42mv7xXSRZskCSpmBU8lgcpdvqrBWSeuM46C9990sFWzjvjnN8huqlZE -9r1TgSOWPbT6MopTZkQloiXGpjwljPDgKAYityZB ------END CERTIFICATE----- - -// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL -// Issuer: CN=GTE CyberTrust Global Root, -// OU=GTE CyberTrust Solutions, Inc., -// O=GTE Corporation, -// C=US -// Serial: 120000505 (07:27:0F:F9) ------BEGIN CERTIFICATE----- -MIIFODCCBKGgAwIBAgIEBycP+TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MB4XDTA2MDkyMDA5NDUzMloXDTEzMDkyMDA5NDQwNlowPjELMAkG -A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy -IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o -XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S -tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 -24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp -naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj -9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu -LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU -Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk -vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 -3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt -eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 -iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB -/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC -ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s -MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV -jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv -bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD -VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 -oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw -MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI -hvcNAQEFBQADgYEACcpiD427SuDUejUrBi3RKGG2rAH7g0m8rtQvLYauGYOl1h0T -4he+/jJ06XoUOMqUXvcpAWlxG5Ea/aO7qh3Ke+IW/aGjDvMMX7LhIDGUK16Sdu36 -6bUjpr8KOwOpb1JgVM1f6bcvfKIn/UGDdbYN+3gm87FF6TKVKho1IZXFonU= ------END CERTIFICATE----- - -// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL -// Issuer: CN=GTE CyberTrust Global Root, -// OU=GTE CyberTrust Solutions, Inc., -// O=GTE Corporation, -// C=US -// Serial: 120000515 (07:27:10:03) ------BEGIN CERTIFICATE----- -MIIFODCCBKGgAwIBAgIEBycQAzANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MB4XDTA2MDkyNzEwNTMzMloXDTExMDkyNzEwNTIzMFowPjELMAkG -A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy -IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o -XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S -tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 -24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp -naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj -9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu -LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU -Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk -vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 -3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt -eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 -iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB -/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC -ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s -MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV -jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv -bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD -VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 -oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw -MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI -hvcNAQEFBQADgYEAWcyGZhizJlRP1jjNupZey+yZG6oMDW4Z11boriMHbYPCndBE -bVh07zmPbZsihOw9w/vm5KbVX5CgxUv4Rhzh/20Faixf3P3bpWg0qgzHVVusNVR/ -P50aKkpdK3hp+QLl56e+lWOddSAINIpmcuyDI1hyuzB+GJEASm9tNU/6rs8= ------END CERTIFICATE----- - -// Subject: EMAILADDRESS=info@diginotar.nl, -// CN=DigiNotar Root CA, -// O=DigiNotar, C=NL -// Issuer: CN=Entrust.net Secure Server Certification Authority -// OU=(c) 1999 Entrust.net Limited, -// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), -// O=Entrust.net, -// C=US, -// Serial: 1184644297 (46:9C:3C:C9) ------BEGIN CERTIFICATE----- -MIIFSDCCBLGgAwIBAgIERpw8yTANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC -VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u -ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc -KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u -ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA0 -MjYwNTAwMDBaFw0xMzA4MTQyMDEyMzZaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK -EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI -hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt -OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx -hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 -gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D -IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T -BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs -Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 -5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf -DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX -9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e -7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj -ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB -BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF -BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD -VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy -bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G -A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob -BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAI979rBep8tu3TeLunapgsZ0jtXp -GDFjKWSk87dj1jCyYi+q/GyDyZ6ZQZNRP0sF+6twscq05lClWNy3TROMp7QeuoLO -G7Utw3OJaswUtp4YglANMRTHEe3g9ltifUXRH5tSuy7u6yi4LD4WTm5ULP6r/g6l -0CnjXYb0+b1Fmz6U ------END CERTIFICATE----- - -// Subject: EMAILADDRESS=info@diginotar.nl, -// CN=DigiNotar Root CA, -// O=DigiNotar, C=NL -// Issuer: CN=Entrust.net Secure Server Certification Authority -// OU=(c) 1999 Entrust.net Limited, -// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), -// O=Entrust.net, -// C=US, -// Serial: 1184640175 (46:9C:2C:AF) ------BEGIN CERTIFICATE----- -MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC -VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u -ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc -KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u -ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 -MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK -EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI -hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt -OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx -hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 -gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D -IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T -BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs -Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 -5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf -DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX -9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e -7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj -ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB -BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF -BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD -VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy -bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G -A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob -BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh -xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd -ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP -ZFdYf+hthc3m6IcJ ------END CERTIFICATE----- - -// Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2, -// O=DigiNotar B.V., -// C=NL -// Issuer: CN=Staat der Nederlanden Organisatie CA - G2, -// O=Staat der Nederlanden, -// C=NL -// Serial: 20001983 (01:31:34:bf) ------BEGIN CERTIFICATE----- -MIIGnDCCBISgAwIBAgIEATE0vzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMTIwMAYDVQQDDClTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gT3JnYW5pc2F0aWUgQ0EgLSBHMjAeFw0xMDA1MTIw -ODUxMzhaFw0yMDAzMjMwOTUwMDRaMFoxCzAJBgNVBAYTAk5MMRcwFQYDVQQKDA5E -aWdpTm90YXIgQi5WLjEyMDAGA1UEAwwpRGlnaU5vdGFyIFBLSW92ZXJoZWlkIENB -IE9yZ2FuaXNhdGllIC0gRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCxExkPJ+Zs1FWGS9DsiYpFkXisR71HK+T8RetPtCZzWzfTw3/2497Xo/gtaMUI -PkuU1uSHJTZrhLUYdPMoWHMvm2rPvAQe9t7dr/xLqvXbZmIlASWC3vKXWhBu3V2p -IrEEqSNzOvhxrR3PhETrR9Gvbch8KKvH8jd6dF9fxQIUiqNa4xtsAeNdjtlo1vQJ -GzLckbUs9SDrjANtJkm4k8SFXdjSm69WaswFM8ygQp40VUSca6DUEtArVM23iQ3l -9uvo+4UBM096a/GdcjOWDveyhKWlJ8Qn8VFzKXe6Z27+TNy04qGhgS85SY1DOBPO -0KVcwoc6AGdlQiPxNlkKHaNRyLyjlCox3+M88p0aPASw77EKMBNzttfzo0wBdRSF -eMDXijlYhVD6LubFvs+LP6+PNtQlCS3SD6xyk/K/i9RQs/kVUJuZ9RTZ+4uRozIm -JqD43ztggYaDeVsr6xM9KTrBbd29no6H1kquNJcF7hSm9tw4fkrpJFQHPZdoN0Zr -DceoIa8TVOQJavFNRgrJXfubT73e+7dUy7g4nKc5+2otwHuNq6WnV+xKkoozxeEg -XHPYkJIrgNUPhhhpfDlPhIa890xb89W0yqDC8DciynlSH1PmqvOQsDvd8ij9rOvF -BiSgydQvD1j9tZ7sD8+yWdCiBHo4aq5y+73wJWKUCacFCwIDAQABo4IBYTCCAV0w -SAYDVR0gBEEwPzA9BgRVHSAAMDUwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cuZGln -aW5vdGFyLm5sL2Nwcy9wa2lvdmVyaGVpZDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjCBhQYDVR0jBH4wfIAUORCLSZJc22ESIM1JnRqO2pxnQLmhXqRc -MFoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4x -KzApBgNVBAMMIlN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBIC0gRzKCBACY -lvQwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5wa2lvdmVyaGVpZC5ubC9E -b21PcmdhbmlzYXRpZUxhdGVzdENSTC1HMi5jcmwwHQYDVR0OBBYEFLxdlDvZq3sD -JXNhwtst7vyrj2WhMA0GCSqGSIb3DQEBCwUAA4ICAQCP/C1Mt9kt1R+978v0t2gX -dZ1O1ffdnPEqJu2forYcA9VTs+wIzzTi48P0tRYvyMO+19NzqwA2+RpKftZj6V5G -uqW2jhW3oyrYQx3vXcgfgYWzi/f/PPTZ9EYIP5y8HaDZqEzNJVJOCrEg9x/pQ9lU -RoETmsBedGwqmDLq/He7DaWiMZgifnx859qkrey3LhoZcfhIUNpDjyyE3cFAJ+O1 -8BVOltT4XOOGKUYr1zsH6zh/yIZXl9PvKjPEF1DVZGlrK2tFXl0vF8paTs/D1zk8 -9TufRrmb5w5Jl53W1eMbD+qPAU6aE5RZCgIHSEsaYKt/T+0L2FUNaG9VnGllFULs -wNzdbKzDFs4LHVabpMTE0i7gD+JEJytQaaTcYuiKISlCbMwAOpZ2m+9AwKRed4Qy -bCYqOWauXeO5ubIsaB8empADOfCqs6TMSYsYNOk3yXspx4R8b0QVL+xhWQTJRcui -1lKifH8pktZKxYtCqNT+6tjHhyMY5J16fXNAUpigrm7jBT8FD+Clxm1N7YM3iJzH -89xCmmq21yFJNnfy7xhPxXDZnunetyuL9Lx+KN8NQMmFXK6dxTH/0FwOtah+8Okv -uq+IruW10Vilr5xxpykBkINpN4IFuvwJwQhujHg7wzMCgD9EhQgd31VWCK0shS1d -sQPhrqp0xaTzTro3mHuCuQ== ------END CERTIFICATE----- - -// Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven, -// O=DigiNotar B.V., -// C=NL -// Issuer: CN=Staat der Nederlanden Overheid CA -// O=Staat der Nederlanden, -// C=NL -// Serial: 20015536 (01:31:69:b0) ------BEGIN CERTIFICATE----- -MIIEiDCCA3CgAwIBAgIEATFpsDANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO -TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDcwNzA1MDg0MjA3WhcN -MTUwNzI3MDgzOTQ2WjBfMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy -IEIuVi4xNzA1BgNVBAMTLkRpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp -ZCBlbiBCZWRyaWp2ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc -vdKnTmoKuzuiheF/AK2+tDBomAfNoHrElM9x+Yo35FPrV3bMi+Zs/u6HVcg+uwQ5 -AKeAeKxbT370vbhUuHE7BzFJOZNUfCA7eSuPu2GQfbGs5h+QLp1FAalkLU3DL7nn -UNVOKlyrdnY3Rtd57EKZ96LspIlw3Dgrh6aqJOadkiQbvvb91C8ZF3rmMgeUVAVT -Q+lsvK9Hy7zL/b07RBKB8WtLu+20z6slTxjSzAL8o0+1QjPLWc0J3NNQ/aB2jKx+ -ZopC9q0ckvO2+xRG603XLzDgbe5bNr5EdLcgBVeFTegAGaL2DOauocBC36esgl3H -aLcY5olLmmv6znn58yynAgMBAAGjggFQMIIBTDBIBgNVHSAEQTA/MD0GBFUdIAAw -NTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5kaWdpbm90YXIubmwvY3BzL3BraW92 -ZXJoZWlkMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIGABgNVHSME -eTB3gBQLhtYPd6NosftkCcOIblwEHFfpPaFZpFcwVTELMAkGA1UEBhMCTkwxHjAc -BgNVBAoTFVN0YWF0IGRlciBOZWRlcmxhbmRlbjEmMCQGA1UEAxMdU3RhYXQgZGVy -IE5lZGVybGFuZGVuIFJvb3QgQ0GCBACYmnkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0 -cDovL2NybC5wa2lvdmVyaGVpZC5ubC9Eb21PdkxhdGVzdENSTC5jcmwwHQYDVR0O -BBYEFEwIyY128ZjHPt881y91DbF2eZfMMA0GCSqGSIb3DQEBBQUAA4IBAQAMlIca -v03jheLu19hjeQ5Q38aEW9K72fUxCho1l3TfFPoqDz7toOMI9tVOW6+mriXiRWsi -D7dUKH6S3o0UbNEc5W50BJy37zRERd/Jgx0ZH8Apad+J1T/CsFNt5U4X5HNhIxMm -cUP9TFnLw98iqiEr2b+VERqKpOKrp11Lbyn1UtHk0hWxi/7wA8+nfemZhzizDXMU -5HIs4c71rQZIZPrTKbmi2Lv01QulQERDjqC/zlqlUkxk0xcxYczopIro5Ij76eUv -BjMzm5RmZrGrUDqhCYF0U1onuabSJc/Tw6f/ltAv6uAejVLpGBwgCkegllYOQJBR -RKwa/fHuhR/3Qlpl ------END CERTIFICATE----- - -// Subject: CN=DigiNotar PKIoverheid CA Overheid -// O=DigiNotar B.V., -// C=NL -// Issuer: CN=Staat der Nederlanden Overheid CA -// O=Staat der Nederlanden, -// C=NL -// Serial: 20006006 (01:31:44:76) ------BEGIN CERTIFICATE----- -MIIEezCCA2OgAwIBAgIEATFEdjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO -TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDQwNjI0MDgxOTMyWhcN -MTAwNjIzMDgxNzM2WjBSMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy -IEIuVi4xKjAoBgNVBAMTIURpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp -ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANSlrubta5tlOjVCi/gb -yLCvRqfBjxG8H594VcKHu0WAYc99SPZF9cycj5mw2GyfQvy/WIrGrL4iyNq1gSqR -0QA/mTXKZIaPqzpDhdm+VvrKkmjrbZfaQxgMSs3ChtBsjcP9Lc0X1zXZ4Q8nBe3k -BTp+zehINfmbjoEgXLxsMR5RQ6GxzKjuC04PQpbJQgTIakglKaqYcDDZbEscWgPV -Hgj/2aoHlj6leW/ThHZ+O41jUguEmBLZA3mu3HrCfrHntb5dPt0ihzSx7GtD/SaX -5HBLxnP189YuqMk5iRA95CtiSdKauvon/xRKRLNgG6XAz0ctSoY7xLDdiBVU5kJd -FScCAwEAAaOCAVAwggFMMEgGA1UdIARBMD8wPQYEVR0gADA1MDMGCCsGAQUFBwIB -FidodHRwOi8vd3d3LmRpZ2lub3Rhci5ubC9jcHMvcGtpb3ZlcmhlaWQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgYAGA1UdIwR5MHeAFAuG1g93o2ix -+2QJw4huXAQcV+k9oVmkVzBVMQswCQYDVQQGEwJOTDEeMBwGA1UEChMVU3RhYXQg -ZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQYIEAJiaeTA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnBraW92 -ZXJoZWlkLm5sL0RvbU92TGF0ZXN0Q1JMLmNybDAdBgNVHQ4EFgQUvRaYQh2+kdE9 -wpcl4CjXWOC1f+IwDQYJKoZIhvcNAQEFBQADggEBAGhQsCWLiaN2EOhPAW+JQP6o -XBOrLv5w6joahzBFVn1BiefzmlMKjibqKYxURRvMAsMkh82/MfL8V0w6ugxl81lu -i42dcxl9cKSVXKMw4bbBzJ2VQI5HTIABwefeNuy/eX6idVwYdt3ajAH7fUA8Q9Cq -vr6H8B+8mwoEqTVTEVlCSsC/EXsokYEUr06PPzRudKjDmijgj7zFaIioZNc8hk7g -ufEgrs/tmcNGylrwRHgCXjCRBt2NHlZ08l7A1AGU8HcHlSbG9Un/2q9kVHUkps0D -gtUaEK+x6jpAu/R8Ojezu/+ZEcwwjI/KOhG+84+ejFmtyEkrUdsAdEdLf/2dKsw= ------END CERTIFICATE----- - -// Subject: EMAILADDRESS=info@diginotar.nl, -// CN=DigiNotar Services 1024 CA -// O=DigiNotar, C=NL -// Issuer: CN=Entrust.net Secure Server Certification Authority, -// OU=(c) 1999 Entrust.net Limited, -// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), -// O=Entrust.net, -// C=US -// Serial: 1184640176 (46:9c:2c:b0) ------BEGIN CERTIFICATE----- -MIIDzTCCAzagAwIBAgIERpwssDANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC -VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u -ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc -KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u -ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 -MjYxNTU5MDBaFw0xMzA4MjYxNjI5MDBaMGgxCzAJBgNVBAYTAk5MMRIwEAYDVQQK -EwlEaWdpTm90YXIxIzAhBgNVBAMTGkRpZ2lOb3RhciBTZXJ2aWNlcyAxMDI0IENB -MSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEA2ptNXTz50eKLxsYIIMXZHkjsZlhneWIrQWP0iY1o2q+4 -lDaLGSSkoJPSmQ+yrS01Tc0vauH5mxkrvAQafi09UmTN8T5nD4ku6PJPrqYIoYX+ -oakJ5sarPkP8r3oDkdqmOaZh7phPGKjTs69mgumfvN1y+QYEvRLZGCTnq5NTi1kC -AwEAAaOCASYwggEiMBIGA1UdEwEB/wQIMAYBAf8CAQAwJwYDVR0lBCAwHgYIKwYB -BQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDBDARBgNVHSAECjAIMAYGBFUdIAAwMwYI -KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l -dDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1c3QubmV0L3NlcnZl -cjEuY3JsMB0GA1UdDgQWBBT+3JRJDG/vXH/G8RKZTxZJrfuCZTALBgNVHQ8EBAMC -AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowGQYJKoZIhvZ9B0EA -BAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEFBQADgYEAY3RqN6k/lpxmyFisCcnv -9WWUf6MCxDgxvV0jh+zUVrLJsm7kBQb87PX6iHBZ1O7m3bV6oKNgLwIMq94SXa/w -NUuqikeRGvWFLELHHe+VQ7NeuJWTpdrFKKqtci0xrZlrbP+MISevrZqRK8fdWMNu -B8WfedLHjFW/TMcnXlEWKz4= ------END CERTIFICATE----- - -// Subject: CN=Buster Paper Comercial Ltda, -// O=Buster Paper Comercial Ltda, -// L=S?o Jos? Dos Campos, -// ST=S?o Paulo, -// C=BR -// Issuer: CN=DigiCert Assured ID Code Signing CA-1, -// OU=www.digicert.com, -// O=DigiCert Inc, -// C=US -// Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12 ------BEGIN CERTIFICATE----- -MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv -ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow -gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT -w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l -cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL -HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn -2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4 -tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi -mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf -Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx -BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw -HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT -BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js -My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6 -Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud -IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov -L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG -AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD -AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh -AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy -AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn -ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs -AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp -AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl -AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho -dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl -cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et -MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI -hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft -jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e -gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44 -/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc -BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj -XMuKLxbh7g== ------END CERTIFICATE----- - -// Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, -// O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, -// L=S?o Paulo, -// ST=S?o Paulo, -// C=BR -// Issuer: CN=DigiCert Assured ID Code Signing CA-1, -// OU=www.digicert.com, -// O=DigiCert Inc, -// C=US -// Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f ------BEGIN CERTIFICATE----- -MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv -ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow -gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT -w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF -TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB -IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA -A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR -4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V -JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW -kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb -0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj -NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV -HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30 -o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD -MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1 -cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t -L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB -hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z -c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A -eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA -ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA -IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA -YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA -cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA -aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA -ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC -BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 -LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp -Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA -MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ -A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE -Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA -XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9 -UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL -zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc ------END CERTIFICATE----- - -// Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT, -// O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US -// Issuer: SERIALNUMBER=07969287, -// CN=Go Daddy Secure Certification Authority, -// OU=http://certificates.godaddy.com/repository, -// O="GoDaddy.com, Inc.", -// L=Scottsdale, -// ST=Arizona, -// C=US -// Serial: 2b:73:43:2a:a8:4f:44 ------BEGIN CERTIFICATE----- -MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE -BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY -BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm -aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5 -IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky -ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC -VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS -RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh -BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU -IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277 -p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E -jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV -9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/ -U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw -DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E -BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n -ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH -AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w -gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk -eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku -Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9 -rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB -XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K -v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC -2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP -4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR -DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI -LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU= ------END CERTIFICATE----- - -// Subject: CN=eDellRoot -// Issuer: CN=eDellRoot -// Serial Number: -// 6b:c5:7b:95:18:93:aa:97:4b:62:4a:c0:88:fc:3b:b6 ------BEGIN CERTIFICATE----- -MIIC8zCCAd+gAwIBAgIQa8V7lRiTqpdLYkrAiPw7tjAJBgUrDgMCHQUAMBQxEjAQ -BgNVBAMTCWVEZWxsUm9vdDAeFw0xNTA0MDcxMDIzMjdaFw0zOTEyMzEyMzU5NTla -MBQxEjAQBgNVBAMTCWVEZWxsUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAL3RJg1uzVuEX0Hw4XWGzs6oI9W+o7HZdVdBMMVb4Gzb4uZjCTNjbPx4 -b8LNFL1uArUt+5VVMQDsOTY3Lg/Xe/UNukY2b+0llUOzzBYYpbsFcco4n6SsTvDh -Ni5t+kPo7c23ZrYBPmOu82eEJ6cavs/t39u+wFOkXXwvRCiHA/lWyNWNEPh17+bC -EP3q5N+JrV+6Ho3zQPEv5QUJYdmXsMmD2CMQojeQUj68J91P5w5BKjurG0xjivzh -Soie9ym7VRwLFjWScRuw/9XV6CLqTyL5xrqiiDp1uTOuqNj3uxyts9ocbsoJXuxj -5iEYkSM1nvLupEv+lgy9WqzIEFMm1l8CAwEAAaNJMEcwRQYDVR0BBD4wPIAQYA/f -EzPwmaRcZuSaa/VZ1KEWMBQxEjAQBgNVBAMTCWVEZWxsUm9vdIIQa8V7lRiTqpdL -YkrAiPw7tjAJBgUrDgMCHQUAA4IBAQArfdcScsezj8ooJ92UwwnPgg36noOgiUs5 -XzPLP4h0JpUYQVKB9hY1WTDwRUfTKGh7oNOowd027a/rVSb/TNeoiJIvMKn4gbvV -CWAiHhO8u2u0RkHCDVsa7e0i4ncpueWsihjn6jBrY8T+7eDYwiFT/F03A8NJ7mK5 -lZA8SFd5CTDy3EBUU5UwzXUc5HoIRUxXSPycu3aIBWawg3sCdKiAoikScPAWj0bM -0vmsP/8QSlTOBqO+QFQ6R82BtTvBNU3qbVICV4QObsxib++FAFL56NApPqskg7Vz -LfNIAjKabHUcjbuZkmg6jr4BfYW7+oQDHCsYgADjjKGdKz/8U/fP ------END CERTIFICATE-----
diff --git a/make/data/blockedcertsconverter/blocked.certs.pem b/make/data/blockedcertsconverter/blocked.certs.pem new file mode 100644 index 0000000..4a3b33b --- /dev/null +++ b/make/data/blockedcertsconverter/blocked.certs.pem
@@ -0,0 +1,749 @@ +#! java BlockedCertsConverter SHA-256 + +# The line above must be the first line of this file. Do not +# remove it. + +// Subject: CN=Digisign Server ID (Enrich), +// OU=457608-K, +// O=Digicert Sdn. Bhd., +// C=MY +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120001705 (07:27:14:a9) +-----BEGIN CERTIFICATE----- +MIIDyzCCAzSgAwIBAgIEBycUqTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA3MDcxNzE1MTc0OFoXDTEyMDcxNzE1MTY1NFowYzELMAkG +A1UEBhMCTVkxGzAZBgNVBAoTEkRpZ2ljZXJ0IFNkbi4gQmhkLjERMA8GA1UECxMI +NDU3NjA4LUsxJDAiBgNVBAMTG0RpZ2lzaWduIFNlcnZlciBJRCAoRW5yaWNoKTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArahkS02Hx4RZufuQRqCmicDx/tXa +VII3DZkrRSYK6Fawf8qo9I5HhAGCKeOzarWR8/uVhbxyqGToCkCcxfRxrnt7agfq +kBRPjYmvlKuyBtQCanuYH1m5Os1U+iDfsioK6bjdaZDAKdNO0JftZszFGUkGf/pe +LHx7hRsyQt97lSUCAwEAAaOCAXgwggF0MBIGA1UdEwEB/wQIMAYBAf8CAQAwXAYD +VR0gBFUwUzBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy +dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMAcGBWCDSgEBMA4GA1Ud +DwEB/wQEAwIB5jCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVibGljLXRydXN0 +LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYDVR0OBBYEFMYWk04WF+wW +royUdvOGbcV0boR3MA0GCSqGSIb3DQEBBQUAA4GBAHYAe6Z4K2Ydjl42xqSOBfIj +knyTZ9P0wAp9iy3Z6tVvGvPhSilaIoRNUC9LDPL/hcJ7VdREgr5trGeOvLQfkpxR +gBoU9m6rYYgLrRx/90tQUdZlG6ZHcRVesHHzNRTyN71jyNXwk1o0X9g96F33xR7A +5c8fhiSpPAdmzcHSNmNZ +-----END CERTIFICATE----- + +// Subject: CN=Digisign Server ID - (Enrich), +// OU=457608-K, +// O=Digicert Sdn. Bhd., +// C=MY +// Issuer: CN=Entrust.net Certification Authority (2048) +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), +// O=Entrust.net +// Serial: 1184644297 (4c:0e:63:6a) +-----BEGIN CERTIFICATE----- +MIIEzjCCA7agAwIBAgIETA5jajANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0xMDA3MTYxNzIzMzdaFw0xNTA3 +MTYxNzUzMzdaMGUxCzAJBgNVBAYTAk1ZMRswGQYDVQQKExJEaWdpY2VydCBTZG4u +IEJoZC4xETAPBgNVBAsTCDQ1NzYwOC1LMSYwJAYDVQQDEx1EaWdpc2lnbiBTZXJ2 +ZXIgSUQgLSAoRW5yaWNoKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AMWJ5PQNBkCSWccaszXRDkwqM/n4r8qef+65p21g9FTob9Wb8xtjMQRoctE0Foy0 +FyyX3nPF2JAVoBor9cuzSIZE8B2ITM5BQhrv9Qze/kDaOSD3BlU6ap1GwdJvpbLI +Vz4po5zg6YV3ZuiYpyR+vsBZIOVEb7ZX2L7OwmV3WMZhQdF0BMh/SULFcqlyFu6M +3RJdtErU0a9Qt9iqdXZorT5dqjBtYairEFs+E78z4K9EnTgiW+9ML6ZxJhUmyiiM +2fqOjqmiFDXimySItPR/hZ2DTwehthSQNsQ0HI0mYW0Tb3i+6I8nx0uElqOGaAwj +vgvsjJQAqQSKE5D334VsDLECAwEAAaOCATQwggEwMA4GA1UdDwEB/wQEAwIBBjAS +BgNVHRMBAf8ECDAGAQH/AgEAMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcD +AgYIKwYBBQUHAwQwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8v +b2NzcC5lbnRydXN0Lm5ldDBEBgNVHSAEPTA7MDkGBWCDSgEBMDAwLgYIKwYBBQUH +AgEWImh0dHA6Ly93d3cuZGlnaWNlcnQuY29tLm15L2Nwcy5odG0wMgYDVR0fBCsw +KTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3JsMBEGA1Ud +DgQKBAhMTswlKAMpgTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDAN +BgkqhkiG9w0BAQUFAAOCAQEAl0zvSjpJrHL8MCBrtClbp8WVBJD5MtXChWreA6E3 ++YkAsFqsVX7bQzX/yQH4Ub7MJsrIaqTEVD4mHucMo82XZ5TdpkLrXM2POXlrM3kh +Bnn6gkQVmczBtznTRmJ8snDrb84gqj4Zt+l0gpy0pUtNYQA35IfS8hQ6ZHy4qXth +4JMi59WfPkfmNnagU9gAAzoPtTP+lsrT0oI6Lt3XSOHkp2nMHOmZSufKcEXXCwcO +mnUb0C+Sb/akB8O9HEumhLZ9qJqp0qcp8QtXaR6XVybsK0Os1EWDBQDp4/BGQAf6 +6rFRc5Mcpd1TETfIKqcVJx20qsx/qjEw/LhFn0gJ7RDixQ== +-----END CERTIFICATE----- + +// Subject: CN=Java Media APIs, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 6a:8b:99:91:37:59:4f:89:53:e2:97:18:9f:19:1e:4e +-----BEGIN CERTIFICATE----- +MIIFdzCCBF+gAwIBAgIQaouZkTdZT4lT4pcYnxkeTjANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDUxMjAw +MDAwMFoXDTEyMDUxMTIzNTk1OVowfTEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt +cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE +CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEYMBYGA1UEAxQPSmF2YSBNZWRpYSBB +UElzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl5blzoKTVE8y4Hpz +q6E15RZz1bF5HnYEyYqgHkZXnAKedmYCoMzm1XK8s+gQWShLEvGEAvs5yqarx9gE +nnC21N28aEZgIJMa2/arKxCUkS4pxdGPYGexL9UzSRkUpoBShCZKEGdmX7gfJE2K +/sd9MFvGV5/yZtWXrADzvm0Kd/9mg1KRv1gfrZIq0TJbupoXPYYqb73AkI9eT2ZD +q9MdwD4E5+oojsDFXt8GU/D00fUhtXpYwuplU7D667WHYdJhIah0ST6JywyqcLXG +XSuFTXOgITT2idSHluZVmx3dqJ72u9kPkO4JdJTMDfaK8zgNLaRkiU8Qcj+qhLYH +ytaqcwIDAQABo4IB6jCCAeYwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwfwYD +VR0fBHgwdjB0oHKgcIZuaHR0cDovL29uc2l0ZWNybC52ZXJpc2lnbi5jb20vU3Vu +TWljcm9zeXN0ZW1zSW5jQ29ycG9yYXRlT2JqZWN0U2lnbmluZ0phdmFTaWduZWRF +eHRlbnNpb25zQ2xhc3NCL0xhdGVzdENSTC5jcmwwHwYDVR0jBBgwFoAUs0crgn5T +tHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFKS32mVx0gNWTeS4ProHEaeSpvvIMDsG +CCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3NwLnZl +cmlzaWduLmNvbTCBtQYDVR0gBIGtMIGqMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYB +BQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwbQYLYIZIAYb3AIN9 +nD8wXjAnBggrBgEFBQcCARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDMG +CCsGAQUFBwICMCcaJVZhbGlkYXRlZCBGb3IgU3VuIEJ1c2luZXNzIE9wZXJhdGlv +bnMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQEFBQADggEBAAe6BO4W +3TSNWfezyelJs6kE3HfulT6Bdyz4UUoh9ykXcV8nRwT+kh25I5MdyG2GfkJoADPR +VhC5DYo13UFpIsTNVjq+hGYe2hML93bN7ad9SxCCyjHUo3yMz2qgBbHZI3VA9ZHA +aWM4Tx0saMwbcnVvlbuGh+PXvStfypJqYT6lzcdFfjNVX4FI/QQNGhBswMY51tC8 +GTBCL2qhJon0gSCU4zaawDOf7+XxJWirLamYL1Aal1/h2z2sFrvA/1ftxtU3kZ6I +7De8DyoHeZg7pYGdrj7g+lPhCga/WvEhN152I+aP08YbFcJHYmK05ngl/Ye4c6Bd +cdrdfbw6QzEUIYY= +-----END CERTIFICATE----- + +// Subject: CN=JavaFX 1.0 Runtime, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 55:c0:e6:44:59:59:79:9e:d9:26:f1:b0:4a:1e:f0:27 +-----BEGIN CERTIFICATE----- +MIIFezCCBGOgAwIBAgIQVcDmRFlZeZ7ZJvGwSh7wJzANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA4MTAwOTAw +MDAwMFoXDTExMTAwOTIzNTk1OVowgYAxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl +bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxHzAdBgNV +BAsUFkphdmEgU2lnbmVkIEV4dGVuc2lvbnMxGzAZBgNVBAMUEkphdmFGWCAxLjAg +UnVudGltZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM+WDc6+bu+4 +tmAcS/lBtUc02WOt9QZpVsXg9cG2pu/8bUtmDELa8iiYBVFpIs8DU58HLrGQtCUY +SIAGOVPsOJoN29UKCDWfY9j5JeVhfhMGqk9DwrWhzgsjy4cpZ1pIp+k/fJ8zT8Ul +aYLpow1vg3UNddsmwz02tN7cOrMw9WYIG4CRYnY1OrtJSfe2pYzheC4zyvR+aiVl +nang2OtqikSQsNFOFHsLOJFxngy9LrO8evDSu25VTKI6zlWU6/bMeqtztJPN0VOn +NyUrJZvkxZ207Jg0T693BGSxNC1n+ihztXogql8950M/pEuUbDjylv5FFvlp6DSB +dDT2MkutmyMCAwEAAaOCAeowggHmMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeA +MH8GA1UdHwR4MHYwdKByoHCGbmh0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29t +L1N1bk1pY3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdKYXZhU2ln +bmVkRXh0ZW5zaW9uc0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaAFLNH +K4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBTjgufVi3XJ3gx1ewsA6Rr7BR4Z +zjA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUtb2Nz +cC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAqMCgG +CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CGSAGG +9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtpL2Nw +czAzBggrBgEFBQcCAjAnGiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVy +YXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IBAQAB +YVJTTVe7rzyTO4jc3zajErOT/COkdQTfNo0eIX1QbNynFieJvwY/jRzUZwjktIFR +2p4JtbpHGAtKtjOAOTieQ8xdDOoC1djzpE7/AbMvuvlTavtUKT+F7tPdhfXgWXJV +6Wbt8jryKyk3zZGiEhauIwZUkfjRkEtffEmZWLUd8c8rURJjfC/XHH2oyurscoxc +CjX29c9ynxSiS/VvQp1an0HvErGh69N48wj7cj8mtZ1yHzd2XCzSSR1OfTPfk0Pt +yg51p7yJaFiH21PTZegEL6zyVNOYBTKwwIi2OzpwYalD3uvK6e3OKDrfFCOxu17u +4PveESbrdyrmvLe7IVez +-----END CERTIFICATE----- + +// Subject: CN=JavaFX Runtime, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 47:f4:55:f1:da:4a:5e:f9:e3:f7:a8:03:62:17:c0:ff +-----BEGIN CERTIFICATE----- +MIIFdjCCBF6gAwIBAgIQR/RV8dpKXvnj96gDYhfA/zANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDEyOTAw +MDAwMFoXDTEyMDEyOTIzNTk1OVowfDEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt +cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE +CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEXMBUGA1UEAxQOSmF2YUZYIFJ1bnRp +bWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIzd0fAk8mI9ONc6RJ +aGieioK2FLdXEwj8zL3vdGDVmBwyR1zwYkaOIFFgF9IW/8qc4iAYA5sGUY+0g8q3 +5DuYAxfTzBB5KdaYvbuq6GGnoHIWmTirXY+1friFp8lyXSvtuEaGB1VHaBoZchEg +k+UgeVDA43dHwcT1Ov3DePczJRUes8T/QHzLX+BxUDG43vjyncCEO/AjqLZxXEz2 +xrNbKLcH3lGMJK7hdbfssUfF5BjC38Hn71HauYlA43b2no+2y0Sjulwzez2YPbDC +0GLR3TnKtA8dqOrnl5t3DniDbfOBNtBE3VOydJO0XW57Ng1HRXD023nm9ECPY2xp +0N/pAgMBAAGjggHqMIIB5jAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDB/BgNV +HR8EeDB2MHSgcqBwhm5odHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9TdW5N +aWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nSmF2YVNpZ25lZEV4 +dGVuc2lvbnNDbGFzc0IvTGF0ZXN0Q1JMLmNybDAfBgNVHSMEGDAWgBSzRyuCflO0 +c8q4uxm3voFNB5XH7TAdBgNVHQ4EFgQUvOdd0cKPj+Yik/iOBwTdphh5A+gwOwYI +KwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb25zaXRlLW9jc3AudmVy +aXNpZ24uY29tMIG1BgNVHSAEga0wgaowOQYLYIZIAYb4RQEHFwIwKjAoBggrBgEF +BQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTBtBgtghkgBhvcAg32c +PzBeMCcGCCsGAQUFBwIBFhtodHRwczovL3d3dy5zdW4uY29tL3BraS9jcHMwMwYI +KwYBBQUHAgIwJxolVmFsaWRhdGVkIEZvciBTdW4gQnVzaW5lc3MgT3BlcmF0aW9u +czATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAbGcf2NjL +AI93HG6ny2BbepaZA1a8xa/R6uUc7xV+Qw6MgLwFD4Q4i6LWUztQDvg9l68MM2/i +Y9LEi1KM4lcNbK5+D+t9x98wXBiuojXhVdp5ZmC03EyEBbriopdBsmXVLDSu/Y3+ +zowOO5xwpMK3dbgsSDs2Vt0UosD3FTcRaD3GNfOhXMp+o1grHNiXF9YgkmdQbPPZ +DQ2KBhFPCRJXBGvyKOqno/DTg0sQ3crGH/C4/4t7mnQXWldZotmJUZ0ONc9oD+Q1 +JAaguUKqIwn9yZ093ie+JWHbYNid9IIIPXYgtRxmf9a376WBhqhu56uJftBJ7x9g +eQ7Lot6CSWCiFw== +-----END CERTIFICATE----- + +// Subject: CN=Solaris INTERNAL DEVELOPMENT USE ONLY, +// OU=Solaris Cryptographic Framework, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 77:29:77:52:6a:19:7b:9a:a6:a2:c7:99:a0:e1:cd:8c +-----BEGIN CERTIFICATE----- +MIIFHjCCBAagAwIBAgIQdyl3UmoZe5qmoseZoOHNjDANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA3MDEwNDAw +MDAwMFoXDTEwMDEwMzIzNTk1OVowgZwxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl +bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxKDAmBgNV +BAsUH1NvbGFyaXMgQ3J5cHRvZ3JhcGhpYyBGcmFtZXdvcmsxLjAsBgNVBAMUJVNv +bGFyaXMgSU5URVJOQUwgREVWRUxPUE1FTlQgVVNFIE9OTFkwgZ8wDQYJKoZIhvcN +AQEBBQADgY0AMIGJAoGBALbNU4hf3mD5ArDI9pjgioAyvV3bjMPRQdCZniIeGJBp +odFlSEH+Mh64W1DsY8coeZ7FvvGJkx9IpTMJW9k8w1oJK9UNqHyAQfaYjQyXi3xQ +LJp62EvYdGfDlwOZejEcR/MbzZG+GOPMMvQj5+xyFDvLXNGfQNTnxw2qnBgCJXjj +AgMBAAGjggH1MIIB8TAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDCBiQYDVR0f +BIGBMH8wfaB7oHmGd2h0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29tL1N1bk1p +Y3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdTb2xhcmlzQ3J5cHRv +Z3JhcGhpY0ZyYW1ld29ya0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaA +FLNHK4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBRpfiGYkehTnsIzuN2H6AFb +VCZG8jA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUt +b2NzcC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAq +MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CG +SAGG9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtp +L2NwczAzBggrBgEFBQcCAjAnFiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBP +cGVyYXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IB +AQCG5soy3LFHTFbA8/5SzDRhQoJkHUnOP0t3b6nvX6vZYRp649fje7TQOPRm1pFd +CZ17J+tggdZwgzTqY4aYpJ00jZaK6pV37q/vgFC/ia6jDs8Q+ly9cEcadBZ5loYg +cmxp9p57W2MNWx8VA8oFdNtKfF0jUNXbLNtvwGHmgR6YcwLrGN1b6/9Lt9bO3ODl +FO+ZDwkfQz5ClUVrTx2dGBvKRYFqSG5S8JAfsgYhPvcacUQkA7ExyKvfRXLWVrce +ZiPpcElbx+819H2sAPvVvparVeAruZGMAtejHZp9NFoowKen5drJp9VxePS4eM49 +3DepB6lKRrNRw66LNQol4ZBz +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, CN=DigiNotar Cyber CA, +// O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000525 (07:27:10:0D) +-----BEGIN CERTIFICATE----- +MIIFWjCCBMOgAwIBAgIEBycQDTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MTAwNDEwNTQxMVoXDTExMTAwNDEwNTMxMVowYDELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANLOFQotqF6EZ639vu9Gx8i5z3P8 +9DS5+SxD52ATPXrjss87Z2yQrcC5P4RS8DVC3HTcKDu9UrSnrHJFF8bwieu0qiXy +XUte0dmHutZ9fPXOMp8QM8WxSrtekTHC0OlBwpFkfglBO9uLCDdqqspS3rU5HsCI +A6U/i5kTYUO1m4Kz7iBvz6FEouova0CfjytXraFTwoUiaZ2gP1HfC0GRDaXhqKpc +SQhdvd5wQbEPyWNr0380dAIvNFp4dRxoeoFnivPaQPBgY/SSINcDpj2jHmfEhBtB +pcmM5r3qSLYFFgizNxJa92E89zhvLpfgb1Y4VNMota0Ubi5LZLUnZbd1JQm2Bz2V +VgIKgmCyc0XgMyZRdJq51FAc9k1bW1JSE1qmf6cO4ehBVGeYjIfVydNsy9NUkgYJ +NEH3gW8/nsl8dVWw58Gzd+jDxAA1lUBwEEoF3iW7n1mlZLxHYL9g43aLE1Xd4XR6 +uc8kpmp/3mQiRFhogmoQ+T3lPhu5vfwi9GAEibtVbShV+t6OjRshFNc3izR7Tfay +shDPM7F9HGKZSMsrbHaWVb8ZDR0fu2WqG46ZtcYokOWCLXhQIJr9eS8kf/CJKWn0 +fc1zvrPtTsHR7VJej/e4142HrbLZG1ES/1az4a80fVykeIgQnp0DxqWqoiRR90kU +xbHuWUOV36toKDA/AgMBAAGjggGGMIIBgjASBgNVHRMBAf8ECDAGAQH/AgEBMFMG +A1UdIARMMEowSAYJKwYBBAGxPgEAMDswOQYIKwYBBQUHAgEWLWh0dHA6Ly93d3cu +cHVibGljLXRydXN0LmNvbS9DUFMvT21uaVJvb3QuaHRtbDAOBgNVHQ8BAf8EBAMC +AQYwgaAGA1UdIwSBmDCBlYAUpgwdn2H/Bxe1vzhG20Mw1Y6wUgaheaR3MHUxCzAJ +BgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdU +RSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVy +VHJ1c3QgR2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93 +d3cucHVibGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYD +VR0OBBYEFKv5aN/PSjfXe0WMX3LeQETDZbvCMA0GCSqGSIb3DQEBBQUAA4GBAI9o +a6VbB7pEZg4cqFwwezPkCiYE/O+eGjjWLqEf0JlHwnVkJP2eOyh2uSYoYZEMbSz4 +BJ98UAHV42mv7xXSRZskCSpmBU8lgcpdvqrBWSeuM46C9990sFWzjvjnN8huqlZE +9r1TgSOWPbT6MopTZkQloiXGpjwljPDgKAYityZB +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000505 (07:27:0F:F9) +-----BEGIN CERTIFICATE----- +MIIFODCCBKGgAwIBAgIEBycP+TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MDkyMDA5NDUzMloXDTEzMDkyMDA5NDQwNlowPjELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o +XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S +tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 +24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp +naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj +9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu +LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU +Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk +vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 +3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt +eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 +iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB +/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC +ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s +MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV +jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv +bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD +VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 +oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw +MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI +hvcNAQEFBQADgYEACcpiD427SuDUejUrBi3RKGG2rAH7g0m8rtQvLYauGYOl1h0T +4he+/jJ06XoUOMqUXvcpAWlxG5Ea/aO7qh3Ke+IW/aGjDvMMX7LhIDGUK16Sdu36 +6bUjpr8KOwOpb1JgVM1f6bcvfKIn/UGDdbYN+3gm87FF6TKVKho1IZXFonU= +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000515 (07:27:10:03) +-----BEGIN CERTIFICATE----- +MIIFODCCBKGgAwIBAgIEBycQAzANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MDkyNzEwNTMzMloXDTExMDkyNzEwNTIzMFowPjELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o +XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S +tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 +24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp +naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj +9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu +LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU +Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk +vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 +3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt +eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 +iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB +/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC +ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s +MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV +jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv +bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD +VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 +oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw +MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI +hvcNAQEFBQADgYEAWcyGZhizJlRP1jjNupZey+yZG6oMDW4Z11boriMHbYPCndBE +bVh07zmPbZsihOw9w/vm5KbVX5CgxUv4Rhzh/20Faixf3P3bpWg0qgzHVVusNVR/ +P50aKkpdK3hp+QLl56e+lWOddSAINIpmcuyDI1hyuzB+GJEASm9tNU/6rs8= +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Root CA, +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US, +// Serial: 1184644297 (46:9C:3C:C9) +-----BEGIN CERTIFICATE----- +MIIFSDCCBLGgAwIBAgIERpw8yTANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA0 +MjYwNTAwMDBaFw0xMzA4MTQyMDEyMzZaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI +hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt +OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx +hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 +gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D +IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T +BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs +Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 +5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf +DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX +9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e +7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj +ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB +BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF +BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD +VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy +bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G +A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob +BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAI979rBep8tu3TeLunapgsZ0jtXp +GDFjKWSk87dj1jCyYi+q/GyDyZ6ZQZNRP0sF+6twscq05lClWNy3TROMp7QeuoLO +G7Utw3OJaswUtp4YglANMRTHEe3g9ltifUXRH5tSuy7u6yi4LD4WTm5ULP6r/g6l +0CnjXYb0+b1Fmz6U +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Root CA, +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US, +// Serial: 1184640175 (46:9C:2C:AF) +-----BEGIN CERTIFICATE----- +MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 +MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI +hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt +OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx +hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 +gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D +IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T +BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs +Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 +5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf +DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX +9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e +7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj +ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB +BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF +BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD +VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy +bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G +A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob +BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh +xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd +ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP +ZFdYf+hthc3m6IcJ +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2, +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Organisatie CA - G2, +// O=Staat der Nederlanden, +// C=NL +// Serial: 20001983 (01:31:34:bf) +-----BEGIN CERTIFICATE----- +MIIGnDCCBISgAwIBAgIEATE0vzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMTIwMAYDVQQDDClTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3JnYW5pc2F0aWUgQ0EgLSBHMjAeFw0xMDA1MTIw +ODUxMzhaFw0yMDAzMjMwOTUwMDRaMFoxCzAJBgNVBAYTAk5MMRcwFQYDVQQKDA5E +aWdpTm90YXIgQi5WLjEyMDAGA1UEAwwpRGlnaU5vdGFyIFBLSW92ZXJoZWlkIENB +IE9yZ2FuaXNhdGllIC0gRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCxExkPJ+Zs1FWGS9DsiYpFkXisR71HK+T8RetPtCZzWzfTw3/2497Xo/gtaMUI +PkuU1uSHJTZrhLUYdPMoWHMvm2rPvAQe9t7dr/xLqvXbZmIlASWC3vKXWhBu3V2p +IrEEqSNzOvhxrR3PhETrR9Gvbch8KKvH8jd6dF9fxQIUiqNa4xtsAeNdjtlo1vQJ +GzLckbUs9SDrjANtJkm4k8SFXdjSm69WaswFM8ygQp40VUSca6DUEtArVM23iQ3l +9uvo+4UBM096a/GdcjOWDveyhKWlJ8Qn8VFzKXe6Z27+TNy04qGhgS85SY1DOBPO +0KVcwoc6AGdlQiPxNlkKHaNRyLyjlCox3+M88p0aPASw77EKMBNzttfzo0wBdRSF +eMDXijlYhVD6LubFvs+LP6+PNtQlCS3SD6xyk/K/i9RQs/kVUJuZ9RTZ+4uRozIm +JqD43ztggYaDeVsr6xM9KTrBbd29no6H1kquNJcF7hSm9tw4fkrpJFQHPZdoN0Zr +DceoIa8TVOQJavFNRgrJXfubT73e+7dUy7g4nKc5+2otwHuNq6WnV+xKkoozxeEg +XHPYkJIrgNUPhhhpfDlPhIa890xb89W0yqDC8DciynlSH1PmqvOQsDvd8ij9rOvF +BiSgydQvD1j9tZ7sD8+yWdCiBHo4aq5y+73wJWKUCacFCwIDAQABo4IBYTCCAV0w +SAYDVR0gBEEwPzA9BgRVHSAAMDUwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cuZGln +aW5vdGFyLm5sL2Nwcy9wa2lvdmVyaGVpZDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjCBhQYDVR0jBH4wfIAUORCLSZJc22ESIM1JnRqO2pxnQLmhXqRc +MFoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4x +KzApBgNVBAMMIlN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBIC0gRzKCBACY +lvQwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5wa2lvdmVyaGVpZC5ubC9E +b21PcmdhbmlzYXRpZUxhdGVzdENSTC1HMi5jcmwwHQYDVR0OBBYEFLxdlDvZq3sD +JXNhwtst7vyrj2WhMA0GCSqGSIb3DQEBCwUAA4ICAQCP/C1Mt9kt1R+978v0t2gX +dZ1O1ffdnPEqJu2forYcA9VTs+wIzzTi48P0tRYvyMO+19NzqwA2+RpKftZj6V5G +uqW2jhW3oyrYQx3vXcgfgYWzi/f/PPTZ9EYIP5y8HaDZqEzNJVJOCrEg9x/pQ9lU +RoETmsBedGwqmDLq/He7DaWiMZgifnx859qkrey3LhoZcfhIUNpDjyyE3cFAJ+O1 +8BVOltT4XOOGKUYr1zsH6zh/yIZXl9PvKjPEF1DVZGlrK2tFXl0vF8paTs/D1zk8 +9TufRrmb5w5Jl53W1eMbD+qPAU6aE5RZCgIHSEsaYKt/T+0L2FUNaG9VnGllFULs +wNzdbKzDFs4LHVabpMTE0i7gD+JEJytQaaTcYuiKISlCbMwAOpZ2m+9AwKRed4Qy +bCYqOWauXeO5ubIsaB8empADOfCqs6TMSYsYNOk3yXspx4R8b0QVL+xhWQTJRcui +1lKifH8pktZKxYtCqNT+6tjHhyMY5J16fXNAUpigrm7jBT8FD+Clxm1N7YM3iJzH +89xCmmq21yFJNnfy7xhPxXDZnunetyuL9Lx+KN8NQMmFXK6dxTH/0FwOtah+8Okv +uq+IruW10Vilr5xxpykBkINpN4IFuvwJwQhujHg7wzMCgD9EhQgd31VWCK0shS1d +sQPhrqp0xaTzTro3mHuCuQ== +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven, +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Overheid CA +// O=Staat der Nederlanden, +// C=NL +// Serial: 20015536 (01:31:69:b0) +-----BEGIN CERTIFICATE----- +MIIEiDCCA3CgAwIBAgIEATFpsDANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDcwNzA1MDg0MjA3WhcN +MTUwNzI3MDgzOTQ2WjBfMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy +IEIuVi4xNzA1BgNVBAMTLkRpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp +ZCBlbiBCZWRyaWp2ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc +vdKnTmoKuzuiheF/AK2+tDBomAfNoHrElM9x+Yo35FPrV3bMi+Zs/u6HVcg+uwQ5 +AKeAeKxbT370vbhUuHE7BzFJOZNUfCA7eSuPu2GQfbGs5h+QLp1FAalkLU3DL7nn +UNVOKlyrdnY3Rtd57EKZ96LspIlw3Dgrh6aqJOadkiQbvvb91C8ZF3rmMgeUVAVT +Q+lsvK9Hy7zL/b07RBKB8WtLu+20z6slTxjSzAL8o0+1QjPLWc0J3NNQ/aB2jKx+ +ZopC9q0ckvO2+xRG603XLzDgbe5bNr5EdLcgBVeFTegAGaL2DOauocBC36esgl3H +aLcY5olLmmv6znn58yynAgMBAAGjggFQMIIBTDBIBgNVHSAEQTA/MD0GBFUdIAAw +NTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5kaWdpbm90YXIubmwvY3BzL3BraW92 +ZXJoZWlkMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIGABgNVHSME +eTB3gBQLhtYPd6NosftkCcOIblwEHFfpPaFZpFcwVTELMAkGA1UEBhMCTkwxHjAc +BgNVBAoTFVN0YWF0IGRlciBOZWRlcmxhbmRlbjEmMCQGA1UEAxMdU3RhYXQgZGVy +IE5lZGVybGFuZGVuIFJvb3QgQ0GCBACYmnkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0 +cDovL2NybC5wa2lvdmVyaGVpZC5ubC9Eb21PdkxhdGVzdENSTC5jcmwwHQYDVR0O +BBYEFEwIyY128ZjHPt881y91DbF2eZfMMA0GCSqGSIb3DQEBBQUAA4IBAQAMlIca +v03jheLu19hjeQ5Q38aEW9K72fUxCho1l3TfFPoqDz7toOMI9tVOW6+mriXiRWsi +D7dUKH6S3o0UbNEc5W50BJy37zRERd/Jgx0ZH8Apad+J1T/CsFNt5U4X5HNhIxMm +cUP9TFnLw98iqiEr2b+VERqKpOKrp11Lbyn1UtHk0hWxi/7wA8+nfemZhzizDXMU +5HIs4c71rQZIZPrTKbmi2Lv01QulQERDjqC/zlqlUkxk0xcxYczopIro5Ij76eUv +BjMzm5RmZrGrUDqhCYF0U1onuabSJc/Tw6f/ltAv6uAejVLpGBwgCkegllYOQJBR +RKwa/fHuhR/3Qlpl +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Overheid +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Overheid CA +// O=Staat der Nederlanden, +// C=NL +// Serial: 20006006 (01:31:44:76) +-----BEGIN CERTIFICATE----- +MIIEezCCA2OgAwIBAgIEATFEdjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDQwNjI0MDgxOTMyWhcN +MTAwNjIzMDgxNzM2WjBSMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy +IEIuVi4xKjAoBgNVBAMTIURpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp +ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANSlrubta5tlOjVCi/gb +yLCvRqfBjxG8H594VcKHu0WAYc99SPZF9cycj5mw2GyfQvy/WIrGrL4iyNq1gSqR +0QA/mTXKZIaPqzpDhdm+VvrKkmjrbZfaQxgMSs3ChtBsjcP9Lc0X1zXZ4Q8nBe3k +BTp+zehINfmbjoEgXLxsMR5RQ6GxzKjuC04PQpbJQgTIakglKaqYcDDZbEscWgPV +Hgj/2aoHlj6leW/ThHZ+O41jUguEmBLZA3mu3HrCfrHntb5dPt0ihzSx7GtD/SaX +5HBLxnP189YuqMk5iRA95CtiSdKauvon/xRKRLNgG6XAz0ctSoY7xLDdiBVU5kJd +FScCAwEAAaOCAVAwggFMMEgGA1UdIARBMD8wPQYEVR0gADA1MDMGCCsGAQUFBwIB +FidodHRwOi8vd3d3LmRpZ2lub3Rhci5ubC9jcHMvcGtpb3ZlcmhlaWQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgYAGA1UdIwR5MHeAFAuG1g93o2ix ++2QJw4huXAQcV+k9oVmkVzBVMQswCQYDVQQGEwJOTDEeMBwGA1UEChMVU3RhYXQg +ZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQYIEAJiaeTA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnBraW92 +ZXJoZWlkLm5sL0RvbU92TGF0ZXN0Q1JMLmNybDAdBgNVHQ4EFgQUvRaYQh2+kdE9 +wpcl4CjXWOC1f+IwDQYJKoZIhvcNAQEFBQADggEBAGhQsCWLiaN2EOhPAW+JQP6o +XBOrLv5w6joahzBFVn1BiefzmlMKjibqKYxURRvMAsMkh82/MfL8V0w6ugxl81lu +i42dcxl9cKSVXKMw4bbBzJ2VQI5HTIABwefeNuy/eX6idVwYdt3ajAH7fUA8Q9Cq +vr6H8B+8mwoEqTVTEVlCSsC/EXsokYEUr06PPzRudKjDmijgj7zFaIioZNc8hk7g +ufEgrs/tmcNGylrwRHgCXjCRBt2NHlZ08l7A1AGU8HcHlSbG9Un/2q9kVHUkps0D +gtUaEK+x6jpAu/R8Ojezu/+ZEcwwjI/KOhG+84+ejFmtyEkrUdsAdEdLf/2dKsw= +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Services 1024 CA +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority, +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US +// Serial: 1184640176 (46:9c:2c:b0) +-----BEGIN CERTIFICATE----- +MIIDzTCCAzagAwIBAgIERpwssDANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 +MjYxNTU5MDBaFw0xMzA4MjYxNjI5MDBaMGgxCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxIzAhBgNVBAMTGkRpZ2lOb3RhciBTZXJ2aWNlcyAxMDI0IENB +MSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA2ptNXTz50eKLxsYIIMXZHkjsZlhneWIrQWP0iY1o2q+4 +lDaLGSSkoJPSmQ+yrS01Tc0vauH5mxkrvAQafi09UmTN8T5nD4ku6PJPrqYIoYX+ +oakJ5sarPkP8r3oDkdqmOaZh7phPGKjTs69mgumfvN1y+QYEvRLZGCTnq5NTi1kC +AwEAAaOCASYwggEiMBIGA1UdEwEB/wQIMAYBAf8CAQAwJwYDVR0lBCAwHgYIKwYB +BQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDBDARBgNVHSAECjAIMAYGBFUdIAAwMwYI +KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l +dDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1c3QubmV0L3NlcnZl +cjEuY3JsMB0GA1UdDgQWBBT+3JRJDG/vXH/G8RKZTxZJrfuCZTALBgNVHQ8EBAMC +AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowGQYJKoZIhvZ9B0EA +BAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEFBQADgYEAY3RqN6k/lpxmyFisCcnv +9WWUf6MCxDgxvV0jh+zUVrLJsm7kBQb87PX6iHBZ1O7m3bV6oKNgLwIMq94SXa/w +NUuqikeRGvWFLELHHe+VQ7NeuJWTpdrFKKqtci0xrZlrbP+MISevrZqRK8fdWMNu +B8WfedLHjFW/TMcnXlEWKz4= +-----END CERTIFICATE----- + +// Subject: CN=Buster Paper Comercial Ltda, +// O=Buster Paper Comercial Ltda, +// L=S?o Jos? Dos Campos, +// ST=S?o Paulo, +// C=BR +// Issuer: CN=DigiCert Assured ID Code Signing CA-1, +// OU=www.digicert.com, +// O=DigiCert Inc, +// C=US +// Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12 +-----BEGIN CERTIFICATE----- +MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv +ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow +gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT +w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l +cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL +HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn +2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4 +tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi +mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf +Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx +BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw +HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT +BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js +My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6 +Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud +IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov +L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG +AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD +AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh +AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy +AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn +ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs +AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp +AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl +AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho +dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl +cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et +MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI +hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft +jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e +gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44 +/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc +BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj +XMuKLxbh7g== +-----END CERTIFICATE----- + +// Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, +// O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, +// L=S?o Paulo, +// ST=S?o Paulo, +// C=BR +// Issuer: CN=DigiCert Assured ID Code Signing CA-1, +// OU=www.digicert.com, +// O=DigiCert Inc, +// C=US +// Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f +-----BEGIN CERTIFICATE----- +MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv +ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow +gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT +w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF +TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB +IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR +4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V +JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW +kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb +0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj +NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV +HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30 +o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD +MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1 +cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t +L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB +hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z +c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A +eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA +ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA +IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA +YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA +cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA +aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA +ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC +BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 +LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp +Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA +MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ +A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE +Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA +XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9 +UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL +zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc +-----END CERTIFICATE----- + +// Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT, +// O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US +// Issuer: SERIALNUMBER=07969287, +// CN=Go Daddy Secure Certification Authority, +// OU=http://certificates.godaddy.com/repository, +// O="GoDaddy.com, Inc.", +// L=Scottsdale, +// ST=Arizona, +// C=US +// Serial: 2b:73:43:2a:a8:4f:44 +-----BEGIN CERTIFICATE----- +MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY +BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm +aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5 +IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky +ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC +VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS +RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh +BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU +IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277 +p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E +jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV +9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/ +U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw +DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E +BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n +ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH +AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w +gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk +eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku +Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9 +rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB +XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K +v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC +2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP +4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR +DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI +LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU= +-----END CERTIFICATE----- + +// Subject: CN=eDellRoot +// Issuer: CN=eDellRoot +// Serial Number: +// 6b:c5:7b:95:18:93:aa:97:4b:62:4a:c0:88:fc:3b:b6 +-----BEGIN CERTIFICATE----- +MIIC8zCCAd+gAwIBAgIQa8V7lRiTqpdLYkrAiPw7tjAJBgUrDgMCHQUAMBQxEjAQ +BgNVBAMTCWVEZWxsUm9vdDAeFw0xNTA0MDcxMDIzMjdaFw0zOTEyMzEyMzU5NTla +MBQxEjAQBgNVBAMTCWVEZWxsUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAL3RJg1uzVuEX0Hw4XWGzs6oI9W+o7HZdVdBMMVb4Gzb4uZjCTNjbPx4 +b8LNFL1uArUt+5VVMQDsOTY3Lg/Xe/UNukY2b+0llUOzzBYYpbsFcco4n6SsTvDh +Ni5t+kPo7c23ZrYBPmOu82eEJ6cavs/t39u+wFOkXXwvRCiHA/lWyNWNEPh17+bC +EP3q5N+JrV+6Ho3zQPEv5QUJYdmXsMmD2CMQojeQUj68J91P5w5BKjurG0xjivzh +Soie9ym7VRwLFjWScRuw/9XV6CLqTyL5xrqiiDp1uTOuqNj3uxyts9ocbsoJXuxj +5iEYkSM1nvLupEv+lgy9WqzIEFMm1l8CAwEAAaNJMEcwRQYDVR0BBD4wPIAQYA/f +EzPwmaRcZuSaa/VZ1KEWMBQxEjAQBgNVBAMTCWVEZWxsUm9vdIIQa8V7lRiTqpdL +YkrAiPw7tjAJBgUrDgMCHQUAA4IBAQArfdcScsezj8ooJ92UwwnPgg36noOgiUs5 +XzPLP4h0JpUYQVKB9hY1WTDwRUfTKGh7oNOowd027a/rVSb/TNeoiJIvMKn4gbvV +CWAiHhO8u2u0RkHCDVsa7e0i4ncpueWsihjn6jBrY8T+7eDYwiFT/F03A8NJ7mK5 +lZA8SFd5CTDy3EBUU5UwzXUc5HoIRUxXSPycu3aIBWawg3sCdKiAoikScPAWj0bM +0vmsP/8QSlTOBqO+QFQ6R82BtTvBNU3qbVICV4QObsxib++FAFL56NApPqskg7Vz +LfNIAjKabHUcjbuZkmg6jr4BfYW7+oQDHCsYgADjjKGdKz/8U/fP +-----END CERTIFICATE-----
diff --git a/make/data/cacerts/globalsignr2ca b/make/data/cacerts/globalsignr2ca deleted file mode 100644 index 746d1fa..0000000 --- a/make/data/cacerts/globalsignr2ca +++ /dev/null
@@ -1,29 +0,0 @@ -Owner: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2 -Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2 -Serial number: 400000000010f8626e60d -Valid from: Fri Dec 15 08:00:00 GMT 2006 until: Wed Dec 15 08:00:00 GMT 2021 -Signature algorithm name: SHA1withRSA -Subject Public Key Algorithm: 2048-bit RSA key -Version: 3 ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE-----
diff --git a/make/data/currency/CurrencyData.properties b/make/data/currency/CurrencyData.properties index a4ad6d6..c4400bb 100644 --- a/make/data/currency/CurrencyData.properties +++ b/make/data/currency/CurrencyData.properties
@@ -32,7 +32,7 @@ # Version of the currency code information in this class. # It is a serial number that accompanies with each amendment. -dataVersion=169 +dataVersion=170 # List of all valid ISO 4217 currency codes. # To ensure compatibility, do not remove codes. @@ -54,7 +54,7 @@ SBD090-SCR690-SDD736-SDG938-SEK752-SGD702-SHP654-SIT705-SKK703-SLL694-SOS706-\ SRD968-SRG740-SSP728-STD678-STN930-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TMT934-TND788-TOP776-\ TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-UYI940-\ - UYU858-UZS860-VEB862-VEF937-VES928-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\ + UYU858-UZS860-VEB862-VED926-VEF937-VES928-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\ XBB956-XBC957-XBD958-XCD951-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\ XPT962-XSU994-XTS963-XUA965-XXX999-YER886-YUM891-ZAR710-ZMK894-ZMW967-ZWD716-ZWL932-\ ZWN942-ZWR935
diff --git a/make/data/tzdata/VERSION b/make/data/tzdata/VERSION index 71632a7..3a40c91 100644 --- a/make/data/tzdata/VERSION +++ b/make/data/tzdata/VERSION
@@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2021a +tzdata2021e
diff --git a/make/data/tzdata/africa b/make/data/tzdata/africa index 5de2e5f..0f36771 100644 --- a/make/data/tzdata/africa +++ b/make/data/tzdata/africa
@@ -53,9 +53,6 @@ # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. # https://www.jstor.org/stable/1774359 # -# A reliable and entertaining source about time zones is -# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997). -# # European-style abbreviations are commonly used along the Mediterranean. # For sub-Saharan Africa abbreviations were less standardized. # Previous editions of this database used WAT, CAT, SAT, and EAT @@ -176,8 +173,9 @@ # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Abidjan -0:16:08 - LMT 1912 0:00 - GMT +Link Africa/Abidjan Africa/Accra # Ghana Link Africa/Abidjan Africa/Bamako # Mali -Link Africa/Abidjan Africa/Banjul # Gambia +Link Africa/Abidjan Africa/Banjul # The Gambia Link Africa/Abidjan Africa/Conakry # Guinea Link Africa/Abidjan Africa/Dakar # Senegal Link Africa/Abidjan Africa/Freetown # Sierra Leone @@ -404,93 +402,8 @@ # Gabon # See Africa/Lagos. -# Gambia -# See Africa/Abidjan. - +# The Gambia # Ghana - -# From P Chan (2020-11-20): -# Interpretation Amendment Ordinance, 1915 (No.24 of 1915) [1915-11-02] -# Ordinances of the Gold Coast, Ashanti, Northern Territories 1915, p 69-71 -# https://books.google.com/books?id=ErA-AQAAIAAJ&pg=PA70 -# This Ordinance added "'Time' shall mean Greenwich Mean Time" to the -# Interpretation Ordinance, 1876. -# -# Determination of the Time Ordinance, 1919 (No. 18 of 1919) [1919-11-24] -# Ordinances of the Gold Coast, Ashanti, Northern Territories 1919, p 75-76 -# https://books.google.com/books?id=MbA-AQAAIAAJ&pg=PA75 -# This Ordinance removed the previous definition of time and introduced DST. -# -# Time Determination Ordinance (Cap. 214) -# The Laws of the Gold Coast (including Togoland Under British Mandate) -# Vol. II (1937), p 2328 -# https://books.google.com/books?id=Z7M-AQAAIAAJ&pg=PA2328 -# Revised edition of the 1919 Ordinance. -# -# Time Determination (Amendment) Ordinance, 1940 (No. 9 of 1940) [1940-04-06] -# Annual Volume of the Laws of the Gold Coast: -# Containing All Legislation Enacted During Year 1940, p 22 -# https://books.google.com/books?id=1ao-AQAAIAAJ&pg=PA22 -# This Ordinance changed the forward transition from September to May. -# -# Defence (Time Determination Ordinance Amendment) Regulations, 1942 -# (Regulations No. 6 of 1942) [1942-01-31, commenced on 1942-02-08] -# Annual Volume of the Laws of the Gold Coast: -# Containing All Legislation Enacted During Year 1942, p 48 -# https://books.google.com/books?id=Das-AQAAIAAJ&pg=PA48 -# These regulations advanced the [standard] time by thirty minutes. -# -# Defence (Time Determination Ordinance Amendment (No.2)) Regulations, -# 1942 (Regulations No. 28 of 1942) [1942-04-25] -# Annual Volume of the Laws of the Gold Coast: -# Containing All Legislation Enacted During Year 1942, p 87 -# https://books.google.com/books?id=Das-AQAAIAAJ&pg=PA87 -# These regulations abolished DST and changed the time to GMT+0:30. -# -# Defence (Revocation) (No.4) Regulations, 1945 (Regulations No. 45 of -# 1945) [1945-10-24, commenced on 1946-01-06] -# Annual Volume of the Laws of the Gold Coast: -# Containing All Legislation Enacted During Year 1945, p 256 -# https://books.google.com/books?id=9as-AQAAIAAJ&pg=PA256 -# These regulations revoked the previous two sets of Regulations. -# -# Time Determination (Amendment) Ordinance, 1945 (No. 18 of 1945) [1946-01-06] -# Annual Volume of the Laws of the Gold Coast: -# Containing All Legislation Enacted During Year 1945, p 69 -# https://books.google.com/books?id=9as-AQAAIAAJ&pg=PA69 -# This Ordinance abolished DST. -# -# Time Determination (Amendment) Ordinance, 1950 (No. 26 of 1950) [1950-07-22] -# Annual Volume of the Laws of the Gold Coast: -# Containing All Legislation Enacted During Year 1950, p 35 -# https://books.google.com/books?id=e60-AQAAIAAJ&pg=PA35 -# This Ordinance restored DST but with thirty minutes offset. -# -# Time Determination Ordinance (Cap. 264) -# The Laws of the Gold Coast, Vol. V (1954), p 380 -# https://books.google.com/books?id=Mqc-AQAAIAAJ&pg=PA380 -# Revised edition of the Time Determination Ordinance. -# -# Time Determination (Amendment) Ordinance, 1956 (No. 21 of 1956) [1956-08-29] -# Annual Volume of the Ordinances of the Gold Coast Enacted During the -# Year 1956, p 83 -# https://books.google.com/books?id=VLE-AQAAIAAJ&pg=PA83 -# This Ordinance abolished DST. - -# Rule NAME FROM TO - IN ON AT SAVE LETTER/S -Rule Ghana 1919 only - Nov 24 0:00 0:20 +0020 -Rule Ghana 1920 1942 - Jan 1 2:00 0 GMT -Rule Ghana 1920 1939 - Sep 1 2:00 0:20 +0020 -Rule Ghana 1940 1941 - May 1 2:00 0:20 +0020 -Rule Ghana 1950 1955 - Sep 1 2:00 0:30 +0030 -Rule Ghana 1951 1956 - Jan 1 2:00 0 GMT - -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Africa/Accra -0:00:52 - LMT 1915 Nov 2 - 0:00 Ghana %s 1942 Feb 8 - 0:30 - +0030 1946 Jan 6 - 0:00 Ghana %s - # Guinea # See Africa/Abidjan. @@ -755,7 +668,7 @@ # See Africa/Nairobi. # Morocco -# See the 'europe' file for Spanish Morocco (Africa/Ceuta). +# See Africa/Ceuta for Spanish Morocco. # From Alex Krivenyshev (2008-05-09): # Here is an article that Morocco plan to introduce Daylight Saving Time between @@ -1405,23 +1318,21 @@ 0:13:35 - LMT 1914 Jan 1 0:30 - +0030 1919 Sep 1 1:00 - WAT -Link Africa/Lagos Africa/Bangui # Central African Republic -Link Africa/Lagos Africa/Brazzaville # Rep. of the Congo -Link Africa/Lagos Africa/Douala # Cameroon -Link Africa/Lagos Africa/Kinshasa # Dem. Rep. of the Congo (west) -Link Africa/Lagos Africa/Libreville # Gabon -Link Africa/Lagos Africa/Luanda # Angola -Link Africa/Lagos Africa/Malabo # Equatorial Guinea -Link Africa/Lagos Africa/Niamey # Niger -Link Africa/Lagos Africa/Porto-Novo # Benin +Link Africa/Lagos Africa/Bangui # Central African Republic +Link Africa/Lagos Africa/Brazzaville # Rep. of the Congo +Link Africa/Lagos Africa/Douala # Cameroon +Link Africa/Lagos Africa/Kinshasa # Dem. Rep. of the Congo (west) +Link Africa/Lagos Africa/Libreville # Gabon +Link Africa/Lagos Africa/Luanda # Angola +Link Africa/Lagos Africa/Malabo # Equatorial Guinea +Link Africa/Lagos Africa/Niamey # Niger +Link Africa/Lagos Africa/Porto-Novo # Benin # Réunion # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # Saint-Denis 4:00 - +04 # -# Crozet Islands also observes Réunion time; see the 'antarctica' file. -# # Scattered Islands (Îles Éparses) administered from Réunion are as follows. # The following information about them is taken from # Îles Éparses (<http://www.outre-mer.gouv.fr/domtom/ile.htm>, 1997-07-22, @@ -1513,8 +1424,8 @@ Zone Africa/Johannesburg 1:52:00 - LMT 1892 Feb 8 1:30 - SAST 1903 Mar 2:00 SA SAST -Link Africa/Johannesburg Africa/Maseru # Lesotho -Link Africa/Johannesburg Africa/Mbabane # Eswatini +Link Africa/Johannesburg Africa/Maseru # Lesotho +Link Africa/Johannesburg Africa/Mbabane # Eswatini # # Marion and Prince Edward Is # scientific station since 1947 @@ -1550,12 +1461,13 @@ 3:00 - EAT 2017 Nov 1 2:00 - CAT +# South Sudan + # From Steffen Thorsen (2021-01-18): # "South Sudan will change its time zone by setting the clock back 1 # hour on February 1, 2021...." # from https://eyeradio.org/south-sudan-adopts-new-time-zone-makuei/ -# South Sudan # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Juba 2:06:28 - LMT 1931 2:00 Sudan CA%sT 2000 Jan 15 12:00 @@ -1660,7 +1572,7 @@ Rule Tunisia 2006 2008 - Mar lastSun 2:00s 1:00 S Rule Tunisia 2006 2008 - Oct lastSun 2:00s 0 - -# See Europe/Paris for PMT-related transitions. +# See Europe/Paris commentary for PMT-related transitions. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Tunis 0:40:44 - LMT 1881 May 12 0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
diff --git a/make/data/tzdata/antarctica b/make/data/tzdata/antarctica index 509fadc..13f024e 100644 --- a/make/data/tzdata/antarctica +++ b/make/data/tzdata/antarctica
@@ -171,7 +171,7 @@ # # Alfred Faure, Possession Island, Crozet Islands, -462551+0515152, since 1964; # sealing & whaling stations operated variously 1802/1911+; -# see Indian/Reunion. +# see Asia/Dubai. # # Martin-de-Viviès, Amsterdam Island, -374105+0773155, since 1950 # Port-aux-Français, Kerguelen Islands, -492110+0701303, since 1951; @@ -185,17 +185,7 @@ 5:00 - +05 # # year-round base in the main continent -# Dumont d'Urville, Île des Pétrels, -6640+14001, since 1956-11 -# <https://en.wikipedia.org/wiki/Dumont_d'Urville_Station> (2005-12-05) -# -# Another base at Port-Martin, 50km east, began operation in 1947. -# It was destroyed by fire on 1952-01-14. -# -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Antarctica/DumontDUrville 0 - -00 1947 - 10:00 - +10 1952 Jan 14 - 0 - -00 1956 Nov - 10:00 - +10 +# Dumont d'Urville - see Pacific/Port_Moresby. # France & Italy - year-round base # Concordia, -750600+1232000, since 2005 @@ -211,20 +201,7 @@ # Zuchelli, Terra Nova Bay, -744140+1640647, since 1986 # Japan - year-round bases -# Syowa (also known as Showa), -690022+0393524, since 1957 -# -# From Hideyuki Suzuki (1999-02-06): -# In all Japanese stations, +0300 is used as the standard time. -# -# Syowa station, which is the first antarctic station of Japan, -# was established on 1957-01-29. Since Syowa station is still the main -# station of Japan, it's appropriate for the principal location. -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Antarctica/Syowa 0 - -00 1957 Jan 29 - 3:00 - +03 -# See: -# NIPR Antarctic Research Activities (1999-08-17) -# http://www.nipr.ac.jp/english/ara01.html +# See Asia/Riyadh. # S Korea - year-round base # Jang Bogo, Terra Nova Bay, -743700+1641205 since 2014
diff --git a/make/data/tzdata/asia b/make/data/tzdata/asia index 143d8e8..cfe4874 100644 --- a/make/data/tzdata/asia +++ b/make/data/tzdata/asia
@@ -57,9 +57,6 @@ # Byalokoz EL. New Counting of Time in Russia since July 1, 1919. # (See the 'europe' file for a fuller citation.) # -# A reliable and entertaining source about time zones is -# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997). -# # The following alphabetic abbreviations appear in these tables # (corrections are welcome): # std dst @@ -2257,6 +2254,14 @@ # From Paul Eggert (2013-12-11): # As Steffen suggested, consider the past 21-month experiment to be DST. +# From Steffen Thorsen (2021-09-24): +# The Jordanian Government announced yesterday that they will start DST +# in February instead of March: +# https://petra.gov.jo/Include/InnerPage.jsp?ID=37683&lang=en&name=en_news (English) +# https://petra.gov.jo/Include/InnerPage.jsp?ID=189969&lang=ar&name=news (Arabic) +# From the Arabic version, it seems to say it would be at midnight +# (assume 24:00) on the last Thursday in February, starting from 2022. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Jordan 1973 only - Jun 6 0:00 1:00 S Rule Jordan 1973 1975 - Oct 1 0:00 0 - @@ -2287,8 +2292,9 @@ Rule Jordan 2005 only - Sep lastFri 0:00s 0 - Rule Jordan 2006 2011 - Oct lastFri 0:00s 0 - Rule Jordan 2013 only - Dec 20 0:00 0 - -Rule Jordan 2014 max - Mar lastThu 24:00 1:00 S +Rule Jordan 2014 2021 - Mar lastThu 24:00 1:00 S Rule Jordan 2014 max - Oct lastFri 0:00s 0 - +Rule Jordan 2022 max - Feb lastThu 24:00 1:00 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Amman 2:23:44 - LMT 1931 2:00 Jordan EE%sT @@ -2763,7 +2769,8 @@ # # peninsular Malaysia # taken from Mok Ly Yng (2003-10-30) -# http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html +# https://web.archive.org/web/20190822231045/http://www.math.nus.edu.sg/~mathelmr/teaching/timezone.html +# This agrees with Singapore since 1905-06-01. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Kuala_Lumpur 6:46:46 - LMT 1901 Jan 1 6:55:25 - SMT 1905 Jun 1 # Singapore M.T. @@ -3402,11 +3409,6 @@ # shall [end] on Oct 24th 2020 at 01:00AM by delaying the clock by 60 minutes. # http://www.palestinecabinet.gov.ps/portal/Meeting/Details/51584 -# From Tim Parenti (2020-10-20): -# Predict future fall transitions at 01:00 on the Saturday preceding October's -# last Sunday (i.e., Sat>=24). This is consistent with our predictions since -# 2016, although the time of the change differed slightly in 2019. - # From Pierre Cashon (2020-10-20): # The summer time this year started on March 28 at 00:00. # https://wafa.ps/ar_page.aspx?id=GveQNZa872839351758aGveQNZ @@ -3419,6 +3421,17 @@ # For now, guess spring-ahead transitions are at 00:00 on the Saturday # preceding March's last Sunday (i.e., Sat>=24). +# From P Chan (2021-10-18): +# http://wafa.ps/Pages/Details/34701 +# Palestine winter time will start from midnight 2021-10-29 (Thursday-Friday). +# +# From Heba Hemad, Palestine Ministry of Telecom & IT (2021-10-20): +# ... winter time will begin in Palestine from Friday 10-29, 01:00 AM +# by 60 minutes backwards. +# +# From Paul Eggert (2021-10-20): +# Guess future fall transitions on October's last Friday at 01:00. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 - @@ -3454,7 +3467,8 @@ Rule Palestine 2019 only - Mar 29 0:00 1:00 S Rule Palestine 2019 only - Oct Sat>=24 0:00 0 - Rule Palestine 2020 max - Mar Sat>=24 0:00 1:00 S -Rule Palestine 2020 max - Oct Sat>=24 1:00 0 - +Rule Palestine 2020 only - Oct 24 1:00 0 - +Rule Palestine 2021 max - Oct lastFri 1:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct @@ -3523,6 +3537,12 @@ # influence of the sources. There is no current abbreviation for DST, # so use "PDT", the usual American style. +# From P Chan (2021-05-10): +# Here's a fairly comprehensive article in Japanese: +# https://wiki.suikawiki.org/n/Philippine%20Time +# From Paul Eggert (2021-05-10): +# The info in the Japanese table has not been absorbed (yet) below. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Phil 1936 only - Nov 1 0:00 1:00 D Rule Phil 1937 only - Feb 1 0:00 0 S @@ -3589,12 +3609,13 @@ # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14 3:00 - +03 +Link Asia/Riyadh Antarctica/Syowa Link Asia/Riyadh Asia/Aden # Yemen Link Asia/Riyadh Asia/Kuwait # Singapore # taken from Mok Ly Yng (2003-10-30) -# http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html +# https://web.archive.org/web/20190822231045/http://www.math.nus.edu.sg/~mathelmr/teaching/timezone.html # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1 6:55:25 - SMT 1905 Jun 1 # Singapore M.T.
diff --git a/make/data/tzdata/australasia b/make/data/tzdata/australasia index e28538e..a6ecb3a 100644 --- a/make/data/tzdata/australasia +++ b/make/data/tzdata/australasia
@@ -408,9 +408,22 @@ # "Minister for Employment, Parveen Bala says they had never thought of # stopping daylight saving. He says it was just to decide on when it should # start and end. Bala says it is a short period..." -# Since the end date is still in line with our ongoing predictions, assume for -# now that the later-than-usual start date is a one-time departure from the -# recent second Sunday in November pattern. +# +# From Tim Parenti (2021-10-11), per Jashneel Kumar (2021-10-11) and P Chan +# (2021-10-12): +# https://www.fiji.gov.fj/Media-Centre/Speeches/English/PM-BAINIMARAMA-S-COVID-19-ANNOUNCEMENT-10-10-21 +# https://www.fbcnews.com.fj/news/covid-19/curfew-moved-back-to-11pm/ +# In a 2021-10-10 speech concerning updated Covid-19 mitigation measures in +# Fiji, prime minister Josaia Voreqe "Frank" Bainimarama announced the +# suspension of DST for the 2021/2022 season: "Given that we are in the process +# of readjusting in the midst of so many changes, we will also put Daylight +# Savings Time on hold for this year. It will also make the reopening of +# scheduled commercial air service much smoother if we don't have to be +# concerned shifting arrival and departure times, which may look like a simple +# thing but requires some significant logistical adjustments domestically and +# internationally." +# Assume for now that DST will resume with the recent pre-2020 rules for the +# 2022/2023 season. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 - @@ -422,10 +435,11 @@ Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 - Rule Fiji 2014 only - Jan Sun>=18 2:00 0 - Rule Fiji 2014 2018 - Nov Sun>=1 2:00 1:00 - -Rule Fiji 2015 max - Jan Sun>=12 3:00 0 - +Rule Fiji 2015 2021 - Jan Sun>=12 3:00 0 - Rule Fiji 2019 only - Nov Sun>=8 2:00 1:00 - Rule Fiji 2020 only - Dec 20 2:00 1:00 - -Rule Fiji 2021 max - Nov Sun>=8 2:00 1:00 - +Rule Fiji 2022 max - Nov Sun>=8 2:00 1:00 - +Rule Fiji 2023 max - Jan Sun>=12 3:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva 12:00 Fiji +12/+13 @@ -487,7 +501,7 @@ # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Tarawa 11:32:04 - LMT 1901 # Bairiki 12:00 - +12 -Zone Pacific/Enderbury -11:24:20 - LMT 1901 +Zone Pacific/Kanton 0 - -00 1937 Aug 31 -12:00 - -12 1979 Oct -11:00 - -11 1994 Dec 31 13:00 - +13 @@ -620,13 +634,46 @@ # was probably like Pacific/Auckland # Cook Is -# From Shanks & Pottenger: +# +# From Alexander Krivenyshev (2021-03-24): +# In 1899 the Cook Islands celebrated Christmas twice to correct the calendar. +# According to the old books, missionaries were unaware of +# the International Date line, when they came from Sydney. +# Thus the Cook Islands were one day ahead.... +# http://nzetc.victoria.ac.nz/tm/scholarly/tei-KloDisc-t1-body-d18.html +# ... Appendix to the Journals of the House of Representatives, 1900 +# https://atojs.natlib.govt.nz/cgi-bin/atojs?a=d&d=AJHR1900-I.2.1.2.3 +# (page 20) +# +# From Michael Deckers (2021-03-24): +# ... in the Cook Island Act of 1915-10-11, online at +# http://www.paclii.org/ck/legis/ck-nz_act/cia1915132/ +# "651. The hour of the day shall in each of the islands included in the +# Cook Islands be determined in accordance with the meridian of that island." +# so that local (mean?) time was still used in Rarotonga (and Niue) in 1915. +# This was changed in the Cook Island Amendment Act of 1952-10-16 ... +# http://www.paclii.org/ck/legis/ck-nz_act/ciaa1952212/ +# "651 (1) The hour of the day in each of the islands included in the Cook +# Islands, other than Niue, shall be determined as if each island were +# situated on the meridian one hundred and fifty-seven degrees thirty minutes +# West of Greenwich. (2) The hour of the day in the Island of Niue shall be +# determined as if that island were situated on the meridian one hundred and +# seventy degrees West of Greenwich." +# This act does not state when it takes effect, so one has to assume it +# applies since 1952-10-16. But there is the possibility that the act just +# legalized prior existing practice, as we had seen with the Guernsey law of +# 1913-06-18 for the switch in 1909-04-19. +# +# From Paul Eggert (2021-03-24): +# Transitions after 1952 are from Shanks & Pottenger. +# # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Cook 1978 only - Nov 12 0:00 0:30 - Rule Cook 1979 1991 - Mar Sun>=1 0:00 0 - Rule Cook 1979 1990 - Oct lastSun 0:00 0:30 - # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Pacific/Rarotonga -10:39:04 - LMT 1901 # Avarua +Zone Pacific/Rarotonga 13:20:56 - LMT 1899 Dec 26 # Avarua + -10:39:04 - LMT 1952 Oct 16 -10:30 - -1030 1978 Nov 12 -10:00 Cook -10/-0930 @@ -634,10 +681,18 @@ # Niue +# See Pacific/Raratonga comments for 1952 transition. +# +# From Tim Parenti (2021-09-13): +# Consecutive contemporaneous editions of The Air Almanac listed -11:20 for +# Niue as of Apr 1964 but -11 as of Aug 1964: +# Apr 1964: https://books.google.com/books?id=_1So677Y5vUC&pg=SL1-PA23 +# Aug 1964: https://books.google.com/books?id=MbJloqd-zyUC&pg=SL1-PA23 +# Without greater specificity, guess 1964-07-01 for this transition. + # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Pacific/Niue -11:19:40 - LMT 1901 # Alofi - -11:20 - -1120 1951 - -11:30 - -1130 1978 Oct 1 +Zone Pacific/Niue -11:19:40 - LMT 1952 Oct 16 # Alofi + -11:20 - -1120 1964 Jul -11:00 - -11 # Norfolk @@ -661,6 +716,7 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 9:48:32 - PMMT 1895 # Port Moresby Mean Time 10:00 - +10 +Link Pacific/Port_Moresby Antarctica/DumontDUrville # # From Paul Eggert (2014-10-13): # Base the Bougainville entry on the Arawa-Kieta region, which appears to have @@ -765,13 +821,17 @@ # From Paul Eggert (2014-07-08): # That web page currently lists transitions for 2012/3 and 2013/4. # Assume the pattern instituted in 2012 will continue indefinitely. +# +# From Geoffrey D. Bennett (2021-09-20): +# https://www.mcil.gov.ws/storage/2021/09/MCIL-Scan_20210920_120553.pdf +# DST has been cancelled for this year. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule WS 2010 only - Sep lastSun 0:00 1 - Rule WS 2011 only - Apr Sat>=1 4:00 0 - Rule WS 2011 only - Sep lastSat 3:00 1 - -Rule WS 2012 max - Apr Sun>=1 4:00 0 - -Rule WS 2012 max - Sep lastSun 3:00 1 - +Rule WS 2012 2021 - Apr Sun>=1 4:00 0 - +Rule WS 2012 2020 - Sep lastSun 3:00 1 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Apia 12:33:04 - LMT 1892 Jul 5 -11:26:56 - LMT 1911 @@ -818,8 +878,8 @@ Rule Tonga 2016 only - Nov Sun>=1 2:00 1:00 - Rule Tonga 2017 only - Jan Sun>=15 3:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Pacific/Tongatapu 12:19:20 - LMT 1901 - 12:20 - +1220 1941 +Zone Pacific/Tongatapu 12:19:12 - LMT 1945 Sep 10 + 12:20 - +1220 1961 13:00 - +13 1999 13:00 Tonga +13/+14 @@ -1761,6 +1821,23 @@ # One source for this is page 202 of: Bartky IR. One Time Fits All: # The Campaigns for Global Uniformity (2007). +# Kanton + +# From Paul Eggert (2021-05-27): +# Kiribati's +13 timezone is represented by Kanton, its only populated +# island. (It was formerly spelled "Canton", but Gilbertese lacks "C".) +# Kanton was settled on 1937-08-31 by two British radio operators +# <https://history.state.gov/historicaldocuments/frus1937v02/d94>; +# Americans came the next year and built an airfield, partly to +# establish airline service and perhaps partly anticipating the +# next war. Aside from the war, the airfield was used by commercial +# airlines until long-range jets became standard; although currently +# for emergency use only, China says it is considering rebuilding the +# airfield for high-end niche tourism. Kanton has about two dozen +# people, caretakers who rotate in from the rest of Kiribati in 2-5 +# year shifts, and who use some of the leftover structures +# <http://pipa.neaq.org/2012/06/images-of-kanton-island.html>. + # Kwajalein # From an AP article (1993-08-22): @@ -2044,6 +2121,17 @@ # Tonga +# From Paul Eggert (2021-03-04): +# In 1943 "The standard time kept is 12 hrs. 19 min. 12 sec. fast +# on Greenwich mean time." according to the Admiralty's Hydrographic +# Dept., Pacific Islands Pilot, Vol. II, 7th ed., 1943, p 360. + +# From Michael Deckers (2021-03-03): +# [Ian R Bartky: "One Time Fits All: The Campaigns for Global Uniformity". +# Stanford University Press. 2007. p. 255]: +# On 10 September 1945 Tonga adopted a standard time 12 hours, +# 20 minutes in advance of Greenwich. + # From Paul Eggert (1996-01-22): # Today's _Wall Street Journal_ (p 1) reports that "Tonga has been plotting # to sneak ahead of [New Zealanders] by introducing daylight-saving time." @@ -2072,9 +2160,26 @@ # The Crown Prince, presented an unanswerable argument: "Remember that # on the World Day of Prayer, you would be the first people on Earth # to say your prayers in the morning." - -# From Paul Eggert (2006-03-22): -# Shanks & Pottenger say the transition was on 1968-10-01; go with Mundell. +# +# From Tim Parenti (2021-09-13), per Paul Eggert (2006-03-22) and Michael +# Deckers (2021-03-03): +# Mundell places the transition from +12:20 to +13 in 1941, while Shanks & +# Pottenger say the transition was on 1968-10-01. +# +# The Air Almanac published contemporaneous tables of standard times, +# which listed +12:20 as of Nov 1960 and +13 as of Mar 1961: +# Nov 1960: https://books.google.com/books?id=bVgtWM6kPZUC&pg=SL1-PA19 +# Mar 1961: https://books.google.com/books?id=W2nItAul4g0C&pg=SL1-PA19 +# (Thanks to P Chan for pointing us toward these sources.) +# This agrees with Bartky, who writes that "since 1961 [Tonga's] official time +# has been thirteen hours in advance of Greenwich time" (p. 202) and further +# writes in an endnote that this was because "the legislation was amended" on +# 1960-10-19. (p. 255) +# +# Without greater specificity, presume that Bartky and the Air Almanac point to +# a 1961-01-01 transition, as Tāufaʻāhau Tupou IV was still Crown Prince in +# 1961 and this still jives with the gist of Mundell's telling, and go with +# this over Shanks & Pottenger. # From Eric Ulevik (1999-05-03): # Tonga's director of tourism, who is also secretary of the National Millennium
diff --git a/make/data/tzdata/backward b/make/data/tzdata/backward index 48482b7..59c1256 100644 --- a/make/data/tzdata/backward +++ b/make/data/tzdata/backward
@@ -26,8 +26,10 @@ # This file is in the public domain, so clarified as of # 2009-05-17 by Arthur David Olson. -# This file provides links between current names for timezones -# and their old names. Many names changed in late 1993. +# This file provides links from old or merged timezone names to current ones. +# Many names changed in late 1993. Several of these names are +# also present in the file 'backzone', which has data important only +# for pre-1970 timestamps and so is out of scope for tzdb proper. # Link TARGET LINK-NAME Link Africa/Nairobi Africa/Asmera @@ -36,7 +38,7 @@ Link America/Adak America/Atka Link America/Argentina/Buenos_Aires America/Buenos_Aires Link America/Argentina/Catamarca America/Catamarca -Link America/Atikokan America/Coral_Harbour +Link America/Panama America/Coral_Harbour Link America/Argentina/Cordoba America/Cordoba Link America/Tijuana America/Ensenada Link America/Indiana/Indianapolis America/Fort_Wayne @@ -51,7 +53,7 @@ Link America/Argentina/Cordoba America/Rosario Link America/Tijuana America/Santa_Isabel Link America/Denver America/Shiprock -Link America/Port_of_Spain America/Virgin +Link America/Puerto_Rico America/Virgin Link Pacific/Auckland Antarctica/South_Pole Link Asia/Ashgabat Asia/Ashkhabad Link Asia/Kolkata Asia/Calcutta @@ -126,6 +128,7 @@ Link Pacific/Chatham NZ-CHAT Link America/Denver Navajo Link Asia/Shanghai PRC +Link Pacific/Kanton Pacific/Enderbury Link Pacific/Honolulu Pacific/Johnston Link Pacific/Pohnpei Pacific/Ponape Link Pacific/Pago_Pago Pacific/Samoa
diff --git a/make/data/tzdata/europe b/make/data/tzdata/europe index eb9056e..9b0b64a 100644 --- a/make/data/tzdata/europe +++ b/make/data/tzdata/europe
@@ -91,7 +91,6 @@ # 0:00 GMT BST BDST Greenwich, British Summer # 0:00 GMT IST Greenwich, Irish Summer # 0:00 WET WEST WEMT Western Europe -# 0:19:32.13 AMT* NST* Amsterdam, Netherlands Summer (1835-1937) # 1:00 BST British Standard (1968-1971) # 1:00 IST GMT Irish Standard (1968-) with winter DST # 1:00 CET CEST CEMT Central Europe @@ -845,7 +844,7 @@ # Shanks & Pottenger give 02:00, the BEV 00:00. Go with the BEV, # and guess 02:00 for 1945-04-12. -# From Alois Triendl (2019-07-22): +# From Alois Treindl (2019-07-22): # In 1946 the end of DST was on Monday, 7 October 1946, at 3:00 am. # Shanks had this right. Source: Die Weltpresse, 5. Oktober 1946, page 5. @@ -1759,19 +1758,22 @@ # advanced to sixty minutes later starting at hour two on 1944-04-02; ... # Starting at hour three on the date 1944-09-17 standard time will be resumed. # -# From Alois Triendl (2019-07-02): +# From Alois Treindl (2019-07-02): # I spent 6 Euros to buy two archive copies of Il Messaggero, a Roman paper, # for 1 and 2 April 1944. The edition of 2 April has this note: "Tonight at 2 # am, put forward the clock by one hour. Remember that in the night between # today and Monday the 'ora legale' will come in force again." That makes it # clear that in Rome the change was on Monday, 3 April 1944 at 2 am. # -# From Paul Eggert (2016-10-27): +# From Paul Eggert (2021-10-05): # Go with INRiM for DST rules, except as corrected by Inglis for 1944 # for the Kingdom of Italy. This is consistent with Renzo Baldini. # Model Rome's occupation by using C-Eur rules from 1943-09-10 # to 1944-06-04; although Rome was an open city during this period, it -# was effectively controlled by Germany. +# was effectively controlled by Germany. Using C-Eur is consistent +# with Treindl's comment about Rome in April 1944, as the "Rule Italy" +# lines during German occupation do not affect Europe/Rome +# (though they do affect Europe/Malta). # # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Italy 1916 only - Jun 3 24:00 1:00 S @@ -1823,6 +1825,10 @@ 1:00 Italy CE%sT 1980 1:00 EU CE%sT +# Kosovo +# See Europe/Belgrade. + + Link Europe/Rome Europe/Vatican Link Europe/Rome Europe/San_Marino @@ -2173,6 +2179,10 @@ # The data entries before 1945 are taken from # https://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm +# From Paul Eggert (2021-05-09): +# I invented the abbreviations AMT for Amsterdam Mean Time and NST for +# Netherlands Summer Time, used in the Netherlands from 1835 to 1937. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time Rule Neth 1916 only - Oct 1 0:00 0 AMT # Amsterdam Mean Time @@ -2399,12 +2409,10 @@ Rule Port 1944 1945 - Apr Sat>=21 22:00s 2:00 M Rule Port 1946 only - Apr Sat>=1 23:00s 1:00 S Rule Port 1946 only - Oct Sat>=1 23:00s 0 - -Rule Port 1947 1949 - Apr Sun>=1 2:00s 1:00 S -Rule Port 1947 1949 - Oct Sun>=1 2:00s 0 - -# Shanks & Pottenger say DST was observed in 1950; go with Whitman. +# Whitman says DST was not observed in 1950; go with Shanks & Pottenger. # Whitman gives Oct lastSun for 1952 on; go with Shanks & Pottenger. -Rule Port 1951 1965 - Apr Sun>=1 2:00s 1:00 S -Rule Port 1951 1965 - Oct Sun>=1 2:00s 0 - +Rule Port 1947 1965 - Apr Sun>=1 2:00s 1:00 S +Rule Port 1947 1965 - Oct Sun>=1 2:00s 0 - Rule Port 1977 only - Mar 27 0:00s 1:00 S Rule Port 1977 only - Sep 25 0:00s 0 - Rule Port 1978 1979 - Apr Sun>=1 0:00s 1:00 S @@ -2641,7 +2649,7 @@ # Although Shanks lists 1945-01-01 as the date for transition from # +01/+02 to +02/+03, more likely this is a placeholder. Guess that # the transition occurred at 1945-04-10 00:00, which is about when -# Königsberg surrendered to Soviet troops. (Thanks to Alois Triendl.) +# Königsberg surrendered to Soviet troops. (Thanks to Alois Treindl.) # From Paul Eggert (2016-03-18): # The 1989 transition is from USSR act No. 227 (1989-03-14). @@ -3706,6 +3714,9 @@ # # Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left. +# An extra-special abbreviation style is SET for Swedish Time (svensk +# normaltid) 1879-1899, 3° west of the Stockholm Observatory. + # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Europe/Stockholm 1:12:12 - LMT 1879 Jan 1 1:00:14 - SET 1900 Jan 1 # Swedish Time
diff --git a/make/data/tzdata/leapseconds b/make/data/tzdata/leapseconds index 6f19416..cc51456 100644 --- a/make/data/tzdata/leapseconds +++ b/make/data/tzdata/leapseconds
@@ -95,11 +95,11 @@ # Any additional leap seconds will come after this. # This Expires line is commented out for now, # so that pre-2020a zic implementations do not reject this file. -#Expires 2021 Dec 28 00:00:00 +#Expires 2022 Jun 28 00:00:00 # POSIX timestamps for the data in this file: #updated 1467936000 (2016-07-08 00:00:00 UTC) -#expires 1640649600 (2021-12-28 00:00:00 UTC) +#expires 1656374400 (2022-06-28 00:00:00 UTC) -# Updated through IERS Bulletin C61 -# File expires on: 28 December 2021 +# Updated through IERS Bulletin C62 +# File expires on: 28 June 2022
diff --git a/make/data/tzdata/northamerica b/make/data/tzdata/northamerica index 610c606..4110997 100644 --- a/make/data/tzdata/northamerica +++ b/make/data/tzdata/northamerica
@@ -752,7 +752,11 @@ -11:00 US B%sT 1983 Oct 30 2:00 -10:00 US AH%sT 1983 Nov 30 -10:00 US H%sT -# The following switches don't quite make our 1970 cutoff. +# The following switches don't make our 1970 cutoff. +# +# Kiska observed Tokyo date and time during Japanese occupation from +# 1942-06-06 to 1943-07-29, and similarly for Attu from 1942-06-07 to +# 1943-05-29 (all dates American). Both islands are now uninhabited. # # Shanks writes that part of southwest Alaska (e.g. Aniak) # switched from -11:00 to -10:00 on 1968-09-22 at 02:00, @@ -848,6 +852,8 @@ -7:00 - MST 1967 -7:00 US M%sT 1968 Mar 21 -7:00 - MST +Link America/Phoenix America/Creston + # From Arthur David Olson (1988-02-13): # A writer from the Inter Tribal Council of Arizona, Inc., # notes in private correspondence dated 1987-12-28 that "Presently, only the @@ -993,7 +999,7 @@ -5:00 US E%sT # # Perry County, Indiana, switched from eastern to central time in April 2006. -# From Alois Triendl (2019-07-09): +# From Alois Treindl (2019-07-09): # The Indianapolis News, Friday 27 October 1967 states that Perry County # returned to CST. It went again to EST on 27 April 1969, as documented by the # Indianapolis star of Saturday 26 April. @@ -1616,24 +1622,7 @@ # From Paul Eggert (2020-01-10): # See America/Toronto for most of Quebec, including Montreal. # See America/Halifax for the Îles de la Madeleine and the Listuguj reserve. -# -# Matthews and Vincent (1998) also write that Quebec east of the -63 -# meridian is supposed to observe AST, but residents as far east as -# Natashquan use EST/EDT, and residents east of Natashquan use AST. -# The Quebec department of justice writes in -# "The situation in Minganie and Basse-Côte-Nord" -# https://www.justice.gouv.qc.ca/en/department/ministre/functions-and-responsabilities/legal-time-in-quebec/the-situation-in-minganie-and-basse-cote-nord/ -# that the coastal strip from just east of Natashquan to Blanc-Sablon -# observes Atlantic standard time all year round. -# This common practice was codified into law as of 2007; see Legal Time Act, -# CQLR c T-5.1 <http://legisquebec.gouv.qc.ca/en/ShowDoc/cs/T-5.1>. -# For lack of better info, guess this practice began around 1970, contra to -# Shanks & Pottenger who have this region observing AST/ADT. - -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Blanc-Sablon -3:48:28 - LMT 1884 - -4:00 Canada A%sT 1970 - -4:00 - AST +# See America/Puerto_Rico for east of Natashquan. # Ontario @@ -1672,54 +1661,6 @@ # time became a comic failure in Orillia. Toronto Star 2017-07-08. # https://www.thestar.com/news/insight/2017/07/08/bold-attempt-at-daylight-saving-time-became-a-comic-failure-in-orillia.html -# From Paul Eggert (1997-10-17): -# Mark Brader writes that an article in the 1997-10-14 Toronto Star -# says that Atikokan, Ontario currently does not observe DST, -# but will vote on 11-10 whether to use EST/EDT. -# He also writes that the Ontario Time Act (1990, Chapter T.9) -# http://www.gov.on.ca/MBS/english/publications/statregs/conttext.html -# says that Ontario east of 90W uses EST/EDT, and west of 90W uses CST/CDT. -# Officially Atikokan is therefore on CST/CDT, and most likely this report -# concerns a non-official time observed as a matter of local practice. -# -# From Paul Eggert (2000-10-02): -# Matthews and Vincent (1998) write that Atikokan, Pickle Lake, and -# New Osnaburgh observe CST all year, that Big Trout Lake observes -# CST/CDT, and that Upsala and Shebandowan observe EST/EDT, all in -# violation of the official Ontario rules. -# -# From Paul Eggert (2006-07-09): -# Chris Walton (2006-07-06) mentioned an article by Stephanie MacLellan in the -# 2005-07-21 Chronicle-Journal, which said: -# -# The clocks in Atikokan stay set on standard time year-round. -# This means they spend about half the time on central time and -# the other half on eastern time. -# -# For the most part, the system works, Mayor Dennis Brown said. -# -# "The majority of businesses in Atikokan deal more with Eastern -# Canada, but there are some that deal with Western Canada," he -# said. "I don't see any changes happening here." -# -# Walton also writes "Supposedly Pickle Lake and Mishkeegogamang -# [New Osnaburgh] follow the same practice." - -# From Garry McKinnon (2006-07-14) via Chris Walton: -# I chatted with a member of my board who has an outstanding memory -# and a long history in Atikokan (and in the telecom industry) and he -# can say for certain that Atikokan has been practicing the current -# time keeping since 1952, at least. - -# From Paul Eggert (2006-07-17): -# Shanks & Pottenger say that Atikokan has agreed with Rainy River -# ever since standard time was introduced, but the information from -# McKinnon sounds more authoritative. For now, assume that Atikokan -# switched to EST immediately after WWII era daylight saving time -# ended. This matches the old (less-populous) America/Coral_Harbour -# entry since our cutoff date of 1970, so we can move -# America/Coral_Harbour to the 'backward' file. - # From Mark Brader (2010-03-06): # # Currently the database has: @@ -1850,6 +1791,7 @@ -5:00 Canada E%sT 1946 -5:00 Toronto E%sT 1974 -5:00 Canada E%sT +Link America/Toronto America/Nassau Zone America/Thunder_Bay -5:57:00 - LMT 1895 -6:00 - CST 1910 -5:00 - EST 1942 @@ -1865,11 +1807,7 @@ -6:00 Canada C%sT 1940 Sep 29 -6:00 1:00 CDT 1942 Feb 9 2:00s -6:00 Canada C%sT -Zone America/Atikokan -6:06:28 - LMT 1895 - -6:00 Canada C%sT 1940 Sep 29 - -6:00 1:00 CDT 1942 Feb 9 2:00s - -6:00 Canada C%sT 1945 Sep 30 2:00 - -5:00 - EST +# For Atikokan see America/Panama. # Manitoba @@ -2021,7 +1959,7 @@ # Alberta -# From Alois Triendl (2019-07-19): +# From Alois Treindl (2019-07-19): # There was no DST in Alberta in 1967... Calgary Herald, 29 April 1967. # 1969, no DST, from Edmonton Journal 18 April 1969 # @@ -2060,60 +1998,6 @@ # Shanks & Pottenger write that since 1970 most of this region has # been like Vancouver. # Dawson Creek uses MST. Much of east BC is like Edmonton. -# Matthews and Vincent (1998) write that Creston is like Dawson Creek. - -# It seems though that (re: Creston) is not entirely correct: - -# From Chris Walton (2011-12-01): -# There are two areas within the Canadian province of British Columbia -# that do not currently observe daylight saving: -# a) The Creston Valley (includes the town of Creston and surrounding area) -# b) The eastern half of the Peace River Regional District -# (includes the cities of Dawson Creek and Fort St. John) - -# Earlier this year I stumbled across a detailed article about the time -# keeping history of Creston; it was written by Tammy Hardwick who is the -# manager of the Creston & District Museum. The article was written in May 2009. -# http://www.ilovecreston.com/?p=articles&t=spec&ar=260 -# According to the article, Creston has not changed its clocks since June 1918. -# i.e. Creston has been stuck on UT-7 for 93 years. -# Dawson Creek, on the other hand, changed its clocks as recently as April 1972. - -# Unfortunately the exact date for the time change in June 1918 remains -# unknown and will be difficult to ascertain. I e-mailed Tammy a few months -# ago to ask if Sunday June 2 was a reasonable guess. She said it was just -# as plausible as any other date (in June). She also said that after writing -# the article she had discovered another time change in 1916; this is the -# subject of another article which she wrote in October 2010. -# http://www.creston.museum.bc.ca/index.php?module=comments&uop=view_comment&cm+id=56 - -# Here is a summary of the three clock change events in Creston's history: -# 1. 1884 or 1885: adoption of Mountain Standard Time (GMT-7) -# Exact date unknown -# 2. Oct 1916: switch to Pacific Standard Time (GMT-8) -# Exact date in October unknown; Sunday October 1 is a reasonable guess. -# 3. June 1918: switch to Pacific Daylight Time (GMT-7) -# Exact date in June unknown; Sunday June 2 is a reasonable guess. -# note 1: -# On Oct 27/1918 when daylight saving ended in the rest of Canada, -# Creston did not change its clocks. -# note 2: -# During WWII when the Federal Government legislated a mandatory clock change, -# Creston did not oblige. -# note 3: -# There is no guarantee that Creston will remain on Mountain Standard Time -# (UTC-7) forever. -# The subject was debated at least once this year by the town Council. -# http://www.bclocalnews.com/kootenay_rockies/crestonvalleyadvance/news/116760809.html - -# During a period WWII, summer time (Daylight saying) was mandatory in Canada. -# In Creston, that was handled by shifting the area to PST (-8:00) then applying -# summer time to cause the offset to be -7:00, the same as it had been before -# the change. It can be argued that the timezone abbreviation during this -# period should be PDT rather than MST, but that doesn't seem important enough -# (to anyone) to further complicate the rules. - -# The transition dates (and times) are guesses. # From Matt Johnson (2015-09-21): # Fort Nelson, BC, Canada will cancel DST this year. So while previously they @@ -2130,7 +2014,7 @@ # # From Paul Eggert (2019-07-25): # Shanks says Fort Nelson did not observe DST in 1946, unlike Vancouver. -# Alois Triendl confirmed this on 07-22, citing the 1946-04-27 Vancouver Daily +# Alois Treindl confirmed this on 07-22, citing the 1946-04-27 Vancouver Daily # Province. He also cited the 1946-09-28 Victoria Daily Times, which said # that Vancouver, Victoria, etc. "change at midnight Saturday"; for now, # guess they meant 02:00 Sunday since 02:00 was common practice in Vancouver. @@ -2167,10 +2051,7 @@ -8:00 Vanc P%sT 1987 -8:00 Canada P%sT 2015 Mar 8 2:00 -7:00 - MST -Zone America/Creston -7:46:04 - LMT 1884 - -7:00 - MST 1916 Oct 1 - -8:00 - PST 1918 Jun 2 - -7:00 - MST +# For Creston see America/Phoenix. # Northwest Territories, Nunavut, Yukon @@ -2952,64 +2833,61 @@ # Anguilla # Antigua and Barbuda -# See America/Port_of_Spain. +# See America/Puerto_Rico. -# Bahamas -# -# For 1899 Milne gives -5:09:29.5; round that. -# -# From P Chan (2020-11-27, corrected on 2020-12-02): -# There were two periods of DST observed in 1942-1945: 1942-05-01 -# midnight to 1944-12-31 midnight and 1945-02-01 to 1945-10-17 midnight. -# "midnight" should mean 24:00 from the context. -# -# War Time Order 1942 [1942-05-01] and War Time (No. 2) Order 1942 [1942-09-29] -# Appendix to the Statutes of 7 George VI. and the Year 1942. p 34, 43 -# https://books.google.com/books?id=5rlNAQAAIAAJ&pg=RA3-PA34 -# https://books.google.com/books?id=5rlNAQAAIAAJ&pg=RA3-PA43 -# -# War Time Order 1943 [1943-03-31] and War Time Order 1944 [1943-12-29] -# Appendix to the Statutes of 8 George VI. and the Year 1943. p 9-10, 28-29 -# https://books.google.com/books?id=5rlNAQAAIAAJ&pg=RA4-PA9 -# https://books.google.com/books?id=5rlNAQAAIAAJ&pg=RA4-PA28 -# -# War Time Order 1945 [1945-01-31] and the Order which revoke War Time Order -# 1945 [1945-10-16] Appendix to the Statutes of 9 George VI. and the Year -# 1945. p 160, 247-248 -# https://books.google.com/books?id=5rlNAQAAIAAJ&pg=RA6-PA160 -# https://books.google.com/books?id=5rlNAQAAIAAJ&pg=RA6-PA247 -# -# From Sue Williams (2006-12-07): -# The Bahamas announced about a month ago that they plan to change their DST -# rules to sync with the U.S. starting in 2007.... -# http://www.jonesbahamas.com/?c=45&a=10412 +# The Bahamas +# See America/Toronto. -# Rule NAME FROM TO - IN ON AT SAVE LETTER/S -Rule Bahamas 1942 only - May 1 24:00 1:00 W -Rule Bahamas 1944 only - Dec 31 24:00 0 S -Rule Bahamas 1945 only - Feb 1 0:00 1:00 W -Rule Bahamas 1945 only - Aug 14 23:00u 1:00 P # Peace -Rule Bahamas 1945 only - Oct 17 24:00 0 S -Rule Bahamas 1964 1975 - Oct lastSun 2:00 0 S -Rule Bahamas 1964 1975 - Apr lastSun 2:00 1:00 D -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Nassau -5:09:30 - LMT 1912 Mar 2 - -5:00 Bahamas E%sT 1976 - -5:00 US E%sT # Barbados # For 1899 Milne gives -3:58:29.2; round that. +# From P Chan (2020-12-09 and 2020-12-11): +# Standard time of GMT-4 was adopted in 1911. +# Definition of Time Act, 1911 (1911-7) [1911-08-28] +# 1912, Laws of Barbados (5 v.), OCLC Number: 919801291, Vol. 4, Image No. 522 +# 1944, Laws of Barbados (5 v.), OCLC Number: 84548697, Vol. 4, Image No. 122 +# http://llmc.com/browse.aspx?type=2&coll=85&div=297 +# +# DST was observed in 1942-44. +# Defence (Daylight Saving) Regulations, 1942, 1942-04-13 +# Defence (Daylight Saving) (Repeal) Regulations, 1942, 1942-08-22 +# Defence (Daylight Saving) Regulations, 1943, 1943-04-16 +# Defence (Daylight Saving) (Repeal) Regulations, 1943, 1943-09-01 +# Defence (Daylight Saving) Regulations, 1944, 1944-03-21 +# [Defence (Daylight Saving) (Amendment) Regulations 1944, 1944-03-28] +# Defence (Daylight Saving) (Repeal) Regulations, 1944, 1944-08-30 +# +# 1914-, Subsidiary Legis., Annual Vols. OCLC Number: 226290591 +# 1942: Image Nos. 527-528, 555-556 +# 1943: Image Nos. 178-179, 198 +# 1944: Image Nos. 113-115, 129 +# http://llmc.com/titledescfull.aspx?type=2&coll=85&div=297&set=98437 +# +# From Tim Parenti (2021-02-20): +# The transitions below are derived from P Chan's sources, except that the 1977 +# through 1980 transitions are from Shanks & Pottenger since we have no better +# data there. Of particular note, the 1944 DST regulation only advanced the +# time to "exactly three and a half hours later than Greenwich mean time", as +# opposed to "three hours" in the 1942 and 1943 regulations. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S +Rule Barb 1942 only - Apr 19 5:00u 1:00 D +Rule Barb 1942 only - Aug 31 6:00u 0 S +Rule Barb 1943 only - May 2 5:00u 1:00 D +Rule Barb 1943 only - Sep 5 6:00u 0 S +Rule Barb 1944 only - Apr 10 5:00u 0:30 - +Rule Barb 1944 only - Sep 10 6:00u 0 S Rule Barb 1977 only - Jun 12 2:00 1:00 D Rule Barb 1977 1978 - Oct Sun>=1 2:00 0 S Rule Barb 1978 1980 - Apr Sun>=15 2:00 1:00 D Rule Barb 1979 only - Sep 30 2:00 0 S Rule Barb 1980 only - Sep 25 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Barbados -3:58:29 - LMT 1924 # Bridgetown - -3:58:29 - BMT 1932 # Bridgetown Mean Time +Zone America/Barbados -3:58:29 - LMT 1911 Aug 28 # Bridgetown + -4:00 Barb A%sT 1944 + -4:00 Barb AST/-0330 1945 -4:00 Barb A%sT # Belize @@ -3171,6 +3049,9 @@ -4:00 Canada A%sT 1976 -4:00 US A%sT +# Caribbean Netherlands +# See America/Puerto_Rico. + # Cayman Is # See America/Panama. @@ -3399,7 +3280,7 @@ -5:00 Cuba C%sT # Dominica -# See America/Port_of_Spain. +# See America/Puerto_Rico. # Dominican Republic @@ -3451,7 +3332,7 @@ # Guadeloupe # St Barthélemy # St Martin (French part) -# See America/Port_of_Spain. +# See America/Puerto_Rico. # Guatemala # @@ -3638,7 +3519,7 @@ -4:00 - AST # Montserrat -# See America/Port_of_Spain. +# See America/Puerto_Rico. # Nicaragua # @@ -3710,6 +3591,7 @@ Zone America/Panama -5:18:08 - LMT 1890 -5:19:36 - CMT 1908 Apr 22 # Colón Mean Time -5:00 - EST +Link America/Panama America/Atikokan Link America/Panama America/Cayman # Puerto Rico @@ -3719,10 +3601,29 @@ -4:00 - AST 1942 May 3 -4:00 US A%sT 1946 -4:00 - AST +Link America/Puerto_Rico America/Anguilla +Link America/Puerto_Rico America/Antigua +Link America/Puerto_Rico America/Aruba +Link America/Puerto_Rico America/Curacao +Link America/Puerto_Rico America/Blanc-Sablon # Quebec (Lower North Shore) +Link America/Puerto_Rico America/Dominica +Link America/Puerto_Rico America/Grenada +Link America/Puerto_Rico America/Guadeloupe +Link America/Puerto_Rico America/Kralendijk # Caribbean Netherlands +Link America/Puerto_Rico America/Lower_Princes # Sint Maarten +Link America/Puerto_Rico America/Marigot # St Martin (French part) +Link America/Puerto_Rico America/Montserrat +Link America/Puerto_Rico America/Port_of_Spain # Trinidad & Tobago +Link America/Puerto_Rico America/St_Barthelemy # St Barthélemy +Link America/Puerto_Rico America/St_Kitts # St Kitts & Nevis +Link America/Puerto_Rico America/St_Lucia +Link America/Puerto_Rico America/St_Thomas # Virgin Islands (US) +Link America/Puerto_Rico America/St_Vincent +Link America/Puerto_Rico America/Tortola # Virgin Islands (UK) # St Kitts-Nevis # St Lucia -# See America/Port_of_Spain. +# See America/Puerto_Rico. # St Pierre and Miquelon # There are too many St Pierres elsewhere, so we'll use 'Miquelon'. @@ -3733,7 +3634,10 @@ -3:00 Canada -03/-02 # St Vincent and the Grenadines -# See America/Port_of_Spain. +# See America/Puerto_Rico. + +# Sint Maarten +# See America/Puerto_Rico. # Turks and Caicos # @@ -3804,8 +3708,8 @@ -5:00 US E%sT # British Virgin Is -# Virgin Is -# See America/Port_of_Spain. +# US Virgin Is +# See America/Puerto_Rico. # Local Variables:
diff --git a/make/data/tzdata/southamerica b/make/data/tzdata/southamerica index 566dabf..503ed65 100644 --- a/make/data/tzdata/southamerica +++ b/make/data/tzdata/southamerica
@@ -597,7 +597,7 @@ -3:00 - -03 # Aruba -Link America/Curacao America/Aruba +# See America/Puerto_Rico. # Bolivia # Zone NAME STDOFF RULES FORMAT [UNTIL] @@ -1392,35 +1392,14 @@ # no information; probably like America/Bogota # Curaçao - -# Milne gives 4:35:46.9 for Curaçao mean time; round to nearest. +# See America/Puerto_Rico. # -# From Paul Eggert (2006-03-22): -# Shanks & Pottenger say that The Bottom and Philipsburg have been at -# -4:00 since standard time was introduced on 1912-03-02; and that -# Kralendijk and Rincon used Kralendijk Mean Time (-4:33:08) from -# 1912-02-02 to 1965-01-01. The former is dubious, since S&P also say -# Saba Island has been like Curaçao. -# This all predates our 1970 cutoff, though. -# -# By July 2007 Curaçao and St Maarten are planned to become -# associated states within the Netherlands, much like Aruba; -# Bonaire, Saba and St Eustatius would become directly part of the -# Netherlands as Kingdom Islands. This won't affect their time zones -# though, as far as we know. -# -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Curacao -4:35:47 - LMT 1912 Feb 12 # Willemstad - -4:30 - -0430 1965 - -4:00 - AST - # From Arthur David Olson (2011-06-15): # use links for places with new iso3166 codes. # The name "Lower Prince's Quarter" is both longer than fourteen characters -# and contains an apostrophe; use "Lower_Princes" below. - -Link America/Curacao America/Lower_Princes # Sint Maarten -Link America/Curacao America/Kralendijk # Caribbean Netherlands +# and contains an apostrophe; use "Lower_Princes".... +# From Paul Eggert (2021-09-29): +# These backward-compatibility links now are in the 'northamerica' file. # Ecuador # @@ -1563,11 +1542,40 @@ -3:00 - -03 # Guyana + +# From P Chan (2020-11-27): +# https://books.google.com/books?id=5-5CAQAAMAAJ&pg=SA1-PA547 +# The Official Gazette of British Guiana. (New Series.) Vol. XL. July to +# December, 1915, p 1547, lists as several notes: +# "Local Mean Time 3 hours 52 mins. 39 secs. slow of Greenwich Mean Time +# (Georgetown.) From 1st August, 1911, British Guiana Standard Mean Time 4 +# hours slow of Greenwich Mean Time, by notice in Official Gazette on 1st July, +# 1911. From 1st March, 1915, British Guiana Standard Mean Time 3 hours 45 +# mins. 0 secs. slow of Greenwich Mean Time, by notice in Official Gazette on +# 23rd January, 1915." +# +# https://parliament.gov.gy/documents/acts/10923-act_no._27_of_1975_-_interpretation_and_general_clauses_(amendment)_act_1975.pdf +# Interpretation and general clauses (Amendment) Act 1975 (Act No. 27 of 1975) +# [dated 1975-07-31] +# "This Act...shall come into operation on 1st August, 1975." +# "...where any expression of time occurs...the time referred to shall signify +# the standard time of Guyana which shall be three hours behind Greenwich Mean +# Time." +# +# Circular No. 10/1992 dated 1992-03-20 +# https://dps.gov.gy/wp-content/uploads/2018/12/1992-03-20-Circular-010.pdf +# "...cabinet has decided that with effect from Sunday 29th March, 1992, Guyana +# Standard Time would be re-established at 01:00 hours by adjusting the hands +# of the clock back to 24:00 hours." +# Legislated in the Interpretation and general clauses (Amendment) Act 1992 +# (Act No. 6 of 1992) [passed 1992-03-27, published 1992-04-18] +# https://parliament.gov.gy/documents/acts/5885-6_of_1992_interpretation_and_general_clauses_(amendment)_act_1992.pdf + # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Guyana -3:52:40 - LMT 1915 Mar # Georgetown - -3:45 - -0345 1975 Jul 31 - -3:00 - -03 1991 -# IATA SSIM (1996-06) says -4:00. Assume a 1991 switch. +Zone America/Guyana -3:52:39 - LMT 1911 Aug 1 # Georgetown + -4:00 - -04 1915 Mar 1 + -3:45 - -0345 1975 Aug 1 + -3:00 - -03 1992 Mar 29 1:00 -4:00 - -04 # Paraguay @@ -1708,24 +1716,7 @@ -3:00 - -03 # Trinidad and Tobago -# Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Port_of_Spain -4:06:04 - LMT 1912 Mar 2 - -4:00 - AST - -# These all agree with Trinidad and Tobago since 1970. -Link America/Port_of_Spain America/Anguilla -Link America/Port_of_Spain America/Antigua -Link America/Port_of_Spain America/Dominica -Link America/Port_of_Spain America/Grenada -Link America/Port_of_Spain America/Guadeloupe -Link America/Port_of_Spain America/Marigot # St Martin (French part) -Link America/Port_of_Spain America/Montserrat -Link America/Port_of_Spain America/St_Barthelemy # St Barthélemy -Link America/Port_of_Spain America/St_Kitts # St Kitts & Nevis -Link America/Port_of_Spain America/St_Lucia -Link America/Port_of_Spain America/St_Thomas # Virgin Islands (US) -Link America/Port_of_Spain America/St_Vincent -Link America/Port_of_Spain America/Tortola # Virgin Islands (UK) +# See America/Puerto_Rico. # Uruguay # From Paul Eggert (1993-11-18):
diff --git a/make/data/tzdata/zone.tab b/make/data/tzdata/zone.tab index 28db074..0420a69 100644 --- a/make/data/tzdata/zone.tab +++ b/make/data/tzdata/zone.tab
@@ -26,7 +26,7 @@ # This file is in the public domain, so clarified as of # 2009-05-17 by Arthur David Olson. # -# From Paul Eggert (2018-06-27): +# From Paul Eggert (2021-09-20): # This file is intended as a backward-compatibility aid for older programs. # New programs should use zone1970.tab. This file is like zone1970.tab (see # zone1970.tab's comments), but with the following additional restrictions: @@ -39,6 +39,9 @@ # clocks have agreed since 1970; this is a narrower definition than # that of zone1970.tab. # +# Unlike zone1970.tab, a row's third column can be a Link from +# 'backward' instead of a Zone. +# # This table is intended as an aid for users, to help them select timezones # appropriate for their practical needs. It is not intended to take or # endorse any position on legal or territorial claims. @@ -251,7 +254,7 @@ KG +4254+07436 Asia/Bishkek KH +1133+10455 Asia/Phnom_Penh KI +0125+17300 Pacific/Tarawa Gilbert Islands -KI -0308-17105 Pacific/Enderbury Phoenix Islands +KI -0247-17143 Pacific/Kanton Phoenix Islands KI +0152-15720 Pacific/Kiritimati Line Islands KM -1141+04316 Indian/Comoro KN +1718-06243 America/St_Kitts @@ -414,7 +417,7 @@ TL -0833+12535 Asia/Dili TM +3757+05823 Asia/Ashgabat TN +3648+01011 Africa/Tunis -TO -2110-17510 Pacific/Tongatapu +TO -210800-1751200 Pacific/Tongatapu TR +4101+02858 Europe/Istanbul TT +1039-06131 America/Port_of_Spain TV -0831+17913 Pacific/Funafuti
diff --git a/make/devkit/createMacosxDevkit.sh b/make/devkit/createMacosxDevkit.sh new file mode 100644 index 0000000..2a7dfe2 --- /dev/null +++ b/make/devkit/createMacosxDevkit.sh
@@ -0,0 +1,141 @@ +#!/bin/bash +# +# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# This script copies parts of an Xcode installation into a devkit suitable +# for building OpenJDK and OracleJDK. The installation Xcode_X.X.xip needs +# to be either installed or extracted using for example Archive Utility. +# The easiest way to accomplish this is to right click the file in Finder +# and choose "Open With -> Archive Utility", or possible typing +# "open Xcode_9.2.xip" in a terminal. +# erik.joelsson@oracle.com + +USAGE="$0 <Xcode.app>" + +if [ "$1" = "" ]; then + echo $USAGE + exit 1 +fi + +XCODE_APP="$1" +XCODE_APP_DIR_NAME="${XCODE_APP##*/}" + +SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)" +BUILD_DIR="${SCRIPT_DIR}/../../build/devkit" + +# Find the version of Xcode +XCODE_VERSION="$($XCODE_APP/Contents/Developer/usr/bin/xcodebuild -version \ + | awk '/Xcode/ { print $2 }' )" +SDK_VERSION="$(ls $XCODE_APP/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs \ + | grep [0-9] | sort -r | head -n1 | sed 's/\.sdk//')" + +DEVKIT_ROOT="${BUILD_DIR}/Xcode${XCODE_VERSION}-${SDK_VERSION}" +DEVKIT_BUNDLE="${DEVKIT_ROOT}.tar.gz" + +echo "Xcode version: $XCODE_VERSION" +echo "SDK version: $SDK_VERSION" +echo "Creating devkit in $DEVKIT_ROOT" + +mkdir -p $DEVKIT_ROOT + +################################################################################ +# Copy the relevant parts of Xcode.app, removing things that are both big and +# unecessary for our purposes, without building an impossibly long exclude list. +EXCLUDE_DIRS=" \ + Contents/_CodeSignature \ + Contents/Applications \ + Contents/Resources \ + Contents/Library \ + Contents/XPCServices \ + Contents/OtherFrameworks \ + Contents/Developer/Documentation \ + Contents/Developer/usr/share \ + Contents/Developer/usr/libexec/git-core \ + Contents/Developer/usr/bin/git* \ + Contents/Developer/usr/bin/svn* \ + Contents/Developer/usr/lib/libgit* \ + Contents/Developer/usr/lib/libsvn* \ + Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/share/man \ + Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/${SDK_VERSION}.sdk/usr/share/man \ + Contents/Developer/Platforms/MacOSX.platform/Developer/usr/share/man \ + Contents/Developer/Platforms/MacOSX.platform/usr \ + Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man \ + Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift* \ + Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift* \ + Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/sourcekitd.framework \ + Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/libexec/swift* \ + Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/swift* \ + Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/arc \ + Platforms/AppleTVSimulator.platform \ + Platforms/iPhoneSimulator.platform \ + Platforms/WatchSimulator.platform \ + Contents/SharedFrameworks/LLDB.framework \ + Contents/SharedFrameworks/ModelIO.framework \ + Contents/SharedFrameworks/XCSUI.framework \ + Contents/SharedFrameworks/SceneKit.framework \ + Contents/SharedFrameworks/XCBuild.framework \ + Contents/SharedFrameworks/GPUTools*.framework \ + Contents/SharedFrameworks/DNTDocumentationSupport.framework/Versions/A/Resources/external \ + $(cd $XCODE_APP && ls -d Contents/Developer/Platforms/* \ + | grep -v MacOSX.platform | grep -v WatchSimulator.platform) \ +" + +for ex in $EXCLUDE_DIRS; do + EXCLUDE_ARGS+="--exclude=$ex " +done + +echo "Copying Xcode.app..." +echo rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP/." $DEVKIT_ROOT/Xcode.app/ +rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP/." $DEVKIT_ROOT/Xcode.app/ + +################################################################################ + +echo-info() { + echo "$1" >> $DEVKIT_ROOT/devkit.info +} + +echo "Generating devkit.info..." +rm -f $DEVKIT_ROOT/devkit.info +echo-info "# This file describes to configure how to interpret the contents of this devkit" +echo-info "DEVKIT_NAME=\"Xcode $XCODE_VERSION (devkit)\"" +echo-info "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:\$DEVKIT_ROOT/Xcode.app/Contents/Developer/usr/bin\"" +echo-info "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/$SDK_VERSION.sdk\"" +echo-info "DEVKIT_EXTRA_PATH=\"\$DEVKIT_TOOLCHAIN_PATH\"" + +################################################################################ +# Copy this script + +echo "Copying this script..." +cp $0 $DEVKIT_ROOT/ + +################################################################################ +# Create bundle + +echo "Creating bundle..." +GZIP=$(command -v pigz) +if [ -z "$GZIP" ]; then + GZIP="gzip" +fi +(cd $DEVKIT_ROOT && tar c - . | $GZIP - > "$DEVKIT_BUNDLE")
diff --git a/make/devkit/createMacosxDevkit6.sh b/make/devkit/createMacosxDevkit6.sh deleted file mode 100644 index 51637e43..0000000 --- a/make/devkit/createMacosxDevkit6.sh +++ /dev/null
@@ -1,161 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# This script copies part of an Xcode installer into a devkit suitable -# for building OpenJDK and OracleJDK. The installation .dmg files for Xcode -# and the aux tools need to be available. -# erik.joelsson@oracle.com - -USAGE="$0 <Xcode.dmg> <XQuartz.dmg> <gnu make binary> [<auxtools.dmg>]" - -if [ "$1" = "" ] || [ "$2" = "" ]; then - echo $USAGE - exit 1 -fi - -XCODE_DMG="$1" -XQUARTZ_DMG="$2" -GNU_MAKE="$3" -AUXTOOLS_DMG="$4" - -SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)" -BUILD_DIR="${SCRIPT_DIR}/../../build/devkit" - -# Mount XCODE_DMG -if [ -e "/Volumes/Xcode" ]; then - hdiutil detach /Volumes/Xcode -fi -hdiutil attach $XCODE_DMG - -# Find the version of Xcode -XCODE_VERSION="$(/Volumes/Xcode/Xcode.app/Contents/Developer/usr/bin/xcodebuild -version \ - | awk '/Xcode/ { print $2 }' )" -SDK_VERSION="MacOSX10.9" -if [ ! -e "/Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/${SDK_VERSION}.sdk" ]; then - echo "Expected SDK version not found: ${SDK_VERSION}" - exit 1 -fi - -DEVKIT_ROOT="${BUILD_DIR}/Xcode${XCODE_VERSION}-${SDK_VERSION}" -DEVKIT_BUNDLE="${DEVKIT_ROOT}.tar.gz" - -echo "Xcode version: $XCODE_VERSION" -echo "Creating devkit in $DEVKIT_ROOT" - -################################################################################ -# Copy files to root -mkdir -p $DEVKIT_ROOT -if [ ! -d $DEVKIT_ROOT/Xcode.app ]; then - echo "Copying Xcode.app..." - cp -RH "/Volumes/Xcode/Xcode.app" $DEVKIT_ROOT/ -fi -# Trim out some seemingly unneeded parts to save space. -rm -rf $DEVKIT_ROOT/Xcode.app/Contents/Applications -rm -rf $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/iPhone* -rm -rf $DEVKIT_ROOT/Xcode.app/Contents/Developer/Documentation -rm -rf $DEVKIT_ROOT/Xcode.app/Contents/Developer/usr/share/man -( cd $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs \ - && rm -rf `ls | grep -v ${SDK_VERSION}` ) -rm -rf $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/${SDK_VERSION}.sdk/usr/share/man - -hdiutil detach /Volumes/Xcode - -################################################################################ -# Copy Freetype into sysroot -if [ -e "/Volumes/XQuartz-*" ]; then - hdiutil detach /Volumes/XQuartz-* -fi -hdiutil attach $XQUARTZ_DMG - -echo "Copying freetype..." -rm -rf /tmp/XQuartz -pkgutil --expand /Volumes/XQuartz-*/XQuartz.pkg /tmp/XQuartz/ -rm -rf /tmp/x11 -mkdir /tmp/x11 -cd /tmp/x11 -cat /tmp/XQuartz/x11.pkg/Payload | gunzip -dc | cpio -i - -mkdir -p $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/X11/include/ -mkdir -p $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/X11/lib/ -cp -RH opt/X11/include/freetype2 \ - $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/X11/include/ -cp -RH opt/X11/include/ft2build.h \ - $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/X11/include/ -cp -RH opt/X11/lib/libfreetype.* \ - $DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/X11/lib/ - -cd - - -hdiutil detach /Volumes/XQuartz-* - -################################################################################ -# Copy gnu make -mkdir -p $DEVKIT_ROOT/bin -cp $GNU_MAKE $DEVKIT_ROOT/bin - -################################################################################ -# Optionally copy PackageMaker - -if [ -e "$AUXTOOLS_DMG" ]; then - if [ -e "/Volumes/Auxiliary Tools" ]; then - hdiutil detach "/Volumes/Auxiliary Tools" - fi - hdiutil attach $AUXTOOLS_DMG - - echo "Copying PackageMaker.app..." - cp -RH "/Volumes/Auxiliary Tools/PackageMaker.app" $DEVKIT_ROOT/ - - hdiutil detach "/Volumes/Auxiliary Tools" -fi - -################################################################################ -# Generate devkit.info - -echo-info() { - echo "$1" >> $DEVKIT_ROOT/devkit.info -} - -echo "Generating devkit.info..." -rm -f $DEVKIT_ROOT/devkit.info -echo-info "# This file describes to configure how to interpret the contents of this devkit" -echo-info "# The parameters used to create this devkit were:" -echo-info "# $*" -echo-info "DEVKIT_NAME=\"Xcode $XCODE_VERSION (devkit)\"" -echo-info "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:\$DEVKIT_ROOT/Xcode.app/Contents/Developer/usr/bin\"" -echo-info "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk\"" -echo-info "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/bin:\$DEVKIT_ROOT/PackageMaker.app/Contents/MacOS:\$DEVKIT_TOOLCHAIN_PATH\"" - -################################################################################ -# Copy this script - -echo "Copying this script..." -cp $0 $DEVKIT_ROOT/ - -################################################################################ -# Create bundle - -echo "Creating bundle..." -(cd $DEVKIT_ROOT && tar c - . | gzip - > "$DEVKIT_BUNDLE")
diff --git a/make/devkit/createMacosxDevkit9.sh b/make/devkit/createMacosxDevkit9.sh deleted file mode 100644 index 28cd31e..0000000 --- a/make/devkit/createMacosxDevkit9.sh +++ /dev/null
@@ -1,146 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# This script copies parts of an Xcode installation into a devkit suitable -# for building OpenJDK and OracleJDK. The installation Xcode_X.X.xip needs -# to be either installed or extracted using for example Archive Utility. -# The easiest way to accomplish this is to right click the file in Finder -# and choose "Open With -> Archive Utility", or possible typing -# "open Xcode_9.2.xip" in a terminal. -# erik.joelsson@oracle.com - -USAGE="$0 <Xcode.app>" - -if [ "$1" = "" ]; then - echo $USAGE - exit 1 -fi - -XCODE_APP="$1" -XCODE_APP_DIR_NAME="${XCODE_APP##*/}" - -SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)" -BUILD_DIR="${SCRIPT_DIR}/../../build/devkit" - -# Find the version of Xcode -XCODE_VERSION="$($XCODE_APP/Contents/Developer/usr/bin/xcodebuild -version \ - | awk '/Xcode/ { print $2 }' )" -SDK_VERSION="MacOSX10.13" -if [ ! -e "$XCODE_APP/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/${SDK_VERSION}.sdk" ]; then - echo "Expected SDK version not found: ${SDK_VERSION}" - exit 1 -fi - -DEVKIT_ROOT="${BUILD_DIR}/Xcode${XCODE_VERSION}-${SDK_VERSION}" -DEVKIT_BUNDLE="${DEVKIT_ROOT}.tar.gz" - -echo "Xcode version: $XCODE_VERSION" -echo "Creating devkit in $DEVKIT_ROOT" - -mkdir -p $DEVKIT_ROOT - -################################################################################ -# Copy the relevant parts of Xcode.app, removing things that are both big and -# unecessary for our purposes, without building an impossibly long exclude list. -# -# Not including WatchSimulator.platform makes ibtool crashes in some situations. -# It doesn't seem to matter which extra platform is included, but that is the -# smallest one. - -EXCLUDE_DIRS=" \ - Contents/_CodeSignature \ - $XCODE_APP_DIR_NAME/Contents/Applications \ - $XCODE_APP_DIR_NAME/Contents/Resources \ - $XCODE_APP_DIR_NAME/Contents/Library \ - $XCODE_APP_DIR_NAME/Contents/XPCServices \ - $XCODE_APP_DIR_NAME/Contents/OtherFrameworks \ - $XCODE_APP_DIR_NAME/Contents/Developer/Documentation \ - $XCODE_APP_DIR_NAME/Contents/Developer/usr/share \ - $XCODE_APP_DIR_NAME/Contents/Developer/usr/libexec/git-core \ - $XCODE_APP_DIR_NAME/Contents/Developer/usr/bin/git* \ - $XCODE_APP_DIR_NAME/Contents/Developer/usr/bin/svn* \ - $XCODE_APP_DIR_NAME/Contents/Developer/usr/lib/libgit* \ - $XCODE_APP_DIR_NAME/Contents/Developer/usr/lib/libsvn* \ - $XCODE_APP_DIR_NAME/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/share/man \ - $XCODE_APP_DIR_NAME/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/${SDK_VERSION}.sdk/usr/share/man \ - $XCODE_APP_DIR_NAME/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/share/man \ - $XCODE_APP_DIR_NAME/Contents/Developer/Platforms/MacOSX.platform/usr \ - $XCODE_APP_DIR_NAME/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man \ - $XCODE_APP_DIR_NAME/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift* \ - $XCODE_APP_DIR_NAME/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift* \ - $XCODE_APP_DIR_NAME/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/sourcekitd.framework \ - $XCODE_APP_DIR_NAME/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/libexec/swift* \ - $XCODE_APP_DIR_NAME/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/swift* \ - $XCODE_APP_DIR_NAME/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/arc \ - Platforms/AppleTVSimulator.platform \ - Platforms/iPhoneSimulator.platform \ - $XCODE_APP_DIR_NAME/Contents/SharedFrameworks/LLDB.framework \ - $XCODE_APP_DIR_NAME/Contents/SharedFrameworks/ModelIO.framework \ - $XCODE_APP_DIR_NAME/Contents/SharedFrameworks/XCSUI.framework \ - $XCODE_APP_DIR_NAME/Contents/SharedFrameworks/SceneKit.framework \ - $XCODE_APP_DIR_NAME/Contents/SharedFrameworks/XCBuild.framework \ - $XCODE_APP_DIR_NAME/Contents/SharedFrameworks/GPUTools.framework \ - $(cd $XCODE_APP/.. && ls -d $XCODE_APP_DIR_NAME/Contents/Developer/Platforms/* \ - | grep -v MacOSX.platform | grep -v WatchSimulator.platform) \ -" - -for ex in $EXCLUDE_DIRS; do - EXCLUDE_ARGS+="--exclude=$ex " -done - -echo "Copying Xcode.app..." -echo rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP" $DEVKIT_ROOT/ -rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP" $DEVKIT_ROOT/ - -################################################################################ - -echo-info() { - echo "$1" >> $DEVKIT_ROOT/devkit.info -} - -echo "Generating devkit.info..." -rm -f $DEVKIT_ROOT/devkit.info -echo-info "# This file describes to configure how to interpret the contents of this devkit" -echo-info "DEVKIT_NAME=\"Xcode $XCODE_VERSION (devkit)\"" -echo-info "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:\$DEVKIT_ROOT/Xcode.app/Contents/Developer/usr/bin\"" -echo-info "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/$SDK_VERSION.sdk\"" -echo-info "DEVKIT_EXTRA_PATH=\"\$DEVKIT_TOOLCHAIN_PATH\"" - -################################################################################ -# Copy this script - -echo "Copying this script..." -cp $0 $DEVKIT_ROOT/ - -################################################################################ -# Create bundle - -echo "Creating bundle..." -GZIP=$(command -v pigz) -if [ -z "$GZIP" ]; then - GZIP="gzip" -fi -(cd $DEVKIT_ROOT && tar c - . | $GZIP - > "$DEVKIT_BUNDLE")
diff --git a/make/devkit/createWindowsDevkit2017.sh b/make/devkit/createWindowsDevkit2017.sh index 0dda08d..3b70b13 100644 --- a/make/devkit/createWindowsDevkit2017.sh +++ b/make/devkit/createWindowsDevkit2017.sh
@@ -89,19 +89,23 @@ REDIST_SUBDIR="VC/Redist/MSVC/14.12.25810" echo "Copying VC..." mkdir -p $DEVKIT_ROOT/VC/bin + cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/arm64" $DEVKIT_ROOT/VC/bin/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/x64" $DEVKIT_ROOT/VC/bin/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx86/x86" $DEVKIT_ROOT/VC/bin/ mkdir -p $DEVKIT_ROOT/VC/lib + cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/arm64" $DEVKIT_ROOT/VC/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x64" $DEVKIT_ROOT/VC/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x86" $DEVKIT_ROOT/VC/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/include" $DEVKIT_ROOT/VC/ mkdir -p $DEVKIT_ROOT/VC/atlmfc/lib + cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/arm64" $DEVKIT_ROOT/VC/atlmfc/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x64" $DEVKIT_ROOT/VC/atlmfc/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x86" $DEVKIT_ROOT/VC/atlmfc/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/include" $DEVKIT_ROOT/VC/atlmfc/ mkdir -p $DEVKIT_ROOT/VC/Auxiliary cp -r "$VS_INSTALL_DIR/VC/Auxiliary/Build" $DEVKIT_ROOT/VC/Auxiliary/ mkdir -p $DEVKIT_ROOT/VC/redist + cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/arm64" $DEVKIT_ROOT/VC/redist/ cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x64" $DEVKIT_ROOT/VC/redist/ cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x86" $DEVKIT_ROOT/VC/redist/ @@ -111,6 +115,8 @@ cp $DEVKIT_ROOT/VC/redist/x86/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x86 cp $DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x64 cp $DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x64 + cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/arm64 + cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/arm64 fi ################################################################################ @@ -128,8 +134,10 @@ cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x64" $DEVKIT_ROOT/$SDK_VERSION/bin/ cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x86" $DEVKIT_ROOT/$SDK_VERSION/bin/ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/lib + cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/ + cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/Redist @@ -164,6 +172,13 @@ echo-info "DEVKIT_MSVCR_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL\"" echo-info "DEVKIT_MSVCP_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL\"" echo-info "DEVKIT_UCRT_DLL_DIR_x86_64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/x64\"" +echo-info "" +echo-info "DEVKIT_TOOLCHAIN_PATH_aarch64=\"\$DEVKIT_ROOT/VC/bin/arm64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x86\"" +echo-info "DEVKIT_VS_INCLUDE_aarch64=\"\$DEVKIT_ROOT/VC/include;\$DEVKIT_ROOT/VC/atlmfc/include;\$DEVKIT_ROOT/$SDK_VERSION/include/shared;\$DEVKIT_ROOT/$SDK_VERSION/include/ucrt;\$DEVKIT_ROOT/$SDK_VERSION/include/um;\$DEVKIT_ROOT/$SDK_VERSION/include/winrt\"" +echo-info "DEVKIT_VS_LIB_aarch64=\"\$DEVKIT_ROOT/VC/lib/arm64;\$DEVKIT_ROOT/VC/atlmfc/lib/arm64;\$DEVKIT_ROOT/$SDK_VERSION/lib/arm64\"" +echo-info "DEVKIT_MSVCR_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCR_DLL\"" +echo-info "DEVKIT_MSVCP_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL\"" +echo-info "DEVKIT_UCRT_DLL_DIR_aarch64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/arm64\"" ################################################################################ # Copy this script
diff --git a/make/gendata/Gendata-java.base.gmk b/make/gendata/Gendata-java.base.gmk index 3bead43..0783150 100644 --- a/make/gendata/Gendata-java.base.gmk +++ b/make/gendata/Gendata-java.base.gmk
@@ -32,7 +32,7 @@ include GendataTZDB.gmk -include GendataBlacklistedCerts.gmk +include GendataBlockedCerts.gmk include GendataCryptoPolicy.gmk
diff --git a/make/gendata/GendataBlacklistedCerts.gmk b/make/gendata/GendataBlacklistedCerts.gmk deleted file mode 100644 index a35a293..0000000 --- a/make/gendata/GendataBlacklistedCerts.gmk +++ /dev/null
@@ -1,36 +0,0 @@ -# -# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -$(eval $(call IncludeCustomExtension, gendata/GendataBlacklistedCerts.gmk)) - -GENDATA_BLACKLISTED_CERTS_SRC += $(TOPDIR)/make/data/blacklistedcertsconverter/blacklisted.certs.pem -GENDATA_BLACKLISTED_CERTS := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE)/security/blacklisted.certs - -$(GENDATA_BLACKLISTED_CERTS): $(BUILD_TOOLS_JDK) $(GENDATA_BLACKLISTED_CERTS_SRC) - $(call LogInfo, Generating blacklisted certs) - $(call MakeDir, $(@D)) - ($(CAT) $(GENDATA_BLACKLISTED_CERTS_SRC) | $(TOOL_BLACKLISTED_CERTS) > $@) || exit 1 - -TARGETS += $(GENDATA_BLACKLISTED_CERTS)
diff --git a/make/gendata/GendataBlockedCerts.gmk b/make/gendata/GendataBlockedCerts.gmk new file mode 100644 index 0000000..101e93d --- /dev/null +++ b/make/gendata/GendataBlockedCerts.gmk
@@ -0,0 +1,36 @@ +# +# Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +$(eval $(call IncludeCustomExtension, gendata/GendataBlockedCerts.gmk)) + +GENDATA_BLOCKED_CERTS_SRC += $(TOPDIR)/make/data/blockedcertsconverter/blocked.certs.pem +GENDATA_BLOCKED_CERTS := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE)/security/blocked.certs + +$(GENDATA_BLOCKED_CERTS): $(BUILD_TOOLS_JDK) $(GENDATA_BLOCKED_CERTS_SRC) + $(call LogInfo, Generating blocked certs) + $(call MakeDir, $(@D)) + ($(CAT) $(GENDATA_BLOCKED_CERTS_SRC) | $(TOOL_BLOCKED_CERTS) > $@) || exit 1 + +TARGETS += $(GENDATA_BLOCKED_CERTS)
diff --git a/make/gensrc/GensrcMisc.gmk b/make/gensrc/GensrcMisc.gmk index b01dd17..19c37a5 100644 --- a/make/gensrc/GensrcMisc.gmk +++ b/make/gensrc/GensrcMisc.gmk
@@ -63,6 +63,12 @@ CPP_FLAGS += -x c else ifeq ($(TOOLCHAIN_TYPE), microsoft) CPP_FLAGS += -nologo + + ifeq ($(OPENJDK_TARGET_CPU),aarch64) + # cl.exe does only recognize few file extensions as valid (ex: .c, .h, .cpp), so + # make sure *.java.template files are recognized as valid input files + CPP_FILEPREFIX = -Tc + endif endif # Generate a java source file from a template through the C preprocessor for the @@ -75,7 +81,7 @@ define generate-preproc-src $(call MakeDir, $(@D)) ( $(NAWK) '/@@END_COPYRIGHT@@/{exit}1' $< && \ - $(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $< \ + $(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $(CPP_FILEPREFIX) $< \ 2> >($(GREP) -v '^$(<F)$$' >&2) \ | $(NAWK) '/@@START_HERE@@/,0' \ | $(SED) -e 's/@@START_HERE@@/\/\/ AUTOMATICALLY GENERATED FILE - DO NOT EDIT/' \
diff --git a/make/hotspot/gensrc/GensrcAdlc.gmk b/make/hotspot/gensrc/GensrcAdlc.gmk index 6878962..bfb0970 100644 --- a/make/hotspot/gensrc/GensrcAdlc.gmk +++ b/make/hotspot/gensrc/GensrcAdlc.gmk
@@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -99,6 +99,16 @@ ADLCFLAGS += -DAIX=1 else ifeq ($(OPENJDK_TARGET_OS), macosx) ADLCFLAGS += -D_ALLBSD_SOURCE=1 -D_GNU_SOURCE=1 + ifeq ($(HOTSPOT_TARGET_CPU_ARCH), aarch64) + ADLCFLAGS += -DR18_RESERVED + endif + else ifeq ($(OPENJDK_TARGET_OS), windows) + ifeq ($(call isTargetCpuBits, 64), true) + ADLCFLAGS += -D_WIN64=1 + endif + ifeq ($(HOTSPOT_TARGET_CPU_ARCH), aarch64) + ADLCFLAGS += -DR18_RESERVED=1 + endif endif ifneq ($(OPENJDK_TARGET_OS), windows)
diff --git a/make/hotspot/lib/CompileGtest.gmk b/make/hotspot/lib/CompileGtest.gmk index c4c8429..6a52be6 100644 --- a/make/hotspot/lib/CompileGtest.gmk +++ b/make/hotspot/lib/CompileGtest.gmk
@@ -55,6 +55,9 @@ # Disabling undef, switch, format-nonliteral and tautological-undefined-compare # warnings for clang because of test source. +# Disable MSVC warning C4146 "unary minus operator applied to unsigned type, +# result still unsigned". This operation is well-defined. + # Solaris: Disable inlining (+d) to workaround Assertion: (../lnk/vardescr.h, line 109) $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \ NAME := jvm, \ @@ -78,6 +81,7 @@ DISABLED_WARNINGS_clang := undef switch format-nonliteral \ tautological-undefined-compare $(BUILD_LIBJVM_DISABLED_WARNINGS_clang), \ DISABLED_WARNINGS_solstudio := identexpected, \ + DISABLED_WARNINGS_microsoft := 4146, \ LDFLAGS := $(JVM_LDFLAGS), \ LDFLAGS_solaris := -library=stlport4 $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS := $(JVM_LIBS), \
diff --git a/make/hotspot/lib/CompileJvm.gmk b/make/hotspot/lib/CompileJvm.gmk index 5942540..5c2aac6 100644 --- a/make/hotspot/lib/CompileJvm.gmk +++ b/make/hotspot/lib/CompileJvm.gmk
@@ -148,6 +148,8 @@ ################################################################################ # Now set up the actual compilation of the main hotspot native library +# Disable MSVC warning C4146 "unary minus operator applied to unsigned type, +# result still unsigned". This operation is well-defined. $(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \ NAME := jvm, \ TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ @@ -164,6 +166,7 @@ DISABLED_WARNINGS_solstudio := $(DISABLED_WARNINGS_solstudio), \ DISABLED_WARNINGS_xlc := 1540-0216 1540-0198 1540-1090 1540-1639 \ 1540-1088 1500-010, \ + DISABLED_WARNINGS_microsoft := 4146, \ ASFLAGS := $(JVM_ASFLAGS), \ LDFLAGS := $(JVM_LDFLAGS), \ LIBS := $(JVM_LIBS), \
diff --git a/make/jdk/src/classes/build/tools/blacklistedcertsconverter/BlacklistedCertsConverter.java b/make/jdk/src/classes/build/tools/blacklistedcertsconverter/BlacklistedCertsConverter.java deleted file mode 100644 index 653a1db..0000000 --- a/make/jdk/src/classes/build/tools/blacklistedcertsconverter/BlacklistedCertsConverter.java +++ /dev/null
@@ -1,196 +0,0 @@ -/* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package build.tools.blacklistedcertsconverter; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.MessageDigest; -import java.security.PublicKey; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.interfaces.ECPublicKey; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; -import sun.security.util.DerValue; - -/** - * Converts blacklisted.certs.pem from System.in to blacklisted.certs in - * System.out. The input must start with a #! line including the fingerprint - * algorithm. The output is sorted and unique. - */ -public class BlacklistedCertsConverter { - - public static void main(String[] args) throws Exception { - - byte[] pattern = "#! java BlacklistedCertsConverter ".getBytes(); - String mdAlg = ""; - - for (int i=0; ; i++) { - int n = System.in.read(); - if (n < 0) { - throw new Exception("Unexpected EOF"); - } - if (i < pattern.length) { - if (n != pattern[i]) { - throw new Exception("The first line must start with \"" - + new String(pattern) + "\""); - } - } else if (i < pattern.length + 100) { - if (n < 32) { - break; - } else { - mdAlg = mdAlg + String.format("%c", n); - } - } - } - - mdAlg = mdAlg.trim(); - System.out.println("Algorithm=" + mdAlg); - - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - Collection<? extends Certificate> certs - = cf.generateCertificates(System.in); - - // Output sorted so that it's easy to locate an entry. - Set<String> fingerprints = new TreeSet<>(); - for (Certificate cert: certs) { - fingerprints.addAll( - getCertificateFingerPrints(mdAlg, (X509Certificate)cert)); - } - - for (String s: fingerprints) { - System.out.println(s); - } - } - - /** - * Converts a byte to hex digit and writes to the supplied buffer - */ - private static void byte2hex(byte b, StringBuffer buf) { - char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', - '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - int high = ((b & 0xf0) >> 4); - int low = (b & 0x0f); - buf.append(hexChars[high]); - buf.append(hexChars[low]); - } - - /** - * Computes the possible fingerprints of the certificate. - */ - private static List<String> getCertificateFingerPrints( - String mdAlg, X509Certificate cert) throws Exception { - List<String> fingerprints = new ArrayList<>(); - for (byte[] encoding : altEncodings(cert)) { - MessageDigest md = MessageDigest.getInstance(mdAlg); - byte[] digest = md.digest(encoding); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < digest.length; i++) { - byte2hex(digest[i], buf); - } - fingerprints.add(buf.toString()); - } - return fingerprints; - } - - private static List<byte[]> altEncodings(X509Certificate c) - throws Exception { - List<byte[]> result = new ArrayList<>(); - - DerValue d = new DerValue(c.getEncoded()); - DerValue[] seq = new DerValue[3]; - // tbsCertificate - seq[0] = d.data.getDerValue(); - // signatureAlgorithm - seq[1] = d.data.getDerValue(); - // signature - seq[2] = d.data.getDerValue(); - - List<DerValue> algIds = Arrays.asList(seq[1], altAlgId(seq[1])); - - List<DerValue> sigs; - PublicKey p = c.getPublicKey(); - if (p instanceof ECPublicKey) { - ECPublicKey ep = (ECPublicKey) p; - BigInteger mod = ep.getParams().getOrder(); - sigs = Arrays.asList(seq[2], altSig(mod, seq[2])); - } else { - sigs = Arrays.asList(seq[2]); - } - - for (DerValue algId : algIds) { - for (DerValue sig : sigs) { - DerOutputStream tmp = new DerOutputStream(); - tmp.putDerValue(seq[0]); - tmp.putDerValue(algId); - tmp.putDerValue(sig); - DerOutputStream tmp2 = new DerOutputStream(); - tmp2.write(DerValue.tag_Sequence, tmp); - result.add(tmp2.toByteArray()); - } - } - return result; - } - - private static DerValue altSig(BigInteger mod, DerValue sig) - throws IOException { - byte[] sigBits = sig.getBitString(); - DerInputStream in = - new DerInputStream(sigBits, 0, sigBits.length, false); - DerValue[] values = in.getSequence(2); - BigInteger r = values[0].getBigInteger(); - BigInteger s = values[1].getBigInteger(); - BigInteger s2 = s.negate().mod(mod); - DerOutputStream out = new DerOutputStream(); - out.putInteger(r); - out.putInteger(s2); - DerOutputStream tmp = new DerOutputStream(); - tmp.putBitString(new DerValue(DerValue.tag_Sequence, - out.toByteArray()).toByteArray()); - return new DerValue(tmp.toByteArray()); - } - - private static DerValue altAlgId(DerValue algId) throws IOException { - DerInputStream in = algId.toDerInputStream(); - DerOutputStream bytes = new DerOutputStream(); - bytes.putOID(in.getOID()); - // encode parameters as NULL if not present or omit if NULL - if (in.available() == 0) { - bytes.putNull(); - } - DerOutputStream tmp = new DerOutputStream(); - tmp.write(DerValue.tag_Sequence, bytes); - return new DerValue(tmp.toByteArray()); - } -}
diff --git a/make/jdk/src/classes/build/tools/blockedcertsconverter/BlockedCertsConverter.java b/make/jdk/src/classes/build/tools/blockedcertsconverter/BlockedCertsConverter.java new file mode 100644 index 0000000..1b2a3eb --- /dev/null +++ b/make/jdk/src/classes/build/tools/blockedcertsconverter/BlockedCertsConverter.java
@@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package build.tools.blockedcertsconverter; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.PublicKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.interfaces.ECPublicKey; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import sun.security.util.DerInputStream; +import sun.security.util.DerOutputStream; +import sun.security.util.DerValue; + +/** + * Converts blocked.certs.pem from System.in to blocked.certs in + * System.out. The input must start with a #! line including the fingerprint + * algorithm. The output is sorted and unique. + */ +public class BlockedCertsConverter { + + public static void main(String[] args) throws Exception { + + byte[] pattern = "#! java BlockedCertsConverter ".getBytes(); + String mdAlg = ""; + + for (int i=0; ; i++) { + int n = System.in.read(); + if (n < 0) { + throw new Exception("Unexpected EOF"); + } + if (i < pattern.length) { + if (n != pattern[i]) { + throw new Exception("The first line must start with \"" + + new String(pattern) + "\""); + } + } else if (i < pattern.length + 100) { + if (n < 32) { + break; + } else { + mdAlg = mdAlg + String.format("%c", n); + } + } + } + + mdAlg = mdAlg.trim(); + System.out.println("Algorithm=" + mdAlg); + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Collection<? extends Certificate> certs + = cf.generateCertificates(System.in); + + // Output sorted so that it's easy to locate an entry. + Set<String> fingerprints = new TreeSet<>(); + for (Certificate cert: certs) { + fingerprints.addAll( + getCertificateFingerPrints(mdAlg, (X509Certificate)cert)); + } + + for (String s: fingerprints) { + System.out.println(s); + } + } + + /** + * Converts a byte to hex digit and writes to the supplied buffer + */ + private static void byte2hex(byte b, StringBuffer buf) { + char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + int high = ((b & 0xf0) >> 4); + int low = (b & 0x0f); + buf.append(hexChars[high]); + buf.append(hexChars[low]); + } + + /** + * Computes the possible fingerprints of the certificate. + */ + private static List<String> getCertificateFingerPrints( + String mdAlg, X509Certificate cert) throws Exception { + List<String> fingerprints = new ArrayList<>(); + for (byte[] encoding : altEncodings(cert)) { + MessageDigest md = MessageDigest.getInstance(mdAlg); + byte[] digest = md.digest(encoding); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < digest.length; i++) { + byte2hex(digest[i], buf); + } + fingerprints.add(buf.toString()); + } + return fingerprints; + } + + private static List<byte[]> altEncodings(X509Certificate c) + throws Exception { + List<byte[]> result = new ArrayList<>(); + + DerValue d = new DerValue(c.getEncoded()); + DerValue[] seq = new DerValue[3]; + // tbsCertificate + seq[0] = d.data.getDerValue(); + // signatureAlgorithm + seq[1] = d.data.getDerValue(); + // signature + seq[2] = d.data.getDerValue(); + + List<DerValue> algIds = Arrays.asList(seq[1], altAlgId(seq[1])); + + List<DerValue> sigs; + PublicKey p = c.getPublicKey(); + if (p instanceof ECPublicKey) { + ECPublicKey ep = (ECPublicKey) p; + BigInteger mod = ep.getParams().getOrder(); + sigs = Arrays.asList(seq[2], altSig(mod, seq[2])); + } else { + sigs = Arrays.asList(seq[2]); + } + + for (DerValue algId : algIds) { + for (DerValue sig : sigs) { + DerOutputStream tmp = new DerOutputStream(); + tmp.putDerValue(seq[0]); + tmp.putDerValue(algId); + tmp.putDerValue(sig); + DerOutputStream tmp2 = new DerOutputStream(); + tmp2.write(DerValue.tag_Sequence, tmp); + result.add(tmp2.toByteArray()); + } + } + return result; + } + + private static DerValue altSig(BigInteger mod, DerValue sig) + throws IOException { + byte[] sigBits = sig.getBitString(); + DerInputStream in = + new DerInputStream(sigBits, 0, sigBits.length, false); + DerValue[] values = in.getSequence(2); + BigInteger r = values[0].getBigInteger(); + BigInteger s = values[1].getBigInteger(); + BigInteger s2 = s.negate().mod(mod); + DerOutputStream out = new DerOutputStream(); + out.putInteger(r); + out.putInteger(s2); + DerOutputStream tmp = new DerOutputStream(); + tmp.putBitString(new DerValue(DerValue.tag_Sequence, + out.toByteArray()).toByteArray()); + return new DerValue(tmp.toByteArray()); + } + + private static DerValue altAlgId(DerValue algId) throws IOException { + DerInputStream in = algId.toDerInputStream(); + DerOutputStream bytes = new DerOutputStream(); + bytes.putOID(in.getOID()); + // encode parameters as NULL if not present or omit if NULL + if (in.available() == 0) { + bytes.putNull(); + } + DerOutputStream tmp = new DerOutputStream(); + tmp.write(DerValue.tag_Sequence, bytes); + return new DerValue(tmp.toByteArray()); + } +}
diff --git a/make/jdk/src/classes/build/tools/depend/Depend.java b/make/jdk/src/classes/build/tools/depend/Depend.java index ba7e882..75c51fa 100644 --- a/make/jdk/src/classes/build/tools/depend/Depend.java +++ b/make/jdk/src/classes/build/tools/depend/Depend.java
@@ -101,7 +101,7 @@ private final MessageDigest apiHash; { try { - apiHash = MessageDigest.getInstance("MD5"); + apiHash = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException ex) { throw new IllegalStateException(ex); }
diff --git a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java index a4e673d..7d1b7b2 100644 --- a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java +++ b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java
@@ -132,7 +132,7 @@ + " A region/variant subtag \"" + preferred + "\" is registered for more than one subtags."); } - } else { // language, extlang, grandfathered, and redundant + } else { // language, extlang, legacy, and redundant if (!initialLanguageMap.containsKey(preferred)) { sb = new StringBuilder(preferred); sb.append(',');
diff --git a/make/lib/Awt2dLibraries.gmk b/make/lib/Awt2dLibraries.gmk index 39269d0..f9773bf 100644 --- a/make/lib/Awt2dLibraries.gmk +++ b/make/lib/Awt2dLibraries.gmk
@@ -433,7 +433,7 @@ OPTIMIZATION := HIGHEST, \ CFLAGS := $(CFLAGS_JDKLIB), \ HEADERS_FROM_SRC := $(LIBJPEG_HEADERS_FROM_SRC), \ - DISABLED_WARNINGS_gcc := clobbered implicit-fallthrough shift-negative-value, \ + DISABLED_WARNINGS_gcc := clobbered implicit-fallthrough shift-negative-value array-bounds, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS := $(LIBJPEG_LIBS) $(JDKLIB_LIBS), \ @@ -554,12 +554,6 @@ ifeq ($(OPENJDK_TARGET_OS), solaris) HARFBUZZ_CFLAGS += -DHAVE_SOLARIS_ATOMIC_OPS endif - ifeq ($(OPENJDK_TARGET_OS), macosx) - HARFBUZZ_CFLAGS += -DHAVE_CORETEXT - endif - ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-coretext.cc - endif # hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later. LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc @@ -568,7 +562,7 @@ maybe-uninitialized class-memaccess HARFBUZZ_DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \ tautological-constant-out-of-range-compare int-to-pointer-cast \ - undef missing-field-initializers + undef missing-field-initializers deprecated-declarations c++11-narrowing HARFBUZZ_DISABLED_WARNINGS_microsoft := 4267 4244 4090 4146 4334 4819 4101 4068 4805 4138 HARFBUZZ_DISABLED_WARNINGS_C_solstudio := \ E_INTEGER_OVERFLOW_DETECTED \
diff --git a/make/lib/Lib-jdk.hotspot.agent.gmk b/make/lib/Lib-jdk.hotspot.agent.gmk index 83c0b53..e137a4f 100644 --- a/make/lib/Lib-jdk.hotspot.agent.gmk +++ b/make/lib/Lib-jdk.hotspot.agent.gmk
@@ -36,7 +36,7 @@ SA_LDFLAGS := -mt else ifeq ($(OPENJDK_TARGET_OS), macosx) - SA_CFLAGS := -Damd64 -D_GNU_SOURCE -mno-omit-leaf-frame-pointer \ + SA_CFLAGS := -D_GNU_SOURCE -mno-omit-leaf-frame-pointer \ -mstack-alignment=16 -fPIC LIBSA_EXTRA_SRC := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent else ifeq ($(OPENJDK_TARGET_OS), windows)
diff --git a/make/scripts/compare.sh b/make/scripts/compare.sh index 728de45..a2f6cbc 100644 --- a/make/scripts/compare.sh +++ b/make/scripts/compare.sh
@@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,9 @@ exit 1 fi +# Make sure all shell commands are executed with the C locale +export LC_ALL=C + if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then FULLDUMP_CMD="$OTOOL -v -V -h -X -d" LDD_CMD="$OTOOL -L" @@ -81,7 +84,7 @@ if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then # Filter out date string, ant version and java version differences. - TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ + TMP=$($DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>] Ant-Version: Apache Ant .*/d' \ -e '/[<>] Created-By: .* (Oracle [Corpatin)]*/d' \ @@ -89,7 +92,7 @@ -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') fi if test "x$SUFFIX" = "xjava"; then - TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ + TMP=$($DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>] \* from.*\.idl/d' \ -e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ @@ -144,7 +147,7 @@ fi if test "x$SUFFIX" = "xproperties"; then # Filter out date string differences. - TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ + TMP=$($DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d') fi @@ -154,7 +157,7 @@ -e 's/<font size=-1>/<font size=\"-1\">/g'" $CAT $THIS_FILE | eval "$HTML_FILTER" > $THIS_FILE.filtered $CAT $OTHER_FILE | eval "$HTML_FILTER" > $OTHER_FILE.filtered - TMP=$(LC_ALL=C $DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \ + TMP=$($DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \ $GREP '^[<>]' | \ $SED -e '/[<>] <!-- Generated by javadoc .* on .* -->/d' \ -e '/[<>] <meta name="date" content=".*">/d' ) @@ -481,11 +484,11 @@ CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff # On solaris, there is no -q option. if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then - LC_ALL=C $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \ + $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \ | $GREP -v -e "^<" -e "^>" -e "^Common subdirectories:" \ > $CONTENTS_DIFF_FILE else - LC_ALL=C $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE + $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE fi ONLY_OTHER=$($GREP "^Only in $OTHER_UNZIPDIR" $CONTENTS_DIFF_FILE) @@ -532,11 +535,11 @@ if [ -n "$SHOW_DIFFS" ]; then for i in $(cat $WORK_DIR/$ZIP_FILE.difflist) ; do if [ -f "${OTHER_UNZIPDIR}/$i.javap" ]; then - LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap + $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap elif [ -f "${OTHER_UNZIPDIR}/$i.cleaned" ]; then - LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i + $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i else - LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i + $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i fi done fi @@ -776,7 +779,7 @@ > $WORK_FILE_BASE.symbols.this fi - LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff + $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff if [ -s $WORK_FILE_BASE.symbols.diff ]; then SYM_MSG=" diff " if [[ "$ACCEPTED_SYM_DIFF" != *"$BIN_FILE"* ]]; then @@ -816,9 +819,9 @@ | $UNIQ > $WORK_FILE_BASE.deps.this.uniq) (cd $FILE_WORK_DIR && $RM -f $NAME) - LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this \ + $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this \ > $WORK_FILE_BASE.deps.diff - LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq \ + $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq \ > $WORK_FILE_BASE.deps.diff.uniq if [ -s $WORK_FILE_BASE.deps.diff ]; then @@ -868,7 +871,7 @@ > $WORK_FILE_BASE.fulldump.this 2>&1 & wait - LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \ + $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \ > $WORK_FILE_BASE.fulldump.diff if [ -s $WORK_FILE_BASE.fulldump.diff ]; then @@ -915,7 +918,7 @@ | eval "$this_DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this 2>&1 & wait - LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff + $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff if [ -s $WORK_FILE_BASE.dis.diff ]; then DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}') @@ -1044,7 +1047,7 @@ -o -name '*.zip' -o -name '*.jimage' -o -name '*.java' -o -name '*.mf' \ -o -name '*.jpg' -o -name '*.wsdl' -o -name '*.js' -o -name '*.sh' \ -o -name '*.bat' -o -name '*LICENSE' -o -name '*.d' -o -name '*store' \ - -o -name 'blacklist' -o -name '*certs' -o -name '*.ttf' \ + -o -name 'blocked' -o -name '*certs' -o -name '*.ttf' \ -o -name '*.jfc' -o -name '*.dat' -o -name 'release' -o -name '*.dir'\ -o -name '*.sym' -o -name '*.idl' -o -name '*.h' -o -name '*.access' \ -o -name '*.template' -o -name '*.policy' -o -name '*.security' \
diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk index bb6a0ec..58bd7bf 100644 --- a/make/test/JtregNativeHotspot.gmk +++ b/make/test/JtregNativeHotspot.gmk
@@ -148,6 +148,9 @@ # Optimization -O3 needed, HIGH == -O3 BUILD_HOTSPOT_JTREG_LIBRARIES_OPTIMIZATION_libNoFramePointer := HIGH +BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS := -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS +BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS := -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS + BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libProcessUtils := $(VM_SHARE_INCLUDES) BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libThreadController := $(NSK_MONITORING_INCLUDES) @@ -845,10 +848,6 @@ ################################################################################ -ifeq ($(TOOLCHAIN_TYPE), solstudio) - BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libji06t001 += -erroff=E_END_OF_LOOP_CODE_NOT_REACHED -endif - # Platform specific setup ifneq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc) BUILD_HOTSPOT_JTREG_EXCLUDE += liboverflow.c exeThreadSignalMask.c
diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index f6cf7cf..0745606 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk
@@ -83,6 +83,7 @@ else BUILD_JDK_JTREG_EXCLUDE += libTestMainKeyWindow.m BUILD_JDK_JTREG_EXCLUDE += libTestDynamicStore.m + BUILD_JDK_JTREG_EXCLUDE += exeLibraryCache.c endif $(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_LIBRARIES, \
diff --git a/src/demo/share/java2d/J2DBench/options/default.opt b/src/demo/share/java2d/J2DBench/options/default.opt index e188354..c936051 100644 --- a/src/demo/share/java2d/J2DBench/options/default.opt +++ b/src/demo/share/java2d/J2DBench/options/default.opt
@@ -8,8 +8,11 @@ global.results.workunits=units global.results.timeunits=sec global.results.ratio=unitspersec -global.dest.screen=disabled global.dest.offscreen=disabled +global.dest.frame.defaultframe=disabled +global.dest.frame.transframe=disabled +global.dest.frame.shapedframe=disabled +global.dest.frame.shapedtransframe=disabled global.dest.compatimg.compatimg=disabled global.dest.compatimg.opqcompatimg=disabled global.dest.compatimg.bmcompatimg=disabled
diff --git a/src/demo/share/java2d/J2DBench/src/j2dbench/Destinations.java b/src/demo/share/java2d/J2DBench/src/j2dbench/Destinations.java index 5cc3c56..9c5f6c7 100644 --- a/src/demo/share/java2d/J2DBench/src/j2dbench/Destinations.java +++ b/src/demo/share/java2d/J2DBench/src/j2dbench/Destinations.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,9 +40,11 @@ package j2dbench; -import java.awt.Image; import java.awt.Component; +import java.awt.Frame; import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Polygon; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; @@ -50,11 +52,14 @@ import java.awt.image.DataBuffer; import java.awt.image.WritableRaster; +import javax.swing.SwingUtilities; + import j2dbench.tests.GraphicsTests; import j2dbench.tests.ImageTests; public abstract class Destinations extends Option.Enable { public static Group.EnableSet destroot; + public static Group frameroot; public static Group bufimgdestroot; public static Group compatimgdestroot; public static Group volimgdestroot; @@ -63,9 +68,22 @@ destroot = new Group.EnableSet(TestEnvironment.globaloptroot, "dest", "Output Destination Options"); - new Screen(); new OffScreen(); + frameroot = new Group.EnableSet(destroot, "frame", "Output to Frame"); + frameroot.setHorizontal(); + + new Screen(false, false); + if (ImageTests.hasOpacityWindow) { + new Screen(true, false); + } + if (ImageTests.hasShapedWindow) { + new Screen(false, true); + } + if (ImageTests.hasShapedWindow && ImageTests.hasOpacityWindow) { + new Screen(true, true); + } + if (GraphicsTests.hasGraphics2D) { if (ImageTests.hasCompatImage) { compatimgdestroot = @@ -129,17 +147,95 @@ public abstract void setDestination(TestEnvironment env); public static class Screen extends Destinations { - public Screen() { - super(destroot, "screen", "Output to Screen", false); + + private boolean opacity; + private boolean shaped; + + public Screen(boolean opacity, boolean shaped) { + super(frameroot, getDescription(opacity,shaped), + getLongDescription(opacity,shaped), false); + this.opacity = opacity; + this.shaped = shaped; + } + + private static String getDescription(boolean opacity, boolean shaped){ + if (opacity && shaped) { + return "shapedtransframe"; + } + if (shaped) { + return "shapedframe"; + } + if (opacity) { + return "transframe"; + } + return "defaultframe"; + } + + private static String getLongDescription(boolean opacity, boolean shaped){ + if (opacity && shaped) { + return "Translucent and Shaped"; + } + if (shaped) { + return "Shaped"; + } + if (opacity) { + return "Translucent"; + } + return "Default"; } public String getModifierValueName(Object val) { - return "Screen"; + if (opacity && shaped) { + return "Translucent and Shaped Frame"; + } + if (shaped) { + return "Shaped Frame"; + } + if (opacity) { + return "Translucent Frame"; + } + return "Default Frame"; } public void setDestination(TestEnvironment env) { env.setTestImage(null); } + + public void modifyTest(TestEnvironment env) { + setDestination(env); + Frame frame = (Frame) SwingUtilities.getWindowAncestor(env.comp); + if (frame != null && (opacity || shaped)) { + frame.dispose(); + frame.setUndecorated(true); + int w = frame.getWidth(); + int h = frame.getHeight(); + if (shaped) { + Polygon p = new Polygon(); + p.addPoint(0, 0); + p.addPoint(w, 0); + p.addPoint(0, h); + p.addPoint(w, h); + p.addPoint(0, 0); + frame.setShape(p); + } + if (opacity) { + frame.setOpacity(0.5f); + } + frame.setVisible(true); + } + } + + public void restoreTest(TestEnvironment env) { + env.setTestImage(null); + Frame frame = (Frame) SwingUtilities.getWindowAncestor(env.comp); + if (frame != null && (opacity || shaped)) { + frame.dispose(); + frame.setShape(null); + frame.setOpacity(1); + frame.setUndecorated(false); + frame.setVisible(true); + } + } } public static class OffScreen extends Destinations {
diff --git a/src/demo/share/java2d/J2DBench/src/j2dbench/J2DBench.java b/src/demo/share/java2d/J2DBench/src/j2dbench/J2DBench.java index 053908c..457f841 100644 --- a/src/demo/share/java2d/J2DBench/src/j2dbench/J2DBench.java +++ b/src/demo/share/java2d/J2DBench/src/j2dbench/J2DBench.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,6 +40,8 @@ package j2dbench; +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; import java.io.PrintWriter; import java.io.FileReader; import java.io.FileWriter; @@ -780,7 +782,10 @@ f.getContentPane().add(p, BorderLayout.SOUTH); f.pack(); f.setLocationRelativeTo(null); - f.show(); + Rectangle usable = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getMaximumWindowBounds().intersection(f.getBounds()); + f.setBounds(usable); + f.setVisible(true); } public static void runTests(boolean showresults) {
diff --git a/src/demo/share/java2d/J2DBench/src/j2dbench/tests/ImageTests.java b/src/demo/share/java2d/J2DBench/src/j2dbench/tests/ImageTests.java index 69179c4..149e8bc 100644 --- a/src/demo/share/java2d/J2DBench/src/j2dbench/tests/ImageTests.java +++ b/src/demo/share/java2d/J2DBench/src/j2dbench/tests/ImageTests.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,7 +53,9 @@ import java.awt.AlphaComposite; import java.awt.Dimension; import java.awt.GraphicsConfiguration; +import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.Window; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ByteLookupTable; @@ -79,6 +81,8 @@ public abstract class ImageTests extends GraphicsTests { public static boolean hasVolatileImage; public static boolean hasTransparentVolatileImage; + public static boolean hasShapedWindow; + public static boolean hasOpacityWindow; public static boolean hasCompatImage; static { @@ -96,6 +100,16 @@ hasTransparentVolatileImage = true; } catch (NoSuchMethodError e) { } + try { + new Window(null).setShape(new Rectangle()); + hasShapedWindow = true; + } catch (Exception e) { + } + try { + new Window(null).setOpacity(0.5f); + hasOpacityWindow = true; + } catch (Exception e) { + } } static Group imageroot;
diff --git a/src/hotspot/cpu/aarch64/aarch64-asmtest.py b/src/hotspot/cpu/aarch64/aarch64-asmtest.py index 7b5eab0..31c6965 100644 --- a/src/hotspot/cpu/aarch64/aarch64-asmtest.py +++ b/src/hotspot/cpu/aarch64/aarch64-asmtest.py
@@ -13,6 +13,8 @@ def generate(self): self.number = random.randint(0, 30) + if self.number == 18: + self.number = 17 return self def astr(self, prefix): @@ -37,6 +39,8 @@ def generate(self): self.number = random.randint(0, 31) + if self.number == 18: + self.number = 16 return self def astr(self, prefix = ""): @@ -54,6 +58,8 @@ class GeneralRegisterOrSp(Register): def generate(self): self.number = random.randint(0, 31) + if self.number == 18: + self.number = 15 return self def astr(self, prefix = ""):
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index d4ae8da..e8a63ff 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -110,8 +110,8 @@ reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); -reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); -reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); +reg_def R18 ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg() ); +reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next()); reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp @@ -352,7 +352,6 @@ R15, R15_H, R16, R16_H, R17, R17_H, - R18, R18_H, // arg registers R0, R0_H, @@ -375,7 +374,7 @@ R26, R26_H, // non-allocatable registers - + R18, R18_H, // platform R27, R27_H, // heapbase R28, R28_H, // thread R29, R29_H, // fp @@ -533,7 +532,10 @@ R15, R16, R17, +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp R18, +#endif R19, R20, R21, @@ -566,7 +568,10 @@ R15, R16, R17, +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp R18, +#endif R19, R20, R21, @@ -602,7 +607,10 @@ R15, R15_H, R16, R16_H, R17, R17_H, +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp R18, R18_H, +#endif R19, R19_H, R20, R20_H, R21, R21_H, @@ -635,7 +643,10 @@ R15, R15_H, R16, R16_H, R17, R17_H, +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp R18, R18_H, +#endif R19, R19_H, R20, R20_H, R21, R21_H, @@ -775,7 +786,10 @@ R15, R15_H, R16, R16_H, R17, R17_H, +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp R18, R18_H, +#endif R19, R19_H, R20, R20_H, R21, R21_H, @@ -2041,11 +2055,6 @@ const bool Matcher::match_rule_supported(int opcode) { - switch (opcode) { - default: - break; - } - if (!has_match_rule(opcode)) { return false; } @@ -2297,6 +2306,13 @@ bool size_fits_all_mem_uses(AddPNode* addp, int shift) { for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { Node* u = addp->fast_out(i); + if (u->is_LoadStore()) { + // On AArch64, LoadStoreNodes (i.e. compare and swap + // instructions) only take register indirect as an operand, so + // any attempt to use an AddPNode as an input to a LoadStoreNode + // must fail. + return false; + } if (u->is_Mem()) { int opsize = u->as_Mem()->memory_size(); assert(opsize > 0, "unexpected memory operand size"); @@ -3005,7 +3021,7 @@ if (con < (address)(uintptr_t)os::vm_page_size()) { __ mov(dst_reg, con); } else { - uintptr_t offset; + uint64_t offset; __ adrp(dst_reg, con, offset); __ add(dst_reg, dst_reg, offset); }
diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp index 50e774f..8047ed8 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp
@@ -96,662 +96,662 @@ __ bind(back); // ArithOp - __ add(r15, r12, r16, Assembler::LSR, 30); // add x15, x12, x16, LSR #30 - __ sub(r1, r15, r3, Assembler::LSR, 32); // sub x1, x15, x3, LSR #32 - __ adds(r13, r25, r5, Assembler::LSL, 13); // adds x13, x25, x5, LSL #13 - __ subs(r22, r28, r6, Assembler::ASR, 17); // subs x22, x28, x6, ASR #17 - __ addw(r0, r9, r22, Assembler::ASR, 6); // add w0, w9, w22, ASR #6 - __ subw(r19, r3, r25, Assembler::LSL, 21); // sub w19, w3, w25, LSL #21 - __ addsw(r4, r19, r11, Assembler::LSL, 20); // adds w4, w19, w11, LSL #20 - __ subsw(r24, r7, r19, Assembler::ASR, 0); // subs w24, w7, w19, ASR #0 - __ andr(r30, r7, r11, Assembler::LSL, 48); // and x30, x7, x11, LSL #48 - __ orr(r24, r8, r15, Assembler::LSL, 12); // orr x24, x8, x15, LSL #12 - __ eor(r17, r9, r23, Assembler::LSL, 1); // eor x17, x9, x23, LSL #1 - __ ands(r14, r11, r4, Assembler::LSR, 55); // ands x14, x11, x4, LSR #55 - __ andw(r19, r7, r12, Assembler::LSR, 17); // and w19, w7, w12, LSR #17 - __ orrw(r19, r27, r11, Assembler::ASR, 28); // orr w19, w27, w11, ASR #28 - __ eorw(r30, r3, r22, Assembler::LSR, 31); // eor w30, w3, w22, LSR #31 - __ andsw(r19, r26, r28, Assembler::ASR, 0); // ands w19, w26, w28, ASR #0 - __ bic(r29, r6, r26, Assembler::LSL, 51); // bic x29, x6, x26, LSL #51 - __ orn(r26, r27, r17, Assembler::LSL, 35); // orn x26, x27, x17, LSL #35 - __ eon(r21, r4, r14, Assembler::LSL, 5); // eon x21, x4, x14, LSL #5 - __ bics(r2, r15, r0, Assembler::ASR, 5); // bics x2, x15, x0, ASR #5 - __ bicw(r2, r7, r2, Assembler::LSL, 29); // bic w2, w7, w2, LSL #29 - __ ornw(r24, r12, r21, Assembler::LSR, 5); // orn w24, w12, w21, LSR #5 - __ eonw(r30, r15, r19, Assembler::LSL, 2); // eon w30, w15, w19, LSL #2 - __ bicsw(r30, r23, r17, Assembler::ASR, 28); // bics w30, w23, w17, ASR #28 + __ add(r15, r0, r24, Assembler::LSL, 59); // add x15, x0, x24, LSL #59 + __ sub(r17, r22, r22, Assembler::ASR, 13); // sub x17, x22, x22, ASR #13 + __ adds(r10, r26, r28, Assembler::LSL, 57); // adds x10, x26, x28, LSL #57 + __ subs(r25, r16, r24, Assembler::LSL, 18); // subs x25, x16, x24, LSL #18 + __ addw(r8, r5, r28, Assembler::LSL, 7); // add w8, w5, w28, LSL #7 + __ subw(r8, r28, r1, Assembler::ASR, 28); // sub w8, w28, w1, ASR #28 + __ addsw(r12, r2, r1, Assembler::LSL, 0); // adds w12, w2, w1, LSL #0 + __ subsw(r23, r5, r17, Assembler::LSR, 25); // subs w23, w5, w17, LSR #25 + __ andr(r21, r12, r13, Assembler::LSL, 21); // and x21, x12, x13, LSL #21 + __ orr(r21, r15, r23, Assembler::ASR, 36); // orr x21, x15, x23, ASR #36 + __ eor(r22, r24, r27, Assembler::ASR, 48); // eor x22, x24, x27, ASR #48 + __ ands(r22, r15, r2, Assembler::ASR, 52); // ands x22, x15, x2, ASR #52 + __ andw(r1, r17, r24, Assembler::ASR, 3); // and w1, w17, w24, ASR #3 + __ orrw(r5, r2, r6, Assembler::ASR, 11); // orr w5, w2, w6, ASR #11 + __ eorw(r23, r1, r5, Assembler::LSR, 12); // eor w23, w1, w5, LSR #12 + __ andsw(r0, r12, r14, Assembler::ASR, 20); // ands w0, w12, w14, ASR #20 + __ bic(r1, r6, r2, Assembler::LSR, 7); // bic x1, x6, x2, LSR #7 + __ orn(r30, r8, r4, Assembler::LSL, 47); // orn x30, x8, x4, LSL #47 + __ eon(r17, r22, r20, Assembler::ASR, 53); // eon x17, x22, x20, ASR #53 + __ bics(r29, r15, r5, Assembler::ASR, 36); // bics x29, x15, x5, ASR #36 + __ bicw(r30, r23, r29, Assembler::LSR, 27); // bic w30, w23, w29, LSR #27 + __ ornw(r12, r29, r2, Assembler::LSL, 20); // orn w12, w29, w2, LSL #20 + __ eonw(r7, r12, r6, Assembler::ASR, 4); // eon w7, w12, w6, ASR #4 + __ bicsw(r16, r13, r7, Assembler::ASR, 21); // bics w16, w13, w7, ASR #21 // AddSubImmOp - __ addw(r4, r20, 660u); // add w4, w20, #660 - __ addsw(r2, r10, 710u); // adds w2, w10, #710 - __ subw(r19, r26, 244u); // sub w19, w26, #244 - __ subsw(r28, r13, 73u); // subs w28, w13, #73 - __ add(r2, r30, 862u); // add x2, x30, #862 - __ adds(r27, r16, 574u); // adds x27, x16, #574 - __ sub(r22, r9, 589u); // sub x22, x9, #589 - __ subs(r4, r1, 698u); // subs x4, x1, #698 + __ addw(r5, r17, 726u); // add w5, w17, #726 + __ addsw(r10, r16, 347u); // adds w10, w16, #347 + __ subw(r26, r5, 978u); // sub w26, w5, #978 + __ subsw(r21, r24, 689u); // subs w21, w24, #689 + __ add(r10, r16, 987u); // add x10, x16, #987 + __ adds(r15, r15, 665u); // adds x15, x15, #665 + __ sub(r24, r20, 39u); // sub x24, x20, #39 + __ subs(r10, r13, 76u); // subs x10, x13, #76 // LogicalImmOp - __ andw(r28, r19, 4294709247ull); // and w28, w19, #0xfffc0fff - __ orrw(r27, r5, 536870910ull); // orr w27, w5, #0x1ffffffe - __ eorw(r30, r20, 4294840319ull); // eor w30, w20, #0xfffe0fff - __ andsw(r22, r26, 4294959615ull); // ands w22, w26, #0xffffe1ff - __ andr(r5, r7, 4194300ull); // and x5, x7, #0x3ffffc - __ orr(r13, r7, 18014398509481728ull); // orr x13, x7, #0x3fffffffffff00 - __ eor(r7, r9, 18442240474082197503ull); // eor x7, x9, #0xfff0000000003fff - __ ands(r3, r0, 18374686479671656447ull); // ands x3, x0, #0xff00000000007fff + __ andw(r7, r19, 8388600ull); // and w7, w19, #0x7ffff8 + __ orrw(r5, r17, 4026535935ull); // orr w5, w17, #0xf0000fff + __ eorw(r16, r28, 4186112ull); // eor w16, w28, #0x3fe000 + __ andsw(r14, r24, 7168ull); // ands w14, w24, #0x1c00 + __ andr(r14, r27, 18446744073709543551ull); // and x14, x27, #0xffffffffffffe07f + __ orr(r12, r11, 576456354256912384ull); // orr x12, x11, #0x7fffc0000000000 + __ eor(r2, r0, 18437736874454811647ull); // eor x2, x0, #0xffe00000000003ff + __ ands(r13, r20, 18446744073642573823ull); // ands x13, x20, #0xfffffffffc01ffff // AbsOp - __ b(__ pc()); // b . - __ b(back); // b back - __ b(forth); // b forth - __ bl(__ pc()); // bl . - __ bl(back); // bl back - __ bl(forth); // bl forth + __ b(__ pc()); // b . + __ b(back); // b back + __ b(forth); // b forth + __ bl(__ pc()); // bl . + __ bl(back); // bl back + __ bl(forth); // bl forth // RegAndAbsOp - __ cbzw(r16, __ pc()); // cbz w16, . - __ cbzw(r16, back); // cbz w16, back - __ cbzw(r16, forth); // cbz w16, forth - __ cbnzw(r19, __ pc()); // cbnz w19, . - __ cbnzw(r19, back); // cbnz w19, back - __ cbnzw(r19, forth); // cbnz w19, forth - __ cbz(r5, __ pc()); // cbz x5, . - __ cbz(r5, back); // cbz x5, back - __ cbz(r5, forth); // cbz x5, forth - __ cbnz(r4, __ pc()); // cbnz x4, . - __ cbnz(r4, back); // cbnz x4, back - __ cbnz(r4, forth); // cbnz x4, forth - __ adr(r27, __ pc()); // adr x27, . - __ adr(r27, back); // adr x27, back - __ adr(r27, forth); // adr x27, forth - __ _adrp(r16, __ pc()); // adrp x16, . + __ cbzw(r15, __ pc()); // cbz w15, . + __ cbzw(r15, back); // cbz w15, back + __ cbzw(r15, forth); // cbz w15, forth + __ cbnzw(r28, __ pc()); // cbnz w28, . + __ cbnzw(r28, back); // cbnz w28, back + __ cbnzw(r28, forth); // cbnz w28, forth + __ cbz(r27, __ pc()); // cbz x27, . + __ cbz(r27, back); // cbz x27, back + __ cbz(r27, forth); // cbz x27, forth + __ cbnz(r0, __ pc()); // cbnz x0, . + __ cbnz(r0, back); // cbnz x0, back + __ cbnz(r0, forth); // cbnz x0, forth + __ adr(r13, __ pc()); // adr x13, . + __ adr(r13, back); // adr x13, back + __ adr(r13, forth); // adr x13, forth + __ _adrp(r3, __ pc()); // adrp x3, . // RegImmAbsOp - __ tbz(r28, 8, __ pc()); // tbz x28, #8, . - __ tbz(r28, 8, back); // tbz x28, #8, back - __ tbz(r28, 8, forth); // tbz x28, #8, forth - __ tbnz(r1, 1, __ pc()); // tbnz x1, #1, . - __ tbnz(r1, 1, back); // tbnz x1, #1, back - __ tbnz(r1, 1, forth); // tbnz x1, #1, forth + __ tbz(r21, 7, __ pc()); // tbz x21, #7, . + __ tbz(r21, 7, back); // tbz x21, #7, back + __ tbz(r21, 7, forth); // tbz x21, #7, forth + __ tbnz(r15, 9, __ pc()); // tbnz x15, #9, . + __ tbnz(r15, 9, back); // tbnz x15, #9, back + __ tbnz(r15, 9, forth); // tbnz x15, #9, forth // MoveWideImmOp - __ movnw(r20, 8639, 16); // movn w20, #8639, lsl 16 - __ movzw(r7, 25835, 0); // movz w7, #25835, lsl 0 - __ movkw(r17, 7261, 0); // movk w17, #7261, lsl 0 - __ movn(r14, 2097, 32); // movn x14, #2097, lsl 32 - __ movz(r9, 16082, 0); // movz x9, #16082, lsl 0 - __ movk(r19, 13962, 16); // movk x19, #13962, lsl 16 + __ movnw(r14, 2655, 16); // movn w14, #2655, lsl 16 + __ movzw(r17, 7642, 0); // movz w17, #7642, lsl 0 + __ movkw(r27, 11381, 0); // movk w27, #11381, lsl 0 + __ movn(r1, 19524, 32); // movn x1, #19524, lsl 32 + __ movz(r20, 21126, 16); // movz x20, #21126, lsl 16 + __ movk(r20, 32462, 16); // movk x20, #32462, lsl 16 // BitfieldOp - __ sbfm(r9, r22, 6, 22); // sbfm x9, x22, #6, #22 - __ bfmw(r19, r0, 11, 0); // bfm w19, w0, #11, #0 - __ ubfmw(r10, r19, 11, 19); // ubfm w10, w19, #11, #19 - __ sbfm(r4, r15, 5, 17); // sbfm x4, x15, #5, #17 - __ bfm(r3, r5, 19, 28); // bfm x3, x5, #19, #28 - __ ubfm(r12, r28, 17, 2); // ubfm x12, x28, #17, #2 + __ sbfm(r13, r2, 28, 20); // sbfm x13, x2, #28, #20 + __ bfmw(r16, r20, 19, 15); // bfm w16, w20, #19, #15 + __ ubfmw(r11, r11, 9, 6); // ubfm w11, w11, #9, #6 + __ sbfm(r2, r4, 25, 21); // sbfm x2, x4, #25, #21 + __ bfm(r13, r16, 2, 19); // bfm x13, x16, #2, #19 + __ ubfm(r8, r25, 8, 5); // ubfm x8, x25, #8, #5 // ExtractOp - __ extrw(r15, r0, r22, 3); // extr w15, w0, w22, #3 - __ extr(r6, r14, r14, 55); // extr x6, x14, x14, #55 + __ extrw(r29, r27, r10, 14); // extr w29, w27, w10, #14 + __ extr(r6, r20, r6, 24); // extr x6, x20, x6, #24 // CondBranchOp - __ br(Assembler::EQ, __ pc()); // b.EQ . - __ br(Assembler::EQ, back); // b.EQ back - __ br(Assembler::EQ, forth); // b.EQ forth - __ br(Assembler::NE, __ pc()); // b.NE . - __ br(Assembler::NE, back); // b.NE back - __ br(Assembler::NE, forth); // b.NE forth - __ br(Assembler::HS, __ pc()); // b.HS . - __ br(Assembler::HS, back); // b.HS back - __ br(Assembler::HS, forth); // b.HS forth - __ br(Assembler::CS, __ pc()); // b.CS . - __ br(Assembler::CS, back); // b.CS back - __ br(Assembler::CS, forth); // b.CS forth - __ br(Assembler::LO, __ pc()); // b.LO . - __ br(Assembler::LO, back); // b.LO back - __ br(Assembler::LO, forth); // b.LO forth - __ br(Assembler::CC, __ pc()); // b.CC . - __ br(Assembler::CC, back); // b.CC back - __ br(Assembler::CC, forth); // b.CC forth - __ br(Assembler::MI, __ pc()); // b.MI . - __ br(Assembler::MI, back); // b.MI back - __ br(Assembler::MI, forth); // b.MI forth - __ br(Assembler::PL, __ pc()); // b.PL . - __ br(Assembler::PL, back); // b.PL back - __ br(Assembler::PL, forth); // b.PL forth - __ br(Assembler::VS, __ pc()); // b.VS . - __ br(Assembler::VS, back); // b.VS back - __ br(Assembler::VS, forth); // b.VS forth - __ br(Assembler::VC, __ pc()); // b.VC . - __ br(Assembler::VC, back); // b.VC back - __ br(Assembler::VC, forth); // b.VC forth - __ br(Assembler::HI, __ pc()); // b.HI . - __ br(Assembler::HI, back); // b.HI back - __ br(Assembler::HI, forth); // b.HI forth - __ br(Assembler::LS, __ pc()); // b.LS . - __ br(Assembler::LS, back); // b.LS back - __ br(Assembler::LS, forth); // b.LS forth - __ br(Assembler::GE, __ pc()); // b.GE . - __ br(Assembler::GE, back); // b.GE back - __ br(Assembler::GE, forth); // b.GE forth - __ br(Assembler::LT, __ pc()); // b.LT . - __ br(Assembler::LT, back); // b.LT back - __ br(Assembler::LT, forth); // b.LT forth - __ br(Assembler::GT, __ pc()); // b.GT . - __ br(Assembler::GT, back); // b.GT back - __ br(Assembler::GT, forth); // b.GT forth - __ br(Assembler::LE, __ pc()); // b.LE . - __ br(Assembler::LE, back); // b.LE back - __ br(Assembler::LE, forth); // b.LE forth - __ br(Assembler::AL, __ pc()); // b.AL . - __ br(Assembler::AL, back); // b.AL back - __ br(Assembler::AL, forth); // b.AL forth - __ br(Assembler::NV, __ pc()); // b.NV . - __ br(Assembler::NV, back); // b.NV back - __ br(Assembler::NV, forth); // b.NV forth + __ br(Assembler::EQ, __ pc()); // b.EQ . + __ br(Assembler::EQ, back); // b.EQ back + __ br(Assembler::EQ, forth); // b.EQ forth + __ br(Assembler::NE, __ pc()); // b.NE . + __ br(Assembler::NE, back); // b.NE back + __ br(Assembler::NE, forth); // b.NE forth + __ br(Assembler::HS, __ pc()); // b.HS . + __ br(Assembler::HS, back); // b.HS back + __ br(Assembler::HS, forth); // b.HS forth + __ br(Assembler::CS, __ pc()); // b.CS . + __ br(Assembler::CS, back); // b.CS back + __ br(Assembler::CS, forth); // b.CS forth + __ br(Assembler::LO, __ pc()); // b.LO . + __ br(Assembler::LO, back); // b.LO back + __ br(Assembler::LO, forth); // b.LO forth + __ br(Assembler::CC, __ pc()); // b.CC . + __ br(Assembler::CC, back); // b.CC back + __ br(Assembler::CC, forth); // b.CC forth + __ br(Assembler::MI, __ pc()); // b.MI . + __ br(Assembler::MI, back); // b.MI back + __ br(Assembler::MI, forth); // b.MI forth + __ br(Assembler::PL, __ pc()); // b.PL . + __ br(Assembler::PL, back); // b.PL back + __ br(Assembler::PL, forth); // b.PL forth + __ br(Assembler::VS, __ pc()); // b.VS . + __ br(Assembler::VS, back); // b.VS back + __ br(Assembler::VS, forth); // b.VS forth + __ br(Assembler::VC, __ pc()); // b.VC . + __ br(Assembler::VC, back); // b.VC back + __ br(Assembler::VC, forth); // b.VC forth + __ br(Assembler::HI, __ pc()); // b.HI . + __ br(Assembler::HI, back); // b.HI back + __ br(Assembler::HI, forth); // b.HI forth + __ br(Assembler::LS, __ pc()); // b.LS . + __ br(Assembler::LS, back); // b.LS back + __ br(Assembler::LS, forth); // b.LS forth + __ br(Assembler::GE, __ pc()); // b.GE . + __ br(Assembler::GE, back); // b.GE back + __ br(Assembler::GE, forth); // b.GE forth + __ br(Assembler::LT, __ pc()); // b.LT . + __ br(Assembler::LT, back); // b.LT back + __ br(Assembler::LT, forth); // b.LT forth + __ br(Assembler::GT, __ pc()); // b.GT . + __ br(Assembler::GT, back); // b.GT back + __ br(Assembler::GT, forth); // b.GT forth + __ br(Assembler::LE, __ pc()); // b.LE . + __ br(Assembler::LE, back); // b.LE back + __ br(Assembler::LE, forth); // b.LE forth + __ br(Assembler::AL, __ pc()); // b.AL . + __ br(Assembler::AL, back); // b.AL back + __ br(Assembler::AL, forth); // b.AL forth + __ br(Assembler::NV, __ pc()); // b.NV . + __ br(Assembler::NV, back); // b.NV back + __ br(Assembler::NV, forth); // b.NV forth // ImmOp - __ svc(22064); // svc #22064 - __ hvc(533); // hvc #533 - __ smc(9942); // smc #9942 - __ brk(4714); // brk #4714 - __ hlt(4302); // hlt #4302 + __ svc(26948); // svc #26948 + __ hvc(29998); // hvc #29998 + __ smc(10437); // smc #10437 + __ brk(30290); // brk #30290 + __ hlt(20851); // hlt #20851 // Op - __ nop(); // nop - __ eret(); // eret - __ drps(); // drps - __ isb(); // isb + __ nop(); // nop + __ eret(); // eret + __ drps(); // drps + __ isb(); // isb // SystemOp - __ dsb(Assembler::OSH); // dsb OSH - __ dmb(Assembler::NSHLD); // dmb NSHLD + __ dsb(Assembler::LD); // dsb LD + __ dmb(Assembler::ISH); // dmb ISH // OneRegOp - __ br(r20); // br x20 - __ blr(r2); // blr x2 + __ br(r9); // br x9 + __ blr(r9); // blr x9 // LoadStoreExclusiveOp - __ stxr(r18, r23, r0); // stxr w18, x23, [x0] - __ stlxr(r30, r5, r22); // stlxr w30, x5, [x22] - __ ldxr(r5, r8); // ldxr x5, [x8] - __ ldaxr(r20, r16); // ldaxr x20, [x16] - __ stlr(r6, r11); // stlr x6, [x11] - __ ldar(r6, r27); // ldar x6, [x27] + __ stxr(r2, r29, r11); // stxr w2, x29, [x11] + __ stlxr(r22, r5, r28); // stlxr w22, x5, [x28] + __ ldxr(r14, r20); // ldxr x14, [x20] + __ ldaxr(r29, r19); // ldaxr x29, [x19] + __ stlr(r6, r21); // stlr x6, [x21] + __ ldar(r19, r3); // ldar x19, [x3] // LoadStoreExclusiveOp - __ stxrw(r10, r17, r5); // stxr w10, w17, [x5] - __ stlxrw(r22, r9, r12); // stlxr w22, w9, [x12] - __ ldxrw(r27, r8); // ldxr w27, [x8] - __ ldaxrw(r23, r2); // ldaxr w23, [x2] - __ stlrw(r26, r29); // stlr w26, [x29] - __ ldarw(r13, r10); // ldar w13, [x10] + __ stxrw(r12, r3, r27); // stxr w12, w3, [x27] + __ stlxrw(r17, r26, r15); // stlxr w17, w26, [x15] + __ ldxrw(r13, r14); // ldxr w13, [x14] + __ ldaxrw(r12, r26); // ldaxr w12, [x26] + __ stlrw(r8, r17); // stlr w8, [x17] + __ ldarw(r21, r30); // ldar w21, [x30] // LoadStoreExclusiveOp - __ stxrh(r25, r28, r27); // stxrh w25, w28, [x27] - __ stlxrh(r29, r22, r12); // stlxrh w29, w22, [x12] - __ ldxrh(r22, r28); // ldxrh w22, [x28] - __ ldaxrh(r3, r30); // ldaxrh w3, [x30] - __ stlrh(r24, r15); // stlrh w24, [x15] - __ ldarh(r27, r26); // ldarh w27, [x26] + __ stxrh(r0, r15, r11); // stxrh w0, w15, [x11] + __ stlxrh(r17, r20, r1); // stlxrh w17, w20, [x1] + __ ldxrh(r29, r8); // ldxrh w29, [x8] + __ ldaxrh(r17, r12); // ldaxrh w17, [x12] + __ stlrh(r11, r4); // stlrh w11, [x4] + __ ldarh(r16, r4); // ldarh w16, [x4] // LoadStoreExclusiveOp - __ stxrb(r11, r10, r19); // stxrb w11, w10, [x19] - __ stlxrb(r23, r27, r22); // stlxrb w23, w27, [x22] - __ ldxrb(r24, r16); // ldxrb w24, [x16] - __ ldaxrb(r24, r1); // ldaxrb w24, [x1] - __ stlrb(r5, r29); // stlrb w5, [x29] - __ ldarb(r24, r16); // ldarb w24, [x16] + __ stxrb(r14, r5, r4); // stxrb w14, w5, [x4] + __ stlxrb(r27, r17, r16); // stlxrb w27, w17, [x16] + __ ldxrb(r6, r27); // ldxrb w6, [x27] + __ ldaxrb(r27, r24); // ldaxrb w27, [x24] + __ stlrb(r10, r20); // stlrb w10, [x20] + __ ldarb(r9, r26); // ldarb w9, [x26] // LoadStoreExclusiveOp - __ ldxp(r25, r24, r17); // ldxp x25, x24, [x17] - __ ldaxp(r22, r12, r19); // ldaxp x22, x12, [x19] - __ stxp(r0, r26, r21, r25); // stxp w0, x26, x21, [x25] - __ stlxp(r1, r6, r11, r5); // stlxp w1, x6, x11, [x5] + __ ldxp(r5, r30, r28); // ldxp x5, x30, [x28] + __ ldaxp(r10, r9, r19); // ldaxp x10, x9, [x19] + __ stxp(r11, r16, r21, r12); // stxp w11, x16, x21, [x12] + __ stlxp(r10, r20, r23, r4); // stlxp w10, x20, x23, [x4] // LoadStoreExclusiveOp - __ ldxpw(r13, r14, r4); // ldxp w13, w14, [x4] - __ ldaxpw(r17, r2, r6); // ldaxp w17, w2, [x6] - __ stxpw(r15, r3, r9, r18); // stxp w15, w3, w9, [x18] - __ stlxpw(r18, r17, r4, r9); // stlxp w18, w17, w4, [x9] + __ ldxpw(r22, r1, r0); // ldxp w22, w1, [x0] + __ ldaxpw(r3, r1, r8); // ldaxp w3, w1, [x8] + __ stxpw(r0, r9, r23, r30); // stxp w0, w9, w23, [x30] + __ stlxpw(r23, r0, r17, r11); // stlxp w23, w0, w17, [x11] // base_plus_unscaled_offset // LoadStoreOp - __ str(r23, Address(r21, -49)); // str x23, [x21, -49] - __ strw(r21, Address(r2, 63)); // str w21, [x2, 63] - __ strb(r27, Address(r28, 11)); // strb w27, [x28, 11] - __ strh(r29, Address(r15, -13)); // strh w29, [x15, -13] - __ ldr(r14, Address(r30, -45)); // ldr x14, [x30, -45] - __ ldrw(r29, Address(r28, 53)); // ldr w29, [x28, 53] - __ ldrb(r20, Address(r26, 7)); // ldrb w20, [x26, 7] - __ ldrh(r25, Address(r2, -50)); // ldrh w25, [x2, -50] - __ ldrsb(r3, Address(r10, -15)); // ldrsb x3, [x10, -15] - __ ldrsh(r14, Address(r15, 19)); // ldrsh x14, [x15, 19] - __ ldrshw(r29, Address(r11, -5)); // ldrsh w29, [x11, -5] - __ ldrsw(r15, Address(r5, -71)); // ldrsw x15, [x5, -71] - __ ldrd(v19, Address(r12, 3)); // ldr d19, [x12, 3] - __ ldrs(v12, Address(r27, 42)); // ldr s12, [x27, 42] - __ strd(v22, Address(r28, 125)); // str d22, [x28, 125] - __ strs(v24, Address(r15, -20)); // str s24, [x15, -20] + __ str(r6, Address(r10, -31)); // str x6, [x10, -31] + __ strw(r7, Address(r0, -5)); // str w7, [x0, -5] + __ strb(r5, Address(r16, -13)); // strb w5, [x16, -13] + __ strh(r30, Address(r19, 31)); // strh w30, [x19, 31] + __ ldr(r16, Address(r9, 119)); // ldr x16, [x9, 119] + __ ldrw(r8, Address(r16, 59)); // ldr w8, [x16, 59] + __ ldrb(r10, Address(r12, -7)); // ldrb w10, [x12, -7] + __ ldrh(r14, Address(r9, -38)); // ldrh w14, [x9, -38] + __ ldrsb(r24, Address(r30, -8)); // ldrsb x24, [x30, -8] + __ ldrsh(r7, Address(r4, 23)); // ldrsh x7, [x4, 23] + __ ldrshw(r17, Address(r14, -39)); // ldrsh w17, [x14, -39] + __ ldrsw(r11, Address(r27, -31)); // ldrsw x11, [x27, -31] + __ ldrd(v12, Address(r7, 65)); // ldr d12, [x7, 65] + __ ldrs(v0, Address(r16, -2)); // ldr s0, [x16, -2] + __ strd(v13, Address(r23, -161)); // str d13, [x23, -161] + __ strs(v21, Address(r3, -62)); // str s21, [x3, -62] // pre // LoadStoreOp - __ str(r8, Address(__ pre(r28, -24))); // str x8, [x28, -24]! - __ strw(r6, Address(__ pre(r15, 37))); // str w6, [x15, 37]! - __ strb(r7, Address(__ pre(r1, 7))); // strb w7, [x1, 7]! - __ strh(r0, Address(__ pre(r17, 30))); // strh w0, [x17, 30]! - __ ldr(r25, Address(__ pre(r29, 84))); // ldr x25, [x29, 84]! - __ ldrw(r26, Address(__ pre(r20, -52))); // ldr w26, [x20, -52]! - __ ldrb(r26, Address(__ pre(r29, -25))); // ldrb w26, [x29, -25]! - __ ldrh(r4, Address(__ pre(r25, 26))); // ldrh w4, [x25, 26]! - __ ldrsb(r28, Address(__ pre(r8, -21))); // ldrsb x28, [x8, -21]! - __ ldrsh(r17, Address(__ pre(r14, -6))); // ldrsh x17, [x14, -6]! - __ ldrshw(r28, Address(__ pre(r23, 10))); // ldrsh w28, [x23, 10]! - __ ldrsw(r30, Address(__ pre(r27, -64))); // ldrsw x30, [x27, -64]! - __ ldrd(v20, Address(__ pre(r30, -242))); // ldr d20, [x30, -242]! - __ ldrs(v17, Address(__ pre(r27, 20))); // ldr s17, [x27, 20]! - __ strd(v7, Address(__ pre(r3, 17))); // str d7, [x3, 17]! - __ strs(v13, Address(__ pre(r11, -16))); // str s13, [x11, -16]! + __ str(r2, Address(__ pre(r5, 100))); // str x2, [x5, 100]! + __ strw(r9, Address(__ pre(r1, -92))); // str w9, [x1, -92]! + __ strb(r27, Address(__ pre(r30, -5))); // strb w27, [x30, -5]! + __ strh(r27, Address(__ pre(r15, 12))); // strh w27, [x15, 12]! + __ ldr(r4, Address(__ pre(r17, -212))); // ldr x4, [x17, -212]! + __ ldrw(r21, Address(__ pre(r23, 30))); // ldr w21, [x23, 30]! + __ ldrb(r13, Address(__ pre(r17, -7))); // ldrb w13, [x17, -7]! + __ ldrh(r25, Address(__ pre(r0, -50))); // ldrh w25, [x0, -50]! + __ ldrsb(r1, Address(__ pre(r21, -21))); // ldrsb x1, [x21, -21]! + __ ldrsh(r28, Address(__ pre(r21, -54))); // ldrsh x28, [x21, -54]! + __ ldrshw(r11, Address(__ pre(r4, 2))); // ldrsh w11, [x4, 2]! + __ ldrsw(r17, Address(__ pre(r9, 61))); // ldrsw x17, [x9, 61]! + __ ldrd(v29, Address(__ pre(r19, 39))); // ldr d29, [x19, 39]! + __ ldrs(v22, Address(__ pre(r22, -85))); // ldr s22, [x22, -85]! + __ strd(v9, Address(__ pre(r25, -225))); // str d9, [x25, -225]! + __ strs(v9, Address(__ pre(r2, -15))); // str s9, [x2, -15]! // post // LoadStoreOp - __ str(r6, Address(__ post(r9, -61))); // str x6, [x9], -61 - __ strw(r16, Address(__ post(r5, -29))); // str w16, [x5], -29 - __ strb(r29, Address(__ post(r29, 15))); // strb w29, [x29], 15 - __ strh(r4, Address(__ post(r20, 18))); // strh w4, [x20], 18 - __ ldr(r19, Address(__ post(r18, 46))); // ldr x19, [x18], 46 - __ ldrw(r22, Address(__ post(r2, 23))); // ldr w22, [x2], 23 - __ ldrb(r7, Address(__ post(r3, -30))); // ldrb w7, [x3], -30 - __ ldrh(r11, Address(__ post(r12, -29))); // ldrh w11, [x12], -29 - __ ldrsb(r8, Address(__ post(r6, -29))); // ldrsb x8, [x6], -29 - __ ldrsh(r24, Address(__ post(r23, 4))); // ldrsh x24, [x23], 4 - __ ldrshw(r17, Address(__ post(r16, 0))); // ldrsh w17, [x16], 0 - __ ldrsw(r0, Address(__ post(r20, -8))); // ldrsw x0, [x20], -8 - __ ldrd(v20, Address(__ post(r2, -126))); // ldr d20, [x2], -126 - __ ldrs(v19, Address(__ post(r30, -104))); // ldr s19, [x30], -104 - __ strd(v4, Address(__ post(r17, 118))); // str d4, [x17], 118 - __ strs(v21, Address(__ post(r19, -112))); // str s21, [x19], -112 + __ str(r13, Address(__ post(r23, -66))); // str x13, [x23], -66 + __ strw(r17, Address(__ post(r16, 10))); // str w17, [x16], 10 + __ strb(r1, Address(__ post(r14, -32))); // strb w1, [x14], -32 + __ strh(r17, Address(__ post(r0, 6))); // strh w17, [x0], 6 + __ ldr(r27, Address(__ post(r25, -172))); // ldr x27, [x25], -172 + __ ldrw(r13, Address(__ post(r25, -38))); // ldr w13, [x25], -38 + __ ldrb(r11, Address(__ post(r25, -29))); // ldrb w11, [x25], -29 + __ ldrh(r30, Address(__ post(r5, 20))); // ldrh w30, [x5], 20 + __ ldrsb(r9, Address(__ post(r7, -7))); // ldrsb x9, [x7], -7 + __ ldrsh(r0, Address(__ post(r3, -62))); // ldrsh x0, [x3], -62 + __ ldrshw(r7, Address(__ post(r14, 31))); // ldrsh w7, [x14], 31 + __ ldrsw(r17, Address(__ post(r27, 39))); // ldrsw x17, [x27], 39 + __ ldrd(v17, Address(__ post(r4, -235))); // ldr d17, [x4], -235 + __ ldrs(v26, Address(__ post(r21, 34))); // ldr s26, [x21], 34 + __ strd(v5, Address(__ post(r17, -57))); // str d5, [x17], -57 + __ strs(v13, Address(__ post(r13, -109))); // str s13, [x13], -109 // base_plus_reg // LoadStoreOp - __ str(r26, Address(r2, r19, Address::lsl(3))); // str x26, [x2, x19, lsl #3] - __ strw(r9, Address(r0, r15, Address::sxtw(2))); // str w9, [x0, w15, sxtw #2] - __ strb(r26, Address(r12, r1, Address::lsl(0))); // strb w26, [x12, x1, lsl #0] - __ strh(r21, Address(r11, r10, Address::lsl(1))); // strh w21, [x11, x10, lsl #1] - __ ldr(r16, Address(r23, r16, Address::sxtx(0))); // ldr x16, [x23, x16, sxtx #0] - __ ldrw(r10, Address(r11, r17, Address::sxtw(2))); // ldr w10, [x11, w17, sxtw #2] - __ ldrb(r13, Address(r23, r11, Address::lsl(0))); // ldrb w13, [x23, x11, lsl #0] - __ ldrh(r27, Address(r4, r21, Address::lsl(0))); // ldrh w27, [x4, x21, lsl #0] - __ ldrsb(r26, Address(r8, r15, Address::sxtw(0))); // ldrsb x26, [x8, w15, sxtw #0] - __ ldrsh(r21, Address(r10, r2, Address::sxtw(0))); // ldrsh x21, [x10, w2, sxtw #0] - __ ldrshw(r8, Address(r30, r14, Address::lsl(0))); // ldrsh w8, [x30, x14, lsl #0] - __ ldrsw(r29, Address(r14, r20, Address::sxtx(2))); // ldrsw x29, [x14, x20, sxtx #2] - __ ldrd(v30, Address(r27, r22, Address::sxtx(0))); // ldr d30, [x27, x22, sxtx #0] - __ ldrs(v13, Address(r9, r22, Address::lsl(0))); // ldr s13, [x9, x22, lsl #0] - __ strd(v8, Address(r25, r17, Address::sxtw(3))); // str d8, [x25, w17, sxtw #3] - __ strs(v1, Address(r24, r5, Address::uxtw(2))); // str s1, [x24, w5, uxtw #2] + __ str(r6, Address(r16, r4, Address::sxtw(3))); // str x6, [x16, w4, sxtw #3] + __ strw(r9, Address(r24, r20, Address::sxtw(2))); // str w9, [x24, w20, sxtw #2] + __ strb(r3, Address(r29, r3, Address::lsl(0))); // strb w3, [x29, x3, lsl #0] + __ strh(r10, Address(r17, r30, Address::lsl(0))); // strh w10, [x17, x30, lsl #0] + __ ldr(r27, Address(r11, r7, Address::uxtw(0))); // ldr x27, [x11, w7, uxtw #0] + __ ldrw(r14, Address(r15, r25, Address::uxtw(0))); // ldr w14, [x15, w25, uxtw #0] + __ ldrb(r24, Address(r14, r19, Address::lsl(0))); // ldrb w24, [x14, x19, lsl #0] + __ ldrh(r16, Address(r0, r6, Address::sxtw(0))); // ldrh w16, [x0, w6, sxtw #0] + __ ldrsb(r10, Address(r12, r12, Address::sxtw(0))); // ldrsb x10, [x12, w12, sxtw #0] + __ ldrsh(r26, Address(r12, r16, Address::uxtw(0))); // ldrsh x26, [x12, w16, uxtw #0] + __ ldrshw(r26, Address(r0, r14, Address::lsl(1))); // ldrsh w26, [x0, x14, lsl #1] + __ ldrsw(r17, Address(r11, r27, Address::sxtx(2))); // ldrsw x17, [x11, x27, sxtx #2] + __ ldrd(v3, Address(r0, r19, Address::sxtw(3))); // ldr d3, [x0, w19, sxtw #3] + __ ldrs(v26, Address(r15, r9, Address::lsl(2))); // ldr s26, [x15, x9, lsl #2] + __ strd(v11, Address(r13, r16, Address::sxtx(0))); // str d11, [x13, x16, sxtx #0] + __ strs(v26, Address(r19, r21, Address::uxtw(2))); // str s26, [x19, w21, uxtw #2] // base_plus_scaled_offset // LoadStoreOp - __ str(r10, Address(r21, 14496)); // str x10, [x21, 14496] - __ strw(r18, Address(r29, 7228)); // str w18, [x29, 7228] - __ strb(r23, Address(r3, 2018)); // strb w23, [x3, 2018] - __ strh(r28, Address(r11, 3428)); // strh w28, [x11, 3428] - __ ldr(r24, Address(r26, 14376)); // ldr x24, [x26, 14376] - __ ldrw(r21, Address(r2, 6972)); // ldr w21, [x2, 6972] - __ ldrb(r4, Address(r5, 1848)); // ldrb w4, [x5, 1848] - __ ldrh(r14, Address(r14, 3112)); // ldrh w14, [x14, 3112] - __ ldrsb(r4, Address(r27, 1959)); // ldrsb x4, [x27, 1959] - __ ldrsh(r4, Address(r27, 3226)); // ldrsh x4, [x27, 3226] - __ ldrshw(r10, Address(r28, 3286)); // ldrsh w10, [x28, 3286] - __ ldrsw(r10, Address(r17, 7912)); // ldrsw x10, [x17, 7912] - __ ldrd(v13, Address(r28, 13400)); // ldr d13, [x28, 13400] - __ ldrs(v24, Address(r3, 7596)); // ldr s24, [x3, 7596] - __ strd(v2, Address(r12, 15360)); // str d2, [x12, 15360] - __ strs(v17, Address(r1, 6492)); // str s17, [x1, 6492] + __ str(r8, Address(r21, 12552)); // str x8, [x21, 12552] + __ strw(r10, Address(r27, 6380)); // str w10, [x27, 6380] + __ strb(r27, Address(r14, 1733)); // strb w27, [x14, 1733] + __ strh(r16, Address(r7, 3424)); // strh w16, [x7, 3424] + __ ldr(r27, Address(r9, 12520)); // ldr x27, [x9, 12520] + __ ldrw(r24, Address(r10, 6680)); // ldr w24, [x10, 6680] + __ ldrb(r24, Address(r24, 1743)); // ldrb w24, [x24, 1743] + __ ldrh(r20, Address(r5, 3072)); // ldrh w20, [x5, 3072] + __ ldrsb(r17, Address(r4, 1570)); // ldrsb x17, [x4, 1570] + __ ldrsh(r14, Address(r13, 3392)); // ldrsh x14, [x13, 3392] + __ ldrshw(r10, Address(r25, 3722)); // ldrsh w10, [x25, 3722] + __ ldrsw(r2, Address(r26, 6160)); // ldrsw x2, [x26, 6160] + __ ldrd(v26, Address(r14, 14912)); // ldr d26, [x14, 14912] + __ ldrs(v28, Address(r4, 7804)); // ldr s28, [x4, 7804] + __ strd(v14, Address(r19, 13984)); // str d14, [x19, 13984] + __ strs(v23, Address(r28, 6364)); // str s23, [x28, 6364] // pcrel // LoadStoreOp - __ ldr(r16, __ pc()); // ldr x16, . - __ ldrw(r13, __ pc()); // ldr w13, . + __ ldr(r8, forth); // ldr x8, forth + __ ldrw(r17, back); // ldr w17, back // LoadStoreOp - __ prfm(Address(r18, -127)); // prfm PLDL1KEEP, [x18, -127] + __ prfm(Address(r4, -175)); // prfm PLDL1KEEP, [x4, -175] // LoadStoreOp - __ prfm(back); // prfm PLDL1KEEP, back + __ prfm(__ pc()); // prfm PLDL1KEEP, . // LoadStoreOp - __ prfm(Address(r20, r2, Address::lsl(3))); // prfm PLDL1KEEP, [x20, x2, lsl #3] + __ prfm(Address(r8, r4, Address::sxtw(0))); // prfm PLDL1KEEP, [x8, w4, sxtw #0] // LoadStoreOp - __ prfm(Address(r9, 13808)); // prfm PLDL1KEEP, [x9, 13808] + __ prfm(Address(r12, 13248)); // prfm PLDL1KEEP, [x12, 13248] // AddSubCarryOp - __ adcw(r8, r23, r2); // adc w8, w23, w2 - __ adcsw(r24, r3, r19); // adcs w24, w3, w19 - __ sbcw(r22, r24, r29); // sbc w22, w24, w29 - __ sbcsw(r12, r27, r3); // sbcs w12, w27, w3 - __ adc(r11, r23, r1); // adc x11, x23, x1 - __ adcs(r29, r5, r23); // adcs x29, x5, x23 - __ sbc(r9, r25, r12); // sbc x9, x25, x12 - __ sbcs(r12, r0, r22); // sbcs x12, x0, x22 + __ adcw(r20, r27, r21); // adc w20, w27, w21 + __ adcsw(r7, r17, r6); // adcs w7, w17, w6 + __ sbcw(r5, r6, r25); // sbc w5, w6, w25 + __ sbcsw(r30, r11, r14); // sbcs w30, w11, w14 + __ adc(r3, r17, r11); // adc x3, x17, x11 + __ adcs(r25, r10, r17); // adcs x25, x10, x17 + __ sbc(r7, r16, r23); // sbc x7, x16, x23 + __ sbcs(r4, r10, r5); // sbcs x4, x10, x5 // AddSubExtendedOp - __ addw(r26, r12, r3, ext::uxtw, 1); // add w26, w12, w3, uxtw #1 - __ addsw(r20, r16, r18, ext::sxtb, 2); // adds w20, w16, w18, sxtb #2 - __ sub(r30, r30, r7, ext::uxtw, 2); // sub x30, x30, x7, uxtw #2 - __ subsw(r11, r21, r2, ext::uxth, 3); // subs w11, w21, w2, uxth #3 - __ add(r2, r26, r1, ext::uxtw, 2); // add x2, x26, x1, uxtw #2 - __ adds(r18, r29, r20, ext::sxth, 1); // adds x18, x29, x20, sxth #1 - __ sub(r14, r16, r4, ext::uxtw, 4); // sub x14, x16, x4, uxtw #4 - __ subs(r0, r17, r23, ext::sxtb, 3); // subs x0, x17, x23, sxtb #3 + __ addw(r9, r30, r9, ext::uxtx, 4); // add w9, w30, w9, uxtx #4 + __ addsw(r0, r5, r16, ext::sxth, 2); // adds w0, w5, w16, sxth #2 + __ sub(r15, r29, r27, ext::sxtb, 2); // sub x15, x29, x27, sxtb #2 + __ subsw(r11, r9, r1, ext::sxtx, 4); // subs w11, w9, w1, sxtx #4 + __ add(r2, r24, r6, ext::uxtw, 3); // add x2, x24, x6, uxtw #3 + __ adds(r19, r6, r26, ext::uxtx, 4); // adds x19, x6, x26, uxtx #4 + __ sub(r8, r26, r25, ext::sxtx, 3); // sub x8, x26, x25, sxtx #3 + __ subs(r26, r20, r9, ext::uxth, 4); // subs x26, x20, x9, uxth #4 // ConditionalCompareOp - __ ccmnw(r20, r22, 3u, Assembler::PL); // ccmn w20, w22, #3, PL - __ ccmpw(r25, r2, 1u, Assembler::EQ); // ccmp w25, w2, #1, EQ - __ ccmn(r18, r24, 7u, Assembler::GT); // ccmn x18, x24, #7, GT - __ ccmp(r8, r13, 6u, Assembler::PL); // ccmp x8, x13, #6, PL + __ ccmnw(r13, r26, 7u, Assembler::MI); // ccmn w13, w26, #7, MI + __ ccmpw(r8, r20, 15u, Assembler::LO); // ccmp w8, w20, #15, LO + __ ccmn(r22, r3, 8u, Assembler::EQ); // ccmn x22, x3, #8, EQ + __ ccmp(r2, r24, 10u, Assembler::GE); // ccmp x2, x24, #10, GE // ConditionalCompareImmedOp - __ ccmnw(r9, 2, 4, Assembler::VS); // ccmn w9, #2, #4, VS - __ ccmpw(r2, 27, 7, Assembler::EQ); // ccmp w2, #27, #7, EQ - __ ccmn(r16, 1, 2, Assembler::CC); // ccmn x16, #1, #2, CC - __ ccmp(r17, 31, 3, Assembler::LT); // ccmp x17, #31, #3, LT + __ ccmnw(r8, 16, 13, Assembler::MI); // ccmn w8, #16, #13, MI + __ ccmpw(r16, 12, 1, Assembler::EQ); // ccmp w16, #12, #1, EQ + __ ccmn(r15, 31, 3, Assembler::VC); // ccmn x15, #31, #3, VC + __ ccmp(r23, 12, 15, Assembler::EQ); // ccmp x23, #12, #15, EQ // ConditionalSelectOp - __ cselw(r23, r27, r23, Assembler::LS); // csel w23, w27, w23, LS - __ csincw(r10, r0, r6, Assembler::VS); // csinc w10, w0, w6, VS - __ csinvw(r11, r0, r9, Assembler::CC); // csinv w11, w0, w9, CC - __ csnegw(r17, r27, r18, Assembler::LO); // csneg w17, w27, w18, LO - __ csel(r12, r16, r11, Assembler::VC); // csel x12, x16, x11, VC - __ csinc(r6, r28, r6, Assembler::HI); // csinc x6, x28, x6, HI - __ csinv(r13, r27, r26, Assembler::VC); // csinv x13, x27, x26, VC - __ csneg(r29, r22, r18, Assembler::PL); // csneg x29, x22, x18, PL + __ cselw(r14, r7, r26, Assembler::LO); // csel w14, w7, w26, LO + __ csincw(r3, r27, r30, Assembler::LE); // csinc w3, w27, w30, LE + __ csinvw(r11, r21, r23, Assembler::EQ); // csinv w11, w21, w23, EQ + __ csnegw(r26, r30, r21, Assembler::GT); // csneg w26, w30, w21, GT + __ csel(r28, r26, r13, Assembler::HI); // csel x28, x26, x13, HI + __ csinc(r17, r3, r16, Assembler::LS); // csinc x17, x3, x16, LS + __ csinv(r11, r5, r3, Assembler::HI); // csinv x11, x5, x3, HI + __ csneg(r1, r3, r19, Assembler::GT); // csneg x1, x3, x19, GT // TwoRegOp - __ rbitw(r12, r19); // rbit w12, w19 - __ rev16w(r23, r18); // rev16 w23, w18 - __ revw(r9, r28); // rev w9, w28 - __ clzw(r2, r19); // clz w2, w19 - __ clsw(r25, r29); // cls w25, w29 - __ rbit(r4, r23); // rbit x4, x23 - __ rev16(r29, r18); // rev16 x29, x18 - __ rev32(r7, r8); // rev32 x7, x8 - __ rev(r13, r17); // rev x13, x17 - __ clz(r17, r0); // clz x17, x0 - __ cls(r18, r26); // cls x18, x26 + __ rbitw(r0, r9); // rbit w0, w9 + __ rev16w(r26, r14); // rev16 w26, w14 + __ revw(r13, r17); // rev w13, w17 + __ clzw(r11, r20); // clz w11, w20 + __ clsw(r28, r17); // cls w28, w17 + __ rbit(r13, r4); // rbit x13, x4 + __ rev16(r1, r30); // rev16 x1, x30 + __ rev32(r13, r14); // rev32 x13, x14 + __ rev(r5, r8); // rev x5, x8 + __ clz(r2, r25); // clz x2, x25 + __ cls(r20, r8); // cls x20, x8 // ThreeRegOp - __ udivw(r11, r12, r16); // udiv w11, w12, w16 - __ sdivw(r4, r9, r7); // sdiv w4, w9, w7 - __ lslvw(r12, r7, r16); // lslv w12, w7, w16 - __ lsrvw(r19, r16, r23); // lsrv w19, w16, w23 - __ asrvw(r7, r4, r6); // asrv w7, w4, w6 - __ rorvw(r21, r20, r23); // rorv w21, w20, w23 - __ udiv(r16, r12, r28); // udiv x16, x12, x28 - __ sdiv(r4, r12, r13); // sdiv x4, x12, x13 - __ lslv(r9, r13, r7); // lslv x9, x13, x7 - __ lsrv(r28, r27, r15); // lsrv x28, x27, x15 - __ asrv(r20, r30, r14); // asrv x20, x30, x14 - __ rorv(r14, r18, r30); // rorv x14, x18, x30 - __ umulh(r3, r11, r7); // umulh x3, x11, x7 - __ smulh(r23, r20, r24); // smulh x23, x20, x24 + __ udivw(r21, r25, r27); // udiv w21, w25, w27 + __ sdivw(r13, r10, r16); // sdiv w13, w10, w16 + __ lslvw(r28, r1, r17); // lslv w28, w1, w17 + __ lsrvw(r25, r23, r10); // lsrv w25, w23, w10 + __ asrvw(r7, r3, r7); // asrv w7, w3, w7 + __ rorvw(r14, r30, r14); // rorv w14, w30, w14 + __ udiv(r12, r22, r15); // udiv x12, x22, x15 + __ sdiv(r2, r25, r13); // sdiv x2, x25, x13 + __ lslv(r7, r23, r21); // lslv x7, x23, x21 + __ lsrv(r11, r12, r0); // lsrv x11, x12, x0 + __ asrv(r30, r9, r28); // asrv x30, x9, x28 + __ rorv(r13, r5, r22); // rorv x13, x5, x22 + __ umulh(r5, r21, r4); // umulh x5, x21, x4 + __ smulh(r17, r2, r7); // smulh x17, x2, x7 // FourRegMulOp - __ maddw(r2, r5, r21, r9); // madd w2, w5, w21, w9 - __ msubw(r24, r24, r4, r8); // msub w24, w24, w4, w8 - __ madd(r11, r12, r15, r19); // madd x11, x12, x15, x19 - __ msub(r29, r25, r12, r25); // msub x29, x25, x12, x25 - __ smaddl(r17, r11, r12, r22); // smaddl x17, w11, w12, x22 - __ smsubl(r28, r3, r20, r18); // smsubl x28, w3, w20, x18 - __ umaddl(r7, r4, r28, r26); // umaddl x7, w4, w28, x26 - __ umsubl(r22, r10, r17, r5); // umsubl x22, w10, w17, x5 + __ maddw(r12, r12, r17, r12); // madd w12, w12, w17, w12 + __ msubw(r30, r15, r1, r27); // msub w30, w15, w1, w27 + __ madd(r2, r19, r17, r29); // madd x2, x19, x17, x29 + __ msub(r4, r23, r3, r30); // msub x4, x23, x3, x30 + __ smaddl(r15, r23, r17, r15); // smaddl x15, w23, w17, x15 + __ smsubl(r27, r12, r1, r13); // smsubl x27, w12, w1, x13 + __ umaddl(r6, r13, r12, r17); // umaddl x6, w13, w12, x17 + __ umsubl(r25, r1, r6, r10); // umsubl x25, w1, w6, x10 // ThreeRegFloatOp - __ fmuls(v17, v3, v17); // fmul s17, s3, s17 - __ fdivs(v11, v17, v6); // fdiv s11, s17, s6 - __ fadds(v29, v7, v9); // fadd s29, s7, s9 - __ fsubs(v7, v12, v19); // fsub s7, s12, s19 - __ fmuls(v0, v23, v3); // fmul s0, s23, s3 - __ fmuld(v26, v3, v21); // fmul d26, d3, d21 - __ fdivd(v0, v19, v5); // fdiv d0, d19, d5 - __ faddd(v0, v26, v9); // fadd d0, d26, d9 - __ fsubd(v25, v21, v21); // fsub d25, d21, d21 - __ fmuld(v16, v13, v19); // fmul d16, d13, d19 + __ fmuls(v17, v3, v4); // fmul s17, s3, s4 + __ fdivs(v16, v5, v21); // fdiv s16, s5, s21 + __ fadds(v3, v27, v17); // fadd s3, s27, s17 + __ fsubs(v25, v10, v15); // fsub s25, s10, s15 + __ fmuls(v10, v17, v0); // fmul s10, s17, s0 + __ fmuld(v28, v26, v3); // fmul d28, d26, d3 + __ fdivd(v4, v0, v27); // fdiv d4, d0, d27 + __ faddd(v28, v14, v2); // fadd d28, d14, d2 + __ fsubd(v12, v26, v23); // fsub d12, d26, d23 + __ fmuld(v15, v30, v1); // fmul d15, d30, d1 // FourRegFloatOp - __ fmadds(v29, v18, v0, v16); // fmadd s29, s18, s0, s16 - __ fmsubs(v23, v13, v29, v5); // fmsub s23, s13, s29, s5 - __ fnmadds(v9, v7, v10, v14); // fnmadd s9, s7, s10, s14 - __ fnmadds(v25, v28, v15, v23); // fnmadd s25, s28, s15, s23 - __ fmaddd(v6, v13, v21, v17); // fmadd d6, d13, d21, d17 - __ fmsubd(v3, v21, v2, v7); // fmsub d3, d21, d2, d7 - __ fnmaddd(v10, v25, v5, v17); // fnmadd d10, d25, d5, d17 - __ fnmaddd(v14, v14, v20, v18); // fnmadd d14, d14, d20, d18 + __ fmadds(v4, v5, v5, v13); // fmadd s4, s5, s5, s13 + __ fmsubs(v21, v13, v28, v1); // fmsub s21, s13, s28, s1 + __ fnmadds(v17, v3, v29, v7); // fnmadd s17, s3, s29, s7 + __ fnmadds(v23, v25, v29, v26); // fnmadd s23, s25, s29, s26 + __ fmaddd(v14, v7, v30, v26); // fmadd d14, d7, d30, d26 + __ fmsubd(v22, v7, v10, v9); // fmsub d22, d7, d10, d9 + __ fnmaddd(v7, v7, v14, v9); // fnmadd d7, d7, d14, d9 + __ fnmaddd(v14, v24, v15, v24); // fnmadd d14, d24, d15, d24 // TwoRegFloatOp - __ fmovs(v15, v2); // fmov s15, s2 - __ fabss(v18, v7); // fabs s18, s7 - __ fnegs(v3, v6); // fneg s3, s6 - __ fsqrts(v12, v1); // fsqrt s12, s1 - __ fcvts(v9, v0); // fcvt d9, s0 - __ fmovd(v4, v5); // fmov d4, d5 - __ fabsd(v3, v15); // fabs d3, d15 - __ fnegd(v17, v25); // fneg d17, d25 - __ fsqrtd(v12, v24); // fsqrt d12, d24 - __ fcvtd(v21, v5); // fcvt s21, d5 + __ fmovs(v22, v2); // fmov s22, s2 + __ fabss(v0, v3); // fabs s0, s3 + __ fnegs(v9, v17); // fneg s9, s17 + __ fsqrts(v24, v11); // fsqrt s24, s11 + __ fcvts(v15, v25); // fcvt d15, s25 + __ fmovd(v4, v3); // fmov d4, d3 + __ fabsd(v26, v22); // fabs d26, d22 + __ fnegd(v30, v19); // fneg d30, d19 + __ fsqrtd(v12, v14); // fsqrt d12, d14 + __ fcvtd(v17, v7); // fcvt s17, d7 // FloatConvertOp - __ fcvtzsw(r4, v21); // fcvtzs w4, s21 - __ fcvtzs(r27, v3); // fcvtzs x27, s3 - __ fcvtzdw(r29, v8); // fcvtzs w29, d8 - __ fcvtzd(r9, v21); // fcvtzs x9, d21 - __ scvtfws(v20, r29); // scvtf s20, w29 - __ scvtfs(v7, r8); // scvtf s7, x8 - __ scvtfwd(v12, r21); // scvtf d12, w21 - __ scvtfd(v16, r21); // scvtf d16, x21 - __ fmovs(r18, v5); // fmov w18, s5 - __ fmovd(r25, v8); // fmov x25, d8 - __ fmovs(v18, r26); // fmov s18, w26 - __ fmovd(v0, r11); // fmov d0, x11 + __ fcvtzsw(r24, v14); // fcvtzs w24, s14 + __ fcvtzs(r13, v26); // fcvtzs x13, s26 + __ fcvtzdw(r2, v1); // fcvtzs w2, d1 + __ fcvtzd(r5, v11); // fcvtzs x5, d11 + __ scvtfws(v14, r19); // scvtf s14, w19 + __ scvtfs(v1, r22); // scvtf s1, x22 + __ scvtfwd(v27, r17); // scvtf d27, w17 + __ scvtfd(v22, r9); // scvtf d22, x9 + __ fmovs(r14, v3); // fmov w14, s3 + __ fmovd(r12, v17); // fmov x12, d17 + __ fmovs(v8, r27); // fmov s8, w27 + __ fmovd(v29, r28); // fmov d29, x28 // TwoRegFloatOp - __ fcmps(v16, v6); // fcmp s16, s6 - __ fcmpd(v16, v29); // fcmp d16, d29 - __ fcmps(v30, 0.0); // fcmp s30, #0.0 - __ fcmpd(v9, 0.0); // fcmp d9, #0.0 + __ fcmps(v0, v30); // fcmp s0, s30 + __ fcmpd(v12, v9); // fcmp d12, d9 + __ fcmps(v10, 0.0); // fcmp s10, #0.0 + __ fcmpd(v25, 0.0); // fcmp d25, #0.0 // LoadStorePairOp - __ stpw(r27, r4, Address(r12, -16)); // stp w27, w4, [x12, #-16] - __ ldpw(r3, r9, Address(r10, 80)); // ldp w3, w9, [x10, #80] - __ ldpsw(r16, r3, Address(r3, 64)); // ldpsw x16, x3, [x3, #64] - __ stp(r10, r28, Address(r19, -192)); // stp x10, x28, [x19, #-192] - __ ldp(r19, r18, Address(r7, -192)); // ldp x19, x18, [x7, #-192] + __ stpw(r8, r30, Address(r27, -144)); // stp w8, w30, [x27, #-144] + __ ldpw(r21, r19, Address(r24, 80)); // ldp w21, w19, [x24, #80] + __ ldpsw(r16, r27, Address(r2, -240)); // ldpsw x16, x27, [x2, #-240] + __ stp(r21, r5, Address(r6, -128)); // stp x21, x5, [x6, #-128] + __ ldp(r29, r25, Address(r28, -32)); // ldp x29, x25, [x28, #-32] // LoadStorePairOp - __ stpw(r10, r16, Address(__ pre(r30, 16))); // stp w10, w16, [x30, #16]! - __ ldpw(r2, r4, Address(__ pre(r18, -240))); // ldp w2, w4, [x18, #-240]! - __ ldpsw(r24, r19, Address(__ pre(r13, 48))); // ldpsw x24, x19, [x13, #48]! - __ stp(r17, r0, Address(__ pre(r24, 0))); // stp x17, x0, [x24, #0]! - __ ldp(r14, r26, Address(__ pre(r3, -192))); // ldp x14, x26, [x3, #-192]! + __ stpw(r8, r13, Address(__ pre(r0, 128))); // stp w8, w13, [x0, #128]! + __ ldpw(r25, r20, Address(__ pre(r1, -160))); // ldp w25, w20, [x1, #-160]! + __ ldpsw(r14, r24, Address(__ pre(r22, -32))); // ldpsw x14, x24, [x22, #-32]! + __ stp(r17, r1, Address(__ pre(r6, 80))); // stp x17, x1, [x6, #80]! + __ ldp(r21, r17, Address(__ pre(r25, -64))); // ldp x21, x17, [x25, #-64]! // LoadStorePairOp - __ stpw(r22, r1, Address(__ post(r0, 80))); // stp w22, w1, [x0], #80 - __ ldpw(r18, r10, Address(__ post(r0, -16))); // ldp w18, w10, [x0], #-16 - __ ldpsw(r24, r24, Address(__ post(r22, -16))); // ldpsw x24, x24, [x22], #-16 - __ stp(r12, r12, Address(__ post(r4, 80))); // stp x12, x12, [x4], #80 - __ ldp(r4, r9, Address(__ post(r19, -240))); // ldp x4, x9, [x19], #-240 + __ stpw(r17, r21, Address(__ post(r20, -128))); // stp w17, w21, [x20], #-128 + __ ldpw(r28, r28, Address(__ post(r2, 64))); // ldp w28, w28, [x2], #64 + __ ldpsw(r19, r30, Address(__ post(r10, -256))); // ldpsw x19, x30, [x10], #-256 + __ stp(r17, r15, Address(__ post(r17, -16))); // stp x17, x15, [x17], #-16 + __ ldp(r17, r0, Address(__ post(r25, -32))); // ldp x17, x0, [x25], #-32 // LoadStorePairOp - __ stnpw(r18, r26, Address(r6, -224)); // stnp w18, w26, [x6, #-224] - __ ldnpw(r21, r20, Address(r1, 112)); // ldnp w21, w20, [x1, #112] - __ stnp(r25, r29, Address(r20, -224)); // stnp x25, x29, [x20, #-224] - __ ldnp(r1, r5, Address(r23, 112)); // ldnp x1, x5, [x23, #112] + __ stnpw(r14, r5, Address(r24, -32)); // stnp w14, w5, [x24, #-32] + __ ldnpw(r23, r19, Address(r1, 112)); // ldnp w23, w19, [x1, #112] + __ stnp(r11, r6, Address(r14, 64)); // stnp x11, x6, [x14, #64] + __ ldnp(r2, r11, Address(r27, -224)); // ldnp x2, x11, [x27, #-224] // LdStSIMDOp - __ ld1(v4, __ T8B, Address(r20)); // ld1 {v4.8B}, [x20] - __ ld1(v24, v25, __ T16B, Address(__ post(r10, 32))); // ld1 {v24.16B, v25.16B}, [x10], 32 - __ ld1(v24, v25, v26, __ T1D, Address(__ post(r6, r15))); // ld1 {v24.1D, v25.1D, v26.1D}, [x6], x15 - __ ld1(v3, v4, v5, v6, __ T8H, Address(__ post(r4, 64))); // ld1 {v3.8H, v4.8H, v5.8H, v6.8H}, [x4], 64 - __ ld1r(v2, __ T8B, Address(r6)); // ld1r {v2.8B}, [x6] - __ ld1r(v13, __ T4S, Address(__ post(r14, 4))); // ld1r {v13.4S}, [x14], 4 - __ ld1r(v15, __ T1D, Address(__ post(r21, r24))); // ld1r {v15.1D}, [x21], x24 - __ ld2(v9, v10, __ T2D, Address(r21)); // ld2 {v9.2D, v10.2D}, [x21] - __ ld2(v29, v30, __ T4H, Address(__ post(r21, 16))); // ld2 {v29.4H, v30.4H}, [x21], 16 - __ ld2r(v8, v9, __ T16B, Address(r14)); // ld2r {v8.16B, v9.16B}, [x14] - __ ld2r(v7, v8, __ T2S, Address(__ post(r20, 8))); // ld2r {v7.2S, v8.2S}, [x20], 8 - __ ld2r(v28, v29, __ T2D, Address(__ post(r3, r3))); // ld2r {v28.2D, v29.2D}, [x3], x3 - __ ld3(v27, v28, v29, __ T4S, Address(__ post(r11, r29))); // ld3 {v27.4S, v28.4S, v29.4S}, [x11], x29 - __ ld3(v16, v17, v18, __ T2S, Address(r10)); // ld3 {v16.2S, v17.2S, v18.2S}, [x10] - __ ld3r(v21, v22, v23, __ T8H, Address(r12)); // ld3r {v21.8H, v22.8H, v23.8H}, [x12] - __ ld3r(v4, v5, v6, __ T4S, Address(__ post(r29, 12))); // ld3r {v4.4S, v5.4S, v6.4S}, [x29], 12 - __ ld3r(v24, v25, v26, __ T1D, Address(__ post(r9, r19))); // ld3r {v24.1D, v25.1D, v26.1D}, [x9], x19 - __ ld4(v10, v11, v12, v13, __ T8H, Address(__ post(r3, 64))); // ld4 {v10.8H, v11.8H, v12.8H, v13.8H}, [x3], 64 - __ ld4(v27, v28, v29, v30, __ T8B, Address(__ post(r28, r9))); // ld4 {v27.8B, v28.8B, v29.8B, v30.8B}, [x28], x9 - __ ld4r(v21, v22, v23, v24, __ T8B, Address(r30)); // ld4r {v21.8B, v22.8B, v23.8B, v24.8B}, [x30] - __ ld4r(v23, v24, v25, v26, __ T4H, Address(__ post(r14, 8))); // ld4r {v23.4H, v24.4H, v25.4H, v26.4H}, [x14], 8 - __ ld4r(v4, v5, v6, v7, __ T2S, Address(__ post(r13, r20))); // ld4r {v4.2S, v5.2S, v6.2S, v7.2S}, [x13], x20 + __ ld1(v16, __ T8B, Address(r17)); // ld1 {v16.8B}, [x17] + __ ld1(v29, v30, __ T16B, Address(__ post(r9, 32))); // ld1 {v29.16B, v30.16B}, [x9], 32 + __ ld1(v30, v31, v0, __ T1D, Address(__ post(r24, r21))); // ld1 {v30.1D, v31.1D, v0.1D}, [x24], x21 + __ ld1(v0, v1, v2, v3, __ T8H, Address(__ post(r2, 64))); // ld1 {v0.8H, v1.8H, v2.8H, v3.8H}, [x2], 64 + __ ld1r(v20, __ T8B, Address(r9)); // ld1r {v20.8B}, [x9] + __ ld1r(v17, __ T4S, Address(__ post(r0, 4))); // ld1r {v17.4S}, [x0], 4 + __ ld1r(v21, __ T1D, Address(__ post(r22, r26))); // ld1r {v21.1D}, [x22], x26 + __ ld2(v19, v20, __ T2D, Address(r25)); // ld2 {v19.2D, v20.2D}, [x25] + __ ld2(v10, v11, __ T4H, Address(__ post(r5, 16))); // ld2 {v10.4H, v11.4H}, [x5], 16 + __ ld2r(v10, v11, __ T16B, Address(r24)); // ld2r {v10.16B, v11.16B}, [x24] + __ ld2r(v13, v14, __ T2S, Address(__ post(r29, 8))); // ld2r {v13.2S, v14.2S}, [x29], 8 + __ ld2r(v22, v23, __ T2D, Address(__ post(r28, r2))); // ld2r {v22.2D, v23.2D}, [x28], x2 + __ ld3(v30, v31, v0, __ T4S, Address(__ post(r4, r11))); // ld3 {v30.4S, v31.4S, v0.4S}, [x4], x11 + __ ld3(v29, v30, v31, __ T2S, Address(r0)); // ld3 {v29.2S, v30.2S, v31.2S}, [x0] + __ ld3r(v23, v24, v25, __ T8H, Address(r27)); // ld3r {v23.8H, v24.8H, v25.8H}, [x27] + __ ld3r(v3, v4, v5, __ T4S, Address(__ post(r10, 12))); // ld3r {v3.4S, v4.4S, v5.4S}, [x10], 12 + __ ld3r(v19, v20, v21, __ T1D, Address(__ post(r14, r22))); // ld3r {v19.1D, v20.1D, v21.1D}, [x14], x22 + __ ld4(v14, v15, v16, v17, __ T8H, Address(__ post(r0, 64))); // ld4 {v14.8H, v15.8H, v16.8H, v17.8H}, [x0], 64 + __ ld4(v30, v31, v0, v1, __ T8B, Address(__ post(r22, r25))); // ld4 {v30.8B, v31.8B, v0.8B, v1.8B}, [x22], x25 + __ ld4r(v25, v26, v27, v28, __ T8B, Address(r0)); // ld4r {v25.8B, v26.8B, v27.8B, v28.8B}, [x0] + __ ld4r(v10, v11, v12, v13, __ T4H, Address(__ post(r8, 8))); // ld4r {v10.4H, v11.4H, v12.4H, v13.4H}, [x8], 8 + __ ld4r(v1, v2, v3, v4, __ T2S, Address(__ post(r6, r28))); // ld4r {v1.2S, v2.2S, v3.2S, v4.2S}, [x6], x28 // SpecialCases - __ ccmn(zr, zr, 3u, Assembler::LE); // ccmn xzr, xzr, #3, LE - __ ccmnw(zr, zr, 5u, Assembler::EQ); // ccmn wzr, wzr, #5, EQ - __ ccmp(zr, 1, 4u, Assembler::NE); // ccmp xzr, 1, #4, NE - __ ccmpw(zr, 2, 2, Assembler::GT); // ccmp wzr, 2, #2, GT - __ extr(zr, zr, zr, 0); // extr xzr, xzr, xzr, 0 - __ stlxp(r0, zr, zr, sp); // stlxp w0, xzr, xzr, [sp] - __ stlxpw(r2, zr, zr, r3); // stlxp w2, wzr, wzr, [x3] - __ stxp(r4, zr, zr, r5); // stxp w4, xzr, xzr, [x5] - __ stxpw(r6, zr, zr, sp); // stxp w6, wzr, wzr, [sp] - __ dup(v0, __ T16B, zr); // dup v0.16b, wzr - __ mov(v1, __ T1D, 0, zr); // mov v1.d[0], xzr - __ mov(v1, __ T2S, 1, zr); // mov v1.s[1], wzr - __ mov(v1, __ T4H, 2, zr); // mov v1.h[2], wzr - __ mov(v1, __ T8B, 3, zr); // mov v1.b[3], wzr - __ ld1(v31, v0, __ T2D, Address(__ post(r1, r0))); // ld1 {v31.2d, v0.2d}, [x1], x0 + __ ccmn(zr, zr, 3u, Assembler::LE); // ccmn xzr, xzr, #3, LE + __ ccmnw(zr, zr, 5u, Assembler::EQ); // ccmn wzr, wzr, #5, EQ + __ ccmp(zr, 1, 4u, Assembler::NE); // ccmp xzr, 1, #4, NE + __ ccmpw(zr, 2, 2, Assembler::GT); // ccmp wzr, 2, #2, GT + __ extr(zr, zr, zr, 0); // extr xzr, xzr, xzr, 0 + __ stlxp(r0, zr, zr, sp); // stlxp w0, xzr, xzr, [sp] + __ stlxpw(r2, zr, zr, r3); // stlxp w2, wzr, wzr, [x3] + __ stxp(r4, zr, zr, r5); // stxp w4, xzr, xzr, [x5] + __ stxpw(r6, zr, zr, sp); // stxp w6, wzr, wzr, [sp] + __ dup(v0, __ T16B, zr); // dup v0.16b, wzr + __ mov(v1, __ T1D, 0, zr); // mov v1.d[0], xzr + __ mov(v1, __ T2S, 1, zr); // mov v1.s[1], wzr + __ mov(v1, __ T4H, 2, zr); // mov v1.h[2], wzr + __ mov(v1, __ T8B, 3, zr); // mov v1.b[3], wzr + __ ld1(v31, v0, __ T2D, Address(__ post(r1, r0))); // ld1 {v31.2d, v0.2d}, [x1], x0 // FloatImmediateOp - __ fmovd(v0, 2.0); // fmov d0, #2.0 - __ fmovd(v0, 2.125); // fmov d0, #2.125 - __ fmovd(v0, 4.0); // fmov d0, #4.0 - __ fmovd(v0, 4.25); // fmov d0, #4.25 - __ fmovd(v0, 8.0); // fmov d0, #8.0 - __ fmovd(v0, 8.5); // fmov d0, #8.5 - __ fmovd(v0, 16.0); // fmov d0, #16.0 - __ fmovd(v0, 17.0); // fmov d0, #17.0 - __ fmovd(v0, 0.125); // fmov d0, #0.125 - __ fmovd(v0, 0.1328125); // fmov d0, #0.1328125 - __ fmovd(v0, 0.25); // fmov d0, #0.25 - __ fmovd(v0, 0.265625); // fmov d0, #0.265625 - __ fmovd(v0, 0.5); // fmov d0, #0.5 - __ fmovd(v0, 0.53125); // fmov d0, #0.53125 - __ fmovd(v0, 1.0); // fmov d0, #1.0 - __ fmovd(v0, 1.0625); // fmov d0, #1.0625 - __ fmovd(v0, -2.0); // fmov d0, #-2.0 - __ fmovd(v0, -2.125); // fmov d0, #-2.125 - __ fmovd(v0, -4.0); // fmov d0, #-4.0 - __ fmovd(v0, -4.25); // fmov d0, #-4.25 - __ fmovd(v0, -8.0); // fmov d0, #-8.0 - __ fmovd(v0, -8.5); // fmov d0, #-8.5 - __ fmovd(v0, -16.0); // fmov d0, #-16.0 - __ fmovd(v0, -17.0); // fmov d0, #-17.0 - __ fmovd(v0, -0.125); // fmov d0, #-0.125 - __ fmovd(v0, -0.1328125); // fmov d0, #-0.1328125 - __ fmovd(v0, -0.25); // fmov d0, #-0.25 - __ fmovd(v0, -0.265625); // fmov d0, #-0.265625 - __ fmovd(v0, -0.5); // fmov d0, #-0.5 - __ fmovd(v0, -0.53125); // fmov d0, #-0.53125 - __ fmovd(v0, -1.0); // fmov d0, #-1.0 - __ fmovd(v0, -1.0625); // fmov d0, #-1.0625 + __ fmovd(v0, 2.0); // fmov d0, #2.0 + __ fmovd(v0, 2.125); // fmov d0, #2.125 + __ fmovd(v0, 4.0); // fmov d0, #4.0 + __ fmovd(v0, 4.25); // fmov d0, #4.25 + __ fmovd(v0, 8.0); // fmov d0, #8.0 + __ fmovd(v0, 8.5); // fmov d0, #8.5 + __ fmovd(v0, 16.0); // fmov d0, #16.0 + __ fmovd(v0, 17.0); // fmov d0, #17.0 + __ fmovd(v0, 0.125); // fmov d0, #0.125 + __ fmovd(v0, 0.1328125); // fmov d0, #0.1328125 + __ fmovd(v0, 0.25); // fmov d0, #0.25 + __ fmovd(v0, 0.265625); // fmov d0, #0.265625 + __ fmovd(v0, 0.5); // fmov d0, #0.5 + __ fmovd(v0, 0.53125); // fmov d0, #0.53125 + __ fmovd(v0, 1.0); // fmov d0, #1.0 + __ fmovd(v0, 1.0625); // fmov d0, #1.0625 + __ fmovd(v0, -2.0); // fmov d0, #-2.0 + __ fmovd(v0, -2.125); // fmov d0, #-2.125 + __ fmovd(v0, -4.0); // fmov d0, #-4.0 + __ fmovd(v0, -4.25); // fmov d0, #-4.25 + __ fmovd(v0, -8.0); // fmov d0, #-8.0 + __ fmovd(v0, -8.5); // fmov d0, #-8.5 + __ fmovd(v0, -16.0); // fmov d0, #-16.0 + __ fmovd(v0, -17.0); // fmov d0, #-17.0 + __ fmovd(v0, -0.125); // fmov d0, #-0.125 + __ fmovd(v0, -0.1328125); // fmov d0, #-0.1328125 + __ fmovd(v0, -0.25); // fmov d0, #-0.25 + __ fmovd(v0, -0.265625); // fmov d0, #-0.265625 + __ fmovd(v0, -0.5); // fmov d0, #-0.5 + __ fmovd(v0, -0.53125); // fmov d0, #-0.53125 + __ fmovd(v0, -1.0); // fmov d0, #-1.0 + __ fmovd(v0, -1.0625); // fmov d0, #-1.0625 // LSEOp - __ swp(Assembler::xword, r21, r5, r24); // swp x21, x5, [x24] - __ ldadd(Assembler::xword, r13, r13, r15); // ldadd x13, x13, [x15] - __ ldbic(Assembler::xword, r22, r19, r26); // ldclr x22, x19, [x26] - __ ldeor(Assembler::xword, r25, r10, r26); // ldeor x25, x10, [x26] - __ ldorr(Assembler::xword, r5, r27, r15); // ldset x5, x27, [x15] - __ ldsmin(Assembler::xword, r19, r5, r11); // ldsmin x19, x5, [x11] - __ ldsmax(Assembler::xword, r26, r0, r4); // ldsmax x26, x0, [x4] - __ ldumin(Assembler::xword, r22, r23, r30); // ldumin x22, x23, [x30] - __ ldumax(Assembler::xword, r18, r28, r8); // ldumax x18, x28, [x8] + __ swp(Assembler::xword, r16, r20, r15); // swp x16, x20, [x15] + __ ldadd(Assembler::xword, r2, r7, r28); // ldadd x2, x7, [x28] + __ ldbic(Assembler::xword, r20, r10, r25); // ldclr x20, x10, [x25] + __ ldeor(Assembler::xword, r22, r11, r2); // ldeor x22, x11, [x2] + __ ldorr(Assembler::xword, r1, r10, r19); // ldset x1, x10, [x19] + __ ldsmin(Assembler::xword, r14, r21, r3); // ldsmin x14, x21, [x3] + __ ldsmax(Assembler::xword, r28, r27, r13); // ldsmax x28, x27, [x13] + __ ldumin(Assembler::xword, r17, r30, r21); // ldumin x17, x30, [x21] + __ ldumax(Assembler::xword, r27, r16, r29); // ldumax x27, x16, [x29] // LSEOp - __ swpa(Assembler::xword, r13, r29, r27); // swpa x13, x29, [x27] - __ ldadda(Assembler::xword, r11, r5, r13); // ldadda x11, x5, [x13] - __ ldbica(Assembler::xword, r1, r24, r21); // ldclra x1, x24, [x21] - __ ldeora(Assembler::xword, r27, r17, r24); // ldeora x27, x17, [x24] - __ ldorra(Assembler::xword, r18, r30, r5); // ldseta x18, x30, [x5] - __ ldsmina(Assembler::xword, r7, r22, r25); // ldsmina x7, x22, [x25] - __ ldsmaxa(Assembler::xword, r4, r26, r19); // ldsmaxa x4, x26, [x19] - __ ldumina(Assembler::xword, r6, r30, r3); // ldumina x6, x30, [x3] - __ ldumaxa(Assembler::xword, r24, r23, r5); // ldumaxa x24, x23, [x5] + __ swpa(Assembler::xword, r30, r9, r0); // swpa x30, x9, [x0] + __ ldadda(Assembler::xword, r28, r27, r28); // ldadda x28, x27, [x28] + __ ldbica(Assembler::xword, r21, r25, r10); // ldclra x21, x25, [x10] + __ ldeora(Assembler::xword, zr, r20, r15); // ldeora xzr, x20, [x15] + __ ldorra(Assembler::xword, r1, r25, r14); // ldseta x1, x25, [x14] + __ ldsmina(Assembler::xword, r21, r26, r29); // ldsmina x21, x26, [x29] + __ ldsmaxa(Assembler::xword, r8, r29, r25); // ldsmaxa x8, x29, [x25] + __ ldumina(Assembler::xword, r13, r2, r25); // ldumina x13, x2, [x25] + __ ldumaxa(Assembler::xword, r15, r23, r0); // ldumaxa x15, x23, [x0] // LSEOp - __ swpal(Assembler::xword, r24, r18, r28); // swpal x24, x18, [x28] - __ ldaddal(Assembler::xword, r19, zr, r7); // ldaddal x19, xzr, [x7] - __ ldbical(Assembler::xword, r13, r6, r28); // ldclral x13, x6, [x28] - __ ldeoral(Assembler::xword, r8, r15, r21); // ldeoral x8, x15, [x21] - __ ldorral(Assembler::xword, r2, r13, r1); // ldsetal x2, x13, [x1] - __ ldsminal(Assembler::xword, r17, r29, r25); // ldsminal x17, x29, [x25] - __ ldsmaxal(Assembler::xword, r25, r18, r14); // ldsmaxal x25, x18, [x14] - __ lduminal(Assembler::xword, zr, r6, r27); // lduminal xzr, x6, [x27] - __ ldumaxal(Assembler::xword, r16, r5, r15); // ldumaxal x16, x5, [x15] + __ swpal(Assembler::xword, r3, r1, r2); // swpal x3, x1, [x2] + __ ldaddal(Assembler::xword, r28, r3, r20); // ldaddal x28, x3, [x20] + __ ldbical(Assembler::xword, r14, zr, r14); // ldclral x14, xzr, [x14] + __ ldeoral(Assembler::xword, r7, r28, r2); // ldeoral x7, x28, [x2] + __ ldorral(Assembler::xword, r0, r11, r5); // ldsetal x0, x11, [x5] + __ ldsminal(Assembler::xword, r11, r14, r20); // ldsminal x11, x14, [x20] + __ ldsmaxal(Assembler::xword, zr, r4, r2); // ldsmaxal xzr, x4, [x2] + __ lduminal(Assembler::xword, r26, r0, r22); // lduminal x26, x0, [x22] + __ ldumaxal(Assembler::xword, r17, r1, r13); // ldumaxal x17, x1, [x13] // LSEOp - __ swpl(Assembler::xword, r11, r18, r3); // swpl x11, x18, [x3] - __ ldaddl(Assembler::xword, r26, r20, r2); // ldaddl x26, x20, [x2] - __ ldbicl(Assembler::xword, r11, r4, r11); // ldclrl x11, x4, [x11] - __ ldeorl(Assembler::xword, r30, r19, r23); // ldeorl x30, x19, [x23] - __ ldorrl(Assembler::xword, r3, r15, r14); // ldsetl x3, x15, [x14] - __ ldsminl(Assembler::xword, r30, r22, r20); // ldsminl x30, x22, [x20] - __ ldsmaxl(Assembler::xword, r7, r5, r24); // ldsmaxl x7, x5, [x24] - __ lduminl(Assembler::xword, r23, r16, r15); // lduminl x23, x16, [x15] - __ ldumaxl(Assembler::xword, r11, r19, r0); // ldumaxl x11, x19, [x0] + __ swpl(Assembler::xword, r23, r26, r20); // swpl x23, x26, [x20] + __ ldaddl(Assembler::xword, r14, r11, r12); // ldaddl x14, x11, [x12] + __ ldbicl(Assembler::xword, r12, zr, r15); // ldclrl x12, xzr, [x15] + __ ldeorl(Assembler::xword, r27, r14, r8); // ldeorl x27, x14, [x8] + __ ldorrl(Assembler::xword, r10, r30, r25); // ldsetl x10, x30, [x25] + __ ldsminl(Assembler::xword, r22, r7, r16); // ldsminl x22, x7, [x16] + __ ldsmaxl(Assembler::xword, r1, r16, r8); // ldsmaxl x1, x16, [x8] + __ lduminl(Assembler::xword, r1, r1, r26); // lduminl x1, x1, [x26] + __ ldumaxl(Assembler::xword, r0, r23, r15); // ldumaxl x0, x23, [x15] // LSEOp - __ swp(Assembler::word, r28, r28, r1); // swp w28, w28, [x1] - __ ldadd(Assembler::word, r11, r21, r12); // ldadd w11, w21, [x12] - __ ldbic(Assembler::word, r29, r0, r18); // ldclr w29, w0, [x18] - __ ldeor(Assembler::word, r5, r0, r25); // ldeor w5, w0, [x25] - __ ldorr(Assembler::word, r14, r0, r26); // ldset w14, w0, [x26] - __ ldsmin(Assembler::word, r28, r18, r29); // ldsmin w28, w18, [x29] - __ ldsmax(Assembler::word, r15, r1, r29); // ldsmax w15, w1, [x29] - __ ldumin(Assembler::word, r8, r26, r28); // ldumin w8, w26, [x28] - __ ldumax(Assembler::word, r17, r14, r4); // ldumax w17, w14, [x4] + __ swp(Assembler::word, r11, r16, r8); // swp w11, w16, [x8] + __ ldadd(Assembler::word, r1, r7, r14); // ldadd w1, w7, [x14] + __ ldbic(Assembler::word, r16, zr, r9); // ldclr w16, wzr, [x9] + __ ldeor(Assembler::word, r22, r6, r13); // ldeor w22, w6, [x13] + __ ldorr(Assembler::word, r11, r13, r4); // ldset w11, w13, [x4] + __ ldsmin(Assembler::word, r16, r22, r0); // ldsmin w16, w22, [x0] + __ ldsmax(Assembler::word, r28, zr, r10); // ldsmax w28, wzr, [x10] + __ ldumin(Assembler::word, r16, r5, r8); // ldumin w16, w5, [x8] + __ ldumax(Assembler::word, r26, r20, r15); // ldumax w26, w20, [x15] // LSEOp - __ swpa(Assembler::word, r24, r25, r1); // swpa w24, w25, [x1] - __ ldadda(Assembler::word, r10, r17, r17); // ldadda w10, w17, [x17] - __ ldbica(Assembler::word, r29, r20, r21); // ldclra w29, w20, [x21] - __ ldeora(Assembler::word, r29, r9, r12); // ldeora w29, w9, [x12] - __ ldorra(Assembler::word, r11, r6, r5); // ldseta w11, w6, [x5] - __ ldsmina(Assembler::word, r21, r7, r21); // ldsmina w21, w7, [x21] - __ ldsmaxa(Assembler::word, r10, r23, r12); // ldsmaxa w10, w23, [x12] - __ ldumina(Assembler::word, r21, r5, r10); // ldumina w21, w5, [x10] - __ ldumaxa(Assembler::word, r30, r20, r18); // ldumaxa w30, w20, [x18] + __ swpa(Assembler::word, r27, r6, r16); // swpa w27, w6, [x16] + __ ldadda(Assembler::word, zr, zr, r2); // ldadda wzr, wzr, [x2] + __ ldbica(Assembler::word, r24, r28, r8); // ldclra w24, w28, [x8] + __ ldeora(Assembler::word, r15, r9, r23); // ldeora w15, w9, [x23] + __ ldorra(Assembler::word, r26, r2, r7); // ldseta w26, w2, [x7] + __ ldsmina(Assembler::word, r3, r17, r15); // ldsmina w3, w17, [x15] + __ ldsmaxa(Assembler::word, r19, r5, r21); // ldsmaxa w19, w5, [x21] + __ ldumina(Assembler::word, r7, r26, r12); // ldumina w7, w26, [x12] + __ ldumaxa(Assembler::word, r12, r7, r29); // ldumaxa w12, w7, [x29] // LSEOp - __ swpal(Assembler::word, r13, r23, r5); // swpal w13, w23, [x5] - __ ldaddal(Assembler::word, r15, r24, r5); // ldaddal w15, w24, [x5] - __ ldbical(Assembler::word, r9, r10, r25); // ldclral w9, w10, [x25] - __ ldeoral(Assembler::word, r20, r17, r17); // ldeoral w20, w17, [x17] - __ ldorral(Assembler::word, r12, r18, r30); // ldsetal w12, w18, [x30] - __ ldsminal(Assembler::word, r3, r3, r25); // ldsminal w3, w3, [x25] - __ ldsmaxal(Assembler::word, r26, r25, r10); // ldsmaxal w26, w25, [x10] - __ lduminal(Assembler::word, r2, r11, sp); // lduminal w2, w11, [sp] - __ ldumaxal(Assembler::word, r7, r2, r5); // ldumaxal w7, w2, [x5] + __ swpal(Assembler::word, r9, r8, r20); // swpal w9, w8, [x20] + __ ldaddal(Assembler::word, r8, zr, r30); // ldaddal w8, wzr, [x30] + __ ldbical(Assembler::word, r0, r6, r12); // ldclral w0, w6, [x12] + __ ldeoral(Assembler::word, r17, r23, r2); // ldeoral w17, w23, [x2] + __ ldorral(Assembler::word, r0, r30, r1); // ldsetal w0, w30, [x1] + __ ldsminal(Assembler::word, r22, r3, r15); // ldsminal w22, w3, [x15] + __ ldsmaxal(Assembler::word, r25, r21, r13); // ldsmaxal w25, w21, [x13] + __ lduminal(Assembler::word, r13, r24, r27); // lduminal w13, w24, [x27] + __ ldumaxal(Assembler::word, r20, r3, r11); // ldumaxal w20, w3, [x11] // LSEOp - __ swpl(Assembler::word, r0, r7, r20); // swpl w0, w7, [x20] - __ ldaddl(Assembler::word, r5, zr, r2); // ldaddl w5, wzr, [x2] - __ ldbicl(Assembler::word, r27, r25, r27); // ldclrl w27, w25, [x27] - __ ldeorl(Assembler::word, r30, r24, r26); // ldeorl w30, w24, [x26] - __ ldorrl(Assembler::word, r15, r2, r22); // ldsetl w15, w2, [x22] - __ ldsminl(Assembler::word, r0, r3, sp); // ldsminl w0, w3, [sp] - __ ldsmaxl(Assembler::word, r15, r20, r10); // ldsmaxl w15, w20, [x10] - __ lduminl(Assembler::word, r22, r21, r14); // lduminl w22, w21, [x14] - __ ldumaxl(Assembler::word, r6, r30, r2); // ldumaxl w6, w30, [x2] + __ swpl(Assembler::word, r3, r13, r21); // swpl w3, w13, [x21] + __ ldaddl(Assembler::word, r26, r15, r26); // ldaddl w26, w15, [x26] + __ ldbicl(Assembler::word, r9, r19, r2); // ldclrl w9, w19, [x2] + __ ldeorl(Assembler::word, r24, r29, r7); // ldeorl w24, w29, [x7] + __ ldorrl(Assembler::word, r29, r25, r15); // ldsetl w29, w25, [x15] + __ ldsminl(Assembler::word, r11, r30, r7); // ldsminl w11, w30, [x7] + __ ldsmaxl(Assembler::word, r11, r2, r6); // ldsmaxl w11, w2, [x6] + __ lduminl(Assembler::word, r16, r11, r14); // lduminl w16, w11, [x14] + __ ldumaxl(Assembler::word, r5, r8, r11); // ldumaxl w5, w8, [x11] __ bind(forth); @@ -762,567 +762,567 @@ Disassembly of section .text: 0000000000000000 <back>: - 0: 8b50798f add x15, x12, x16, lsr #30 - 4: cb4381e1 sub x1, x15, x3, lsr #32 - 8: ab05372d adds x13, x25, x5, lsl #13 - c: eb864796 subs x22, x28, x6, asr #17 - 10: 0b961920 add w0, w9, w22, asr #6 - 14: 4b195473 sub w19, w3, w25, lsl #21 - 18: 2b0b5264 adds w4, w19, w11, lsl #20 - 1c: 6b9300f8 subs w24, w7, w19, asr #0 - 20: 8a0bc0fe and x30, x7, x11, lsl #48 - 24: aa0f3118 orr x24, x8, x15, lsl #12 - 28: ca170531 eor x17, x9, x23, lsl #1 - 2c: ea44dd6e ands x14, x11, x4, lsr #55 - 30: 0a4c44f3 and w19, w7, w12, lsr #17 - 34: 2a8b7373 orr w19, w27, w11, asr #28 - 38: 4a567c7e eor w30, w3, w22, lsr #31 - 3c: 6a9c0353 ands w19, w26, w28, asr #0 - 40: 8a3accdd bic x29, x6, x26, lsl #51 - 44: aa318f7a orn x26, x27, x17, lsl #35 - 48: ca2e1495 eon x21, x4, x14, lsl #5 - 4c: eaa015e2 bics x2, x15, x0, asr #5 - 50: 0a2274e2 bic w2, w7, w2, lsl #29 - 54: 2a751598 orn w24, w12, w21, lsr #5 - 58: 4a3309fe eon w30, w15, w19, lsl #2 - 5c: 6ab172fe bics w30, w23, w17, asr #28 - 60: 110a5284 add w4, w20, #0x294 - 64: 310b1942 adds w2, w10, #0x2c6 - 68: 5103d353 sub w19, w26, #0xf4 - 6c: 710125bc subs w28, w13, #0x49 - 70: 910d7bc2 add x2, x30, #0x35e - 74: b108fa1b adds x27, x16, #0x23e - 78: d1093536 sub x22, x9, #0x24d - 7c: f10ae824 subs x4, x1, #0x2ba - 80: 120e667c and w28, w19, #0xfffc0fff - 84: 321f6cbb orr w27, w5, #0x1ffffffe - 88: 520f6a9e eor w30, w20, #0xfffe0fff - 8c: 72136f56 ands w22, w26, #0xffffe1ff - 90: 927e4ce5 and x5, x7, #0x3ffffc - 94: b278b4ed orr x13, x7, #0x3fffffffffff00 - 98: d24c6527 eor x7, x9, #0xfff0000000003fff - 9c: f2485803 ands x3, x0, #0xff00000000007fff - a0: 14000000 b a0 <back+0xa0> - a4: 17ffffd7 b 0 <back> - a8: 140001ee b 860 <forth> - ac: 94000000 bl ac <back+0xac> - b0: 97ffffd4 bl 0 <back> - b4: 940001eb bl 860 <forth> - b8: 34000010 cbz w16, b8 <back+0xb8> - bc: 34fffa30 cbz w16, 0 <back> - c0: 34003d10 cbz w16, 860 <forth> - c4: 35000013 cbnz w19, c4 <back+0xc4> - c8: 35fff9d3 cbnz w19, 0 <back> - cc: 35003cb3 cbnz w19, 860 <forth> - d0: b4000005 cbz x5, d0 <back+0xd0> - d4: b4fff965 cbz x5, 0 <back> - d8: b4003c45 cbz x5, 860 <forth> - dc: b5000004 cbnz x4, dc <back+0xdc> - e0: b5fff904 cbnz x4, 0 <back> - e4: b5003be4 cbnz x4, 860 <forth> - e8: 1000001b adr x27, e8 <back+0xe8> - ec: 10fff8bb adr x27, 0 <back> - f0: 10003b9b adr x27, 860 <forth> - f4: 90000010 adrp x16, 0 <back> - f8: 3640001c tbz w28, #8, f8 <back+0xf8> - fc: 3647f83c tbz w28, #8, 0 <back> - 100: 36403b1c tbz w28, #8, 860 <forth> - 104: 37080001 tbnz w1, #1, 104 <back+0x104> - 108: 370ff7c1 tbnz w1, #1, 0 <back> - 10c: 37083aa1 tbnz w1, #1, 860 <forth> - 110: 12a437f4 mov w20, #0xde40ffff // #-566165505 - 114: 528c9d67 mov w7, #0x64eb // #25835 - 118: 72838bb1 movk w17, #0x1c5d - 11c: 92c1062e mov x14, #0xfffff7ceffffffff // #-9006546419713 - 120: d287da49 mov x9, #0x3ed2 // #16082 - 124: f2a6d153 movk x19, #0x368a, lsl #16 - 128: 93465ac9 sbfx x9, x22, #6, #17 - 12c: 330b0013 bfi w19, w0, #21, #1 - 130: 530b4e6a ubfx w10, w19, #11, #9 - 134: 934545e4 sbfx x4, x15, #5, #13 - 138: b35370a3 bfxil x3, x5, #19, #10 - 13c: d3510b8c ubfiz x12, x28, #47, #3 - 140: 13960c0f extr w15, w0, w22, #3 - 144: 93ceddc6 ror x6, x14, #55 - 148: 54000000 b.eq 148 <back+0x148> // b.none - 14c: 54fff5a0 b.eq 0 <back> // b.none - 150: 54003880 b.eq 860 <forth> // b.none - 154: 54000001 b.ne 154 <back+0x154> // b.any - 158: 54fff541 b.ne 0 <back> // b.any - 15c: 54003821 b.ne 860 <forth> // b.any - 160: 54000002 b.cs 160 <back+0x160> // b.hs, b.nlast - 164: 54fff4e2 b.cs 0 <back> // b.hs, b.nlast - 168: 540037c2 b.cs 860 <forth> // b.hs, b.nlast - 16c: 54000002 b.cs 16c <back+0x16c> // b.hs, b.nlast - 170: 54fff482 b.cs 0 <back> // b.hs, b.nlast - 174: 54003762 b.cs 860 <forth> // b.hs, b.nlast - 178: 54000003 b.cc 178 <back+0x178> // b.lo, b.ul, b.last - 17c: 54fff423 b.cc 0 <back> // b.lo, b.ul, b.last - 180: 54003703 b.cc 860 <forth> // b.lo, b.ul, b.last - 184: 54000003 b.cc 184 <back+0x184> // b.lo, b.ul, b.last - 188: 54fff3c3 b.cc 0 <back> // b.lo, b.ul, b.last - 18c: 540036a3 b.cc 860 <forth> // b.lo, b.ul, b.last - 190: 54000004 b.mi 190 <back+0x190> // b.first - 194: 54fff364 b.mi 0 <back> // b.first - 198: 54003644 b.mi 860 <forth> // b.first - 19c: 54000005 b.pl 19c <back+0x19c> // b.nfrst - 1a0: 54fff305 b.pl 0 <back> // b.nfrst - 1a4: 540035e5 b.pl 860 <forth> // b.nfrst - 1a8: 54000006 b.vs 1a8 <back+0x1a8> - 1ac: 54fff2a6 b.vs 0 <back> - 1b0: 54003586 b.vs 860 <forth> - 1b4: 54000007 b.vc 1b4 <back+0x1b4> - 1b8: 54fff247 b.vc 0 <back> - 1bc: 54003527 b.vc 860 <forth> - 1c0: 54000008 b.hi 1c0 <back+0x1c0> // b.pmore - 1c4: 54fff1e8 b.hi 0 <back> // b.pmore - 1c8: 540034c8 b.hi 860 <forth> // b.pmore - 1cc: 54000009 b.ls 1cc <back+0x1cc> // b.plast - 1d0: 54fff189 b.ls 0 <back> // b.plast - 1d4: 54003469 b.ls 860 <forth> // b.plast - 1d8: 5400000a b.ge 1d8 <back+0x1d8> // b.tcont - 1dc: 54fff12a b.ge 0 <back> // b.tcont - 1e0: 5400340a b.ge 860 <forth> // b.tcont - 1e4: 5400000b b.lt 1e4 <back+0x1e4> // b.tstop - 1e8: 54fff0cb b.lt 0 <back> // b.tstop - 1ec: 540033ab b.lt 860 <forth> // b.tstop - 1f0: 5400000c b.gt 1f0 <back+0x1f0> - 1f4: 54fff06c b.gt 0 <back> - 1f8: 5400334c b.gt 860 <forth> - 1fc: 5400000d b.le 1fc <back+0x1fc> - 200: 54fff00d b.le 0 <back> - 204: 540032ed b.le 860 <forth> - 208: 5400000e b.al 208 <back+0x208> - 20c: 54ffefae b.al 0 <back> - 210: 5400328e b.al 860 <forth> - 214: 5400000f b.nv 214 <back+0x214> - 218: 54ffef4f b.nv 0 <back> - 21c: 5400322f b.nv 860 <forth> - 220: d40ac601 svc #0x5630 - 224: d40042a2 hvc #0x215 - 228: d404dac3 smc #0x26d6 - 22c: d4224d40 brk #0x126a - 230: d44219c0 hlt #0x10ce - 234: d503201f nop - 238: d69f03e0 eret - 23c: d6bf03e0 drps - 240: d5033fdf isb - 244: d503339f dsb osh - 248: d50335bf dmb nshld - 24c: d61f0280 br x20 - 250: d63f0040 blr x2 - 254: c8127c17 stxr w18, x23, [x0] - 258: c81efec5 stlxr w30, x5, [x22] - 25c: c85f7d05 ldxr x5, [x8] - 260: c85ffe14 ldaxr x20, [x16] - 264: c89ffd66 stlr x6, [x11] - 268: c8dfff66 ldar x6, [x27] - 26c: 880a7cb1 stxr w10, w17, [x5] - 270: 8816fd89 stlxr w22, w9, [x12] - 274: 885f7d1b ldxr w27, [x8] - 278: 885ffc57 ldaxr w23, [x2] - 27c: 889fffba stlr w26, [x29] - 280: 88dffd4d ldar w13, [x10] - 284: 48197f7c stxrh w25, w28, [x27] - 288: 481dfd96 stlxrh w29, w22, [x12] - 28c: 485f7f96 ldxrh w22, [x28] - 290: 485fffc3 ldaxrh w3, [x30] - 294: 489ffdf8 stlrh w24, [x15] - 298: 48dfff5b ldarh w27, [x26] - 29c: 080b7e6a stxrb w11, w10, [x19] - 2a0: 0817fedb stlxrb w23, w27, [x22] - 2a4: 085f7e18 ldxrb w24, [x16] - 2a8: 085ffc38 ldaxrb w24, [x1] - 2ac: 089fffa5 stlrb w5, [x29] - 2b0: 08dffe18 ldarb w24, [x16] - 2b4: c87f6239 ldxp x25, x24, [x17] - 2b8: c87fb276 ldaxp x22, x12, [x19] - 2bc: c820573a stxp w0, x26, x21, [x25] - 2c0: c821aca6 stlxp w1, x6, x11, [x5] - 2c4: 887f388d ldxp w13, w14, [x4] - 2c8: 887f88d1 ldaxp w17, w2, [x6] - 2cc: 882f2643 stxp w15, w3, w9, [x18] - 2d0: 88329131 stlxp w18, w17, w4, [x9] - 2d4: f81cf2b7 stur x23, [x21, #-49] - 2d8: b803f055 stur w21, [x2, #63] - 2dc: 39002f9b strb w27, [x28, #11] - 2e0: 781f31fd sturh w29, [x15, #-13] - 2e4: f85d33ce ldur x14, [x30, #-45] - 2e8: b843539d ldur w29, [x28, #53] - 2ec: 39401f54 ldrb w20, [x26, #7] - 2f0: 785ce059 ldurh w25, [x2, #-50] - 2f4: 389f1143 ldursb x3, [x10, #-15] - 2f8: 788131ee ldursh x14, [x15, #19] - 2fc: 78dfb17d ldursh w29, [x11, #-5] - 300: b89b90af ldursw x15, [x5, #-71] - 304: fc403193 ldur d19, [x12, #3] - 308: bc42a36c ldur s12, [x27, #42] - 30c: fc07d396 stur d22, [x28, #125] - 310: bc1ec1f8 stur s24, [x15, #-20] - 314: f81e8f88 str x8, [x28, #-24]! - 318: b8025de6 str w6, [x15, #37]! - 31c: 38007c27 strb w7, [x1, #7]! - 320: 7801ee20 strh w0, [x17, #30]! - 324: f8454fb9 ldr x25, [x29, #84]! - 328: b85cce9a ldr w26, [x20, #-52]! - 32c: 385e7fba ldrb w26, [x29, #-25]! - 330: 7841af24 ldrh w4, [x25, #26]! - 334: 389ebd1c ldrsb x28, [x8, #-21]! - 338: 789fadd1 ldrsh x17, [x14, #-6]! - 33c: 78c0aefc ldrsh w28, [x23, #10]! - 340: b89c0f7e ldrsw x30, [x27, #-64]! - 344: fc50efd4 ldr d20, [x30, #-242]! - 348: bc414f71 ldr s17, [x27, #20]! - 34c: fc011c67 str d7, [x3, #17]! - 350: bc1f0d6d str s13, [x11, #-16]! - 354: f81c3526 str x6, [x9], #-61 - 358: b81e34b0 str w16, [x5], #-29 - 35c: 3800f7bd strb w29, [x29], #15 - 360: 78012684 strh w4, [x20], #18 - 364: f842e653 ldr x19, [x18], #46 - 368: b8417456 ldr w22, [x2], #23 - 36c: 385e2467 ldrb w7, [x3], #-30 - 370: 785e358b ldrh w11, [x12], #-29 - 374: 389e34c8 ldrsb x8, [x6], #-29 - 378: 788046f8 ldrsh x24, [x23], #4 - 37c: 78c00611 ldrsh w17, [x16], #0 - 380: b89f8680 ldrsw x0, [x20], #-8 - 384: fc582454 ldr d20, [x2], #-126 - 388: bc5987d3 ldr s19, [x30], #-104 - 38c: fc076624 str d4, [x17], #118 - 390: bc190675 str s21, [x19], #-112 - 394: f833785a str x26, [x2, x19, lsl #3] - 398: b82fd809 str w9, [x0, w15, sxtw #2] - 39c: 3821799a strb w26, [x12, x1, lsl #0] - 3a0: 782a7975 strh w21, [x11, x10, lsl #1] - 3a4: f870eaf0 ldr x16, [x23, x16, sxtx] - 3a8: b871d96a ldr w10, [x11, w17, sxtw #2] - 3ac: 386b7aed ldrb w13, [x23, x11, lsl #0] - 3b0: 7875689b ldrh w27, [x4, x21] - 3b4: 38afd91a ldrsb x26, [x8, w15, sxtw #0] - 3b8: 78a2c955 ldrsh x21, [x10, w2, sxtw] - 3bc: 78ee6bc8 ldrsh w8, [x30, x14] - 3c0: b8b4f9dd ldrsw x29, [x14, x20, sxtx #2] - 3c4: fc76eb7e ldr d30, [x27, x22, sxtx] - 3c8: bc76692d ldr s13, [x9, x22] - 3cc: fc31db28 str d8, [x25, w17, sxtw #3] - 3d0: bc255b01 str s1, [x24, w5, uxtw #2] - 3d4: f91c52aa str x10, [x21, #14496] - 3d8: b91c3fb2 str w18, [x29, #7228] - 3dc: 391f8877 strb w23, [x3, #2018] - 3e0: 791ac97c strh w28, [x11, #3428] - 3e4: f95c1758 ldr x24, [x26, #14376] - 3e8: b95b3c55 ldr w21, [x2, #6972] - 3ec: 395ce0a4 ldrb w4, [x5, #1848] - 3f0: 795851ce ldrh w14, [x14, #3112] - 3f4: 399e9f64 ldrsb x4, [x27, #1959] - 3f8: 79993764 ldrsh x4, [x27, #3226] - 3fc: 79d9af8a ldrsh w10, [x28, #3286] - 400: b99eea2a ldrsw x10, [x17, #7912] - 404: fd5a2f8d ldr d13, [x28, #13400] - 408: bd5dac78 ldr s24, [x3, #7596] - 40c: fd1e0182 str d2, [x12, #15360] - 410: bd195c31 str s17, [x1, #6492] - 414: 58000010 ldr x16, 414 <back+0x414> - 418: 1800000d ldr w13, 418 <back+0x418> - 41c: f8981240 prfum pldl1keep, [x18, #-127] - 420: d8ffdf00 prfm pldl1keep, 0 <back> - 424: f8a27a80 prfm pldl1keep, [x20, x2, lsl #3] - 428: f99af920 prfm pldl1keep, [x9, #13808] - 42c: 1a0202e8 adc w8, w23, w2 - 430: 3a130078 adcs w24, w3, w19 - 434: 5a1d0316 sbc w22, w24, w29 - 438: 7a03036c sbcs w12, w27, w3 - 43c: 9a0102eb adc x11, x23, x1 - 440: ba1700bd adcs x29, x5, x23 - 444: da0c0329 sbc x9, x25, x12 - 448: fa16000c sbcs x12, x0, x22 - 44c: 0b23459a add w26, w12, w3, uxtw #1 - 450: 2b328a14 adds w20, w16, w18, sxtb #2 - 454: cb274bde sub x30, x30, w7, uxtw #2 - 458: 6b222eab subs w11, w21, w2, uxth #3 - 45c: 8b214b42 add x2, x26, w1, uxtw #2 - 460: ab34a7b2 adds x18, x29, w20, sxth #1 - 464: cb24520e sub x14, x16, w4, uxtw #4 - 468: eb378e20 subs x0, x17, w23, sxtb #3 - 46c: 3a565283 ccmn w20, w22, #0x3, pl // pl = nfrst - 470: 7a420321 ccmp w25, w2, #0x1, eq // eq = none - 474: ba58c247 ccmn x18, x24, #0x7, gt - 478: fa4d5106 ccmp x8, x13, #0x6, pl // pl = nfrst - 47c: 3a426924 ccmn w9, #0x2, #0x4, vs - 480: 7a5b0847 ccmp w2, #0x1b, #0x7, eq // eq = none - 484: ba413a02 ccmn x16, #0x1, #0x2, cc // cc = lo, ul, last - 488: fa5fba23 ccmp x17, #0x1f, #0x3, lt // lt = tstop - 48c: 1a979377 csel w23, w27, w23, ls // ls = plast - 490: 1a86640a csinc w10, w0, w6, vs - 494: 5a89300b csinv w11, w0, w9, cc // cc = lo, ul, last - 498: 5a923771 csneg w17, w27, w18, cc // cc = lo, ul, last - 49c: 9a8b720c csel x12, x16, x11, vc - 4a0: 9a868786 csinc x6, x28, x6, hi // hi = pmore - 4a4: da9a736d csinv x13, x27, x26, vc - 4a8: da9256dd csneg x29, x22, x18, pl // pl = nfrst - 4ac: 5ac0026c rbit w12, w19 - 4b0: 5ac00657 rev16 w23, w18 - 4b4: 5ac00b89 rev w9, w28 - 4b8: 5ac01262 clz w2, w19 - 4bc: 5ac017b9 cls w25, w29 - 4c0: dac002e4 rbit x4, x23 - 4c4: dac0065d rev16 x29, x18 - 4c8: dac00907 rev32 x7, x8 - 4cc: dac00e2d rev x13, x17 - 4d0: dac01011 clz x17, x0 - 4d4: dac01752 cls x18, x26 - 4d8: 1ad0098b udiv w11, w12, w16 - 4dc: 1ac70d24 sdiv w4, w9, w7 - 4e0: 1ad020ec lsl w12, w7, w16 - 4e4: 1ad72613 lsr w19, w16, w23 - 4e8: 1ac62887 asr w7, w4, w6 - 4ec: 1ad72e95 ror w21, w20, w23 - 4f0: 9adc0990 udiv x16, x12, x28 - 4f4: 9acd0d84 sdiv x4, x12, x13 - 4f8: 9ac721a9 lsl x9, x13, x7 - 4fc: 9acf277c lsr x28, x27, x15 - 500: 9ace2bd4 asr x20, x30, x14 - 504: 9ade2e4e ror x14, x18, x30 - 508: 9bc77d63 umulh x3, x11, x7 - 50c: 9b587e97 smulh x23, x20, x24 - 510: 1b1524a2 madd w2, w5, w21, w9 - 514: 1b04a318 msub w24, w24, w4, w8 - 518: 9b0f4d8b madd x11, x12, x15, x19 - 51c: 9b0ce73d msub x29, x25, x12, x25 - 520: 9b2c5971 smaddl x17, w11, w12, x22 - 524: 9b34c87c smsubl x28, w3, w20, x18 - 528: 9bbc6887 umaddl x7, w4, w28, x26 - 52c: 9bb19556 umsubl x22, w10, w17, x5 - 530: 1e310871 fmul s17, s3, s17 - 534: 1e261a2b fdiv s11, s17, s6 - 538: 1e2928fd fadd s29, s7, s9 - 53c: 1e333987 fsub s7, s12, s19 - 540: 1e230ae0 fmul s0, s23, s3 - 544: 1e75087a fmul d26, d3, d21 - 548: 1e651a60 fdiv d0, d19, d5 - 54c: 1e692b40 fadd d0, d26, d9 - 550: 1e753ab9 fsub d25, d21, d21 - 554: 1e7309b0 fmul d16, d13, d19 - 558: 1f00425d fmadd s29, s18, s0, s16 - 55c: 1f1d95b7 fmsub s23, s13, s29, s5 - 560: 1f2a38e9 fnmadd s9, s7, s10, s14 - 564: 1f2f5f99 fnmadd s25, s28, s15, s23 - 568: 1f5545a6 fmadd d6, d13, d21, d17 - 56c: 1f429ea3 fmsub d3, d21, d2, d7 - 570: 1f65472a fnmadd d10, d25, d5, d17 - 574: 1f7449ce fnmadd d14, d14, d20, d18 - 578: 1e20404f fmov s15, s2 - 57c: 1e20c0f2 fabs s18, s7 - 580: 1e2140c3 fneg s3, s6 - 584: 1e21c02c fsqrt s12, s1 - 588: 1e22c009 fcvt d9, s0 - 58c: 1e6040a4 fmov d4, d5 - 590: 1e60c1e3 fabs d3, d15 - 594: 1e614331 fneg d17, d25 - 598: 1e61c30c fsqrt d12, d24 - 59c: 1e6240b5 fcvt s21, d5 - 5a0: 1e3802a4 fcvtzs w4, s21 - 5a4: 9e38007b fcvtzs x27, s3 - 5a8: 1e78011d fcvtzs w29, d8 - 5ac: 9e7802a9 fcvtzs x9, d21 - 5b0: 1e2203b4 scvtf s20, w29 - 5b4: 9e220107 scvtf s7, x8 - 5b8: 1e6202ac scvtf d12, w21 - 5bc: 9e6202b0 scvtf d16, x21 - 5c0: 1e2600b2 fmov w18, s5 - 5c4: 9e660119 fmov x25, d8 - 5c8: 1e270352 fmov s18, w26 - 5cc: 9e670160 fmov d0, x11 - 5d0: 1e262200 fcmp s16, s6 - 5d4: 1e7d2200 fcmp d16, d29 - 5d8: 1e2023c8 fcmp s30, #0.0 - 5dc: 1e602128 fcmp d9, #0.0 - 5e0: 293e119b stp w27, w4, [x12, #-16] - 5e4: 294a2543 ldp w3, w9, [x10, #80] - 5e8: 69480c70 ldpsw x16, x3, [x3, #64] - 5ec: a934726a stp x10, x28, [x19, #-192] - 5f0: a97448f3 ldp x19, x18, [x7, #-192] - 5f4: 298243ca stp w10, w16, [x30, #16]! - 5f8: 29e21242 ldp w2, w4, [x18, #-240]! - 5fc: 69c64db8 ldpsw x24, x19, [x13, #48]! - 600: a9800311 stp x17, x0, [x24, #0]! - 604: a9f4686e ldp x14, x26, [x3, #-192]! - 608: 288a0416 stp w22, w1, [x0], #80 - 60c: 28fe2812 ldp w18, w10, [x0], #-16 - 610: 68fe62d8 .inst 0x68fe62d8 ; undefined - 614: a885308c stp x12, x12, [x4], #80 - 618: a8f12664 ldp x4, x9, [x19], #-240 - 61c: 282468d2 stnp w18, w26, [x6, #-224] - 620: 284e5035 ldnp w21, w20, [x1, #112] - 624: a8327699 stnp x25, x29, [x20, #-224] - 628: a84716e1 ldnp x1, x5, [x23, #112] - 62c: 0c407284 ld1 {v4.8b}, [x20] - 630: 4cdfa158 ld1 {v24.16b, v25.16b}, [x10], #32 - 634: 0ccf6cd8 ld1 {v24.1d-v26.1d}, [x6], x15 - 638: 4cdf2483 ld1 {v3.8h-v6.8h}, [x4], #64 - 63c: 0d40c0c2 ld1r {v2.8b}, [x6] - 640: 4ddfc9cd ld1r {v13.4s}, [x14], #4 - 644: 0dd8ceaf ld1r {v15.1d}, [x21], x24 - 648: 4c408ea9 ld2 {v9.2d, v10.2d}, [x21] - 64c: 0cdf86bd ld2 {v29.4h, v30.4h}, [x21], #16 - 650: 4d60c1c8 ld2r {v8.16b, v9.16b}, [x14] - 654: 0dffca87 ld2r {v7.2s, v8.2s}, [x20], #8 - 658: 4de3cc7c ld2r {v28.2d, v29.2d}, [x3], x3 - 65c: 4cdd497b ld3 {v27.4s-v29.4s}, [x11], x29 - 660: 0c404950 ld3 {v16.2s-v18.2s}, [x10] - 664: 4d40e595 ld3r {v21.8h-v23.8h}, [x12] - 668: 4ddfeba4 ld3r {v4.4s-v6.4s}, [x29], #12 - 66c: 0dd3ed38 ld3r {v24.1d-v26.1d}, [x9], x19 - 670: 4cdf046a ld4 {v10.8h-v13.8h}, [x3], #64 - 674: 0cc9039b ld4 {v27.8b-v30.8b}, [x28], x9 - 678: 0d60e3d5 ld4r {v21.8b-v24.8b}, [x30] - 67c: 0dffe5d7 ld4r {v23.4h-v26.4h}, [x14], #8 - 680: 0df4e9a4 ld4r {v4.2s-v7.2s}, [x13], x20 - 684: ba5fd3e3 ccmn xzr, xzr, #0x3, le - 688: 3a5f03e5 ccmn wzr, wzr, #0x5, eq // eq = none - 68c: fa411be4 ccmp xzr, #0x1, #0x4, ne // ne = any - 690: 7a42cbe2 ccmp wzr, #0x2, #0x2, gt - 694: 93df03ff ror xzr, xzr, #0 - 698: c820ffff stlxp w0, xzr, xzr, [sp] - 69c: 8822fc7f stlxp w2, wzr, wzr, [x3] - 6a0: c8247cbf stxp w4, xzr, xzr, [x5] - 6a4: 88267fff stxp w6, wzr, wzr, [sp] - 6a8: 4e010fe0 dup v0.16b, wzr - 6ac: 4e081fe1 mov v1.d[0], xzr - 6b0: 4e0c1fe1 mov v1.s[1], wzr - 6b4: 4e0a1fe1 mov v1.h[2], wzr - 6b8: 4e071fe1 mov v1.b[3], wzr - 6bc: 4cc0ac3f ld1 {v31.2d, v0.2d}, [x1], x0 - 6c0: 1e601000 fmov d0, #2.000000000000000000e+00 - 6c4: 1e603000 fmov d0, #2.125000000000000000e+00 - 6c8: 1e621000 fmov d0, #4.000000000000000000e+00 - 6cc: 1e623000 fmov d0, #4.250000000000000000e+00 - 6d0: 1e641000 fmov d0, #8.000000000000000000e+00 - 6d4: 1e643000 fmov d0, #8.500000000000000000e+00 - 6d8: 1e661000 fmov d0, #1.600000000000000000e+01 - 6dc: 1e663000 fmov d0, #1.700000000000000000e+01 - 6e0: 1e681000 fmov d0, #1.250000000000000000e-01 - 6e4: 1e683000 fmov d0, #1.328125000000000000e-01 - 6e8: 1e6a1000 fmov d0, #2.500000000000000000e-01 - 6ec: 1e6a3000 fmov d0, #2.656250000000000000e-01 - 6f0: 1e6c1000 fmov d0, #5.000000000000000000e-01 - 6f4: 1e6c3000 fmov d0, #5.312500000000000000e-01 - 6f8: 1e6e1000 fmov d0, #1.000000000000000000e+00 - 6fc: 1e6e3000 fmov d0, #1.062500000000000000e+00 - 700: 1e701000 fmov d0, #-2.000000000000000000e+00 - 704: 1e703000 fmov d0, #-2.125000000000000000e+00 - 708: 1e721000 fmov d0, #-4.000000000000000000e+00 - 70c: 1e723000 fmov d0, #-4.250000000000000000e+00 - 710: 1e741000 fmov d0, #-8.000000000000000000e+00 - 714: 1e743000 fmov d0, #-8.500000000000000000e+00 - 718: 1e761000 fmov d0, #-1.600000000000000000e+01 - 71c: 1e763000 fmov d0, #-1.700000000000000000e+01 - 720: 1e781000 fmov d0, #-1.250000000000000000e-01 - 724: 1e783000 fmov d0, #-1.328125000000000000e-01 - 728: 1e7a1000 fmov d0, #-2.500000000000000000e-01 - 72c: 1e7a3000 fmov d0, #-2.656250000000000000e-01 - 730: 1e7c1000 fmov d0, #-5.000000000000000000e-01 - 734: 1e7c3000 fmov d0, #-5.312500000000000000e-01 - 738: 1e7e1000 fmov d0, #-1.000000000000000000e+00 - 73c: 1e7e3000 fmov d0, #-1.062500000000000000e+00 - 740: f8358305 swp x21, x5, [x24] - 744: f82d01ed ldadd x13, x13, [x15] - 748: f8361353 ldclr x22, x19, [x26] - 74c: f839234a ldeor x25, x10, [x26] - 750: f82531fb ldset x5, x27, [x15] - 754: f8335165 ldsmin x19, x5, [x11] - 758: f83a4080 ldsmax x26, x0, [x4] - 75c: f83673d7 ldumin x22, x23, [x30] - 760: f832611c ldumax x18, x28, [x8] - 764: f8ad837d swpa x13, x29, [x27] - 768: f8ab01a5 ldadda x11, x5, [x13] - 76c: f8a112b8 ldclra x1, x24, [x21] - 770: f8bb2311 ldeora x27, x17, [x24] - 774: f8b230be ldseta x18, x30, [x5] - 778: f8a75336 ldsmina x7, x22, [x25] - 77c: f8a4427a ldsmaxa x4, x26, [x19] - 780: f8a6707e ldumina x6, x30, [x3] - 784: f8b860b7 ldumaxa x24, x23, [x5] - 788: f8f88392 swpal x24, x18, [x28] - 78c: f8f300ff ldaddal x19, xzr, [x7] - 790: f8ed1386 ldclral x13, x6, [x28] - 794: f8e822af ldeoral x8, x15, [x21] - 798: f8e2302d ldsetal x2, x13, [x1] - 79c: f8f1533d ldsminal x17, x29, [x25] - 7a0: f8f941d2 ldsmaxal x25, x18, [x14] - 7a4: f8ff7366 lduminal xzr, x6, [x27] - 7a8: f8f061e5 ldumaxal x16, x5, [x15] - 7ac: f86b8072 swpl x11, x18, [x3] - 7b0: f87a0054 ldaddl x26, x20, [x2] - 7b4: f86b1164 ldclrl x11, x4, [x11] - 7b8: f87e22f3 ldeorl x30, x19, [x23] - 7bc: f86331cf ldsetl x3, x15, [x14] - 7c0: f87e5296 ldsminl x30, x22, [x20] - 7c4: f8674305 ldsmaxl x7, x5, [x24] - 7c8: f87771f0 lduminl x23, x16, [x15] - 7cc: f86b6013 ldumaxl x11, x19, [x0] - 7d0: b83c803c swp w28, w28, [x1] - 7d4: b82b0195 ldadd w11, w21, [x12] - 7d8: b83d1240 ldclr w29, w0, [x18] - 7dc: b8252320 ldeor w5, w0, [x25] - 7e0: b82e3340 ldset w14, w0, [x26] - 7e4: b83c53b2 ldsmin w28, w18, [x29] - 7e8: b82f43a1 ldsmax w15, w1, [x29] - 7ec: b828739a ldumin w8, w26, [x28] - 7f0: b831608e ldumax w17, w14, [x4] - 7f4: b8b88039 swpa w24, w25, [x1] - 7f8: b8aa0231 ldadda w10, w17, [x17] - 7fc: b8bd12b4 ldclra w29, w20, [x21] - 800: b8bd2189 ldeora w29, w9, [x12] - 804: b8ab30a6 ldseta w11, w6, [x5] - 808: b8b552a7 ldsmina w21, w7, [x21] - 80c: b8aa4197 ldsmaxa w10, w23, [x12] - 810: b8b57145 ldumina w21, w5, [x10] - 814: b8be6254 ldumaxa w30, w20, [x18] - 818: b8ed80b7 swpal w13, w23, [x5] - 81c: b8ef00b8 ldaddal w15, w24, [x5] - 820: b8e9132a ldclral w9, w10, [x25] - 824: b8f42231 ldeoral w20, w17, [x17] - 828: b8ec33d2 ldsetal w12, w18, [x30] - 82c: b8e35323 ldsminal w3, w3, [x25] - 830: b8fa4159 ldsmaxal w26, w25, [x10] - 834: b8e273eb lduminal w2, w11, [sp] - 838: b8e760a2 ldumaxal w7, w2, [x5] - 83c: b8608287 swpl w0, w7, [x20] - 840: b865005f staddl w5, [x2] - 844: b87b1379 ldclrl w27, w25, [x27] - 848: b87e2358 ldeorl w30, w24, [x26] - 84c: b86f32c2 ldsetl w15, w2, [x22] - 850: b86053e3 ldsminl w0, w3, [sp] - 854: b86f4154 ldsmaxl w15, w20, [x10] - 858: b87671d5 lduminl w22, w21, [x14] - 85c: b866605e ldumaxl w6, w30, [x2] + 0: 8b18ec0f add x15, x0, x24, lsl #59 + 4: cb9636d1 sub x17, x22, x22, asr #13 + 8: ab1ce74a adds x10, x26, x28, lsl #57 + c: eb184a19 subs x25, x16, x24, lsl #18 + 10: 0b1c1ca8 add w8, w5, w28, lsl #7 + 14: 4b817388 sub w8, w28, w1, asr #28 + 18: 2b01004c adds w12, w2, w1 + 1c: 6b5164b7 subs w23, w5, w17, lsr #25 + 20: 8a0d5595 and x21, x12, x13, lsl #21 + 24: aa9791f5 orr x21, x15, x23, asr #36 + 28: ca9bc316 eor x22, x24, x27, asr #48 + 2c: ea82d1f6 ands x22, x15, x2, asr #52 + 30: 0a980e21 and w1, w17, w24, asr #3 + 34: 2a862c45 orr w5, w2, w6, asr #11 + 38: 4a453037 eor w23, w1, w5, lsr #12 + 3c: 6a8e5180 ands w0, w12, w14, asr #20 + 40: 8a621cc1 bic x1, x6, x2, lsr #7 + 44: aa24bd1e orn x30, x8, x4, lsl #47 + 48: cab4d6d1 eon x17, x22, x20, asr #53 + 4c: eaa591fd bics x29, x15, x5, asr #36 + 50: 0a7d6efe bic w30, w23, w29, lsr #27 + 54: 2a2253ac orn w12, w29, w2, lsl #20 + 58: 4aa61187 eon w7, w12, w6, asr #4 + 5c: 6aa755b0 bics w16, w13, w7, asr #21 + 60: 110b5a25 add w5, w17, #0x2d6 + 64: 31056e0a adds w10, w16, #0x15b + 68: 510f48ba sub w26, w5, #0x3d2 + 6c: 710ac715 subs w21, w24, #0x2b1 + 70: 910f6e0a add x10, x16, #0x3db + 74: b10a65ef adds x15, x15, #0x299 + 78: d1009e98 sub x24, x20, #0x27 + 7c: f10131aa subs x10, x13, #0x4c + 80: 121d4e67 and w7, w19, #0x7ffff8 + 84: 32043e25 orr w5, w17, #0xf0000fff + 88: 52132390 eor w16, w28, #0x3fe000 + 8c: 72160b0e ands w14, w24, #0x1c00 + 90: 9273e76e and x14, x27, #0xffffffffffffe07f + 94: b256416c orr x12, x11, #0x7fffc0000000000 + 98: d24b5002 eor x2, x0, #0xffe00000000003ff + 9c: f266da8d ands x13, x20, #0xfffffffffc01ffff + a0: 14000000 b a0 <back+0xa0> + a4: 17ffffd7 b 0 <back> + a8: 140001ee b 860 <forth> + ac: 94000000 bl ac <back+0xac> + b0: 97ffffd4 bl 0 <back> + b4: 940001eb bl 860 <forth> + b8: 3400000f cbz w15, b8 <back+0xb8> + bc: 34fffa2f cbz w15, 0 <back> + c0: 34003d0f cbz w15, 860 <forth> + c4: 3500001c cbnz w28, c4 <back+0xc4> + c8: 35fff9dc cbnz w28, 0 <back> + cc: 35003cbc cbnz w28, 860 <forth> + d0: b400001b cbz x27, d0 <back+0xd0> + d4: b4fff97b cbz x27, 0 <back> + d8: b4003c5b cbz x27, 860 <forth> + dc: b5000000 cbnz x0, dc <back+0xdc> + e0: b5fff900 cbnz x0, 0 <back> + e4: b5003be0 cbnz x0, 860 <forth> + e8: 1000000d adr x13, e8 <back+0xe8> + ec: 10fff8ad adr x13, 0 <back> + f0: 10003b8d adr x13, 860 <forth> + f4: 90000003 adrp x3, 0 <back> + f8: 36380015 tbz w21, #7, f8 <back+0xf8> + fc: 363ff835 tbz w21, #7, 0 <back> + 100: 36383b15 tbz w21, #7, 860 <forth> + 104: 3748000f tbnz w15, #9, 104 <back+0x104> + 108: 374ff7cf tbnz w15, #9, 0 <back> + 10c: 37483aaf tbnz w15, #9, 860 <forth> + 110: 12a14bee mov w14, #0xf5a0ffff // #-173998081 + 114: 5283bb51 mov w17, #0x1dda // #7642 + 118: 72858ebb movk w27, #0x2c75 + 11c: 92c98881 mov x1, #0xffffb3bbffffffff // #-83854941487105 + 120: d2aa50d4 mov x20, #0x52860000 // #1384513536 + 124: f2afd9d4 movk x20, #0x7ece, lsl #16 + 128: 935c504d sbfiz x13, x2, #36, #21 + 12c: 33133e90 bfi w16, w20, #13, #16 + 130: 5309196b ubfiz w11, w11, #23, #7 + 134: 93595482 sbfiz x2, x4, #39, #22 + 138: b3424e0d bfxil x13, x16, #2, #18 + 13c: d3481728 ubfiz x8, x25, #56, #6 + 140: 138a3b7d extr w29, w27, w10, #14 + 144: 93c66286 extr x6, x20, x6, #24 + 148: 54000000 b.eq 148 <back+0x148> // b.none + 14c: 54fff5a0 b.eq 0 <back> // b.none + 150: 54003880 b.eq 860 <forth> // b.none + 154: 54000001 b.ne 154 <back+0x154> // b.any + 158: 54fff541 b.ne 0 <back> // b.any + 15c: 54003821 b.ne 860 <forth> // b.any + 160: 54000002 b.cs 160 <back+0x160> // b.hs, b.nlast + 164: 54fff4e2 b.cs 0 <back> // b.hs, b.nlast + 168: 540037c2 b.cs 860 <forth> // b.hs, b.nlast + 16c: 54000002 b.cs 16c <back+0x16c> // b.hs, b.nlast + 170: 54fff482 b.cs 0 <back> // b.hs, b.nlast + 174: 54003762 b.cs 860 <forth> // b.hs, b.nlast + 178: 54000003 b.cc 178 <back+0x178> // b.lo, b.ul, b.last + 17c: 54fff423 b.cc 0 <back> // b.lo, b.ul, b.last + 180: 54003703 b.cc 860 <forth> // b.lo, b.ul, b.last + 184: 54000003 b.cc 184 <back+0x184> // b.lo, b.ul, b.last + 188: 54fff3c3 b.cc 0 <back> // b.lo, b.ul, b.last + 18c: 540036a3 b.cc 860 <forth> // b.lo, b.ul, b.last + 190: 54000004 b.mi 190 <back+0x190> // b.first + 194: 54fff364 b.mi 0 <back> // b.first + 198: 54003644 b.mi 860 <forth> // b.first + 19c: 54000005 b.pl 19c <back+0x19c> // b.nfrst + 1a0: 54fff305 b.pl 0 <back> // b.nfrst + 1a4: 540035e5 b.pl 860 <forth> // b.nfrst + 1a8: 54000006 b.vs 1a8 <back+0x1a8> + 1ac: 54fff2a6 b.vs 0 <back> + 1b0: 54003586 b.vs 860 <forth> + 1b4: 54000007 b.vc 1b4 <back+0x1b4> + 1b8: 54fff247 b.vc 0 <back> + 1bc: 54003527 b.vc 860 <forth> + 1c0: 54000008 b.hi 1c0 <back+0x1c0> // b.pmore + 1c4: 54fff1e8 b.hi 0 <back> // b.pmore + 1c8: 540034c8 b.hi 860 <forth> // b.pmore + 1cc: 54000009 b.ls 1cc <back+0x1cc> // b.plast + 1d0: 54fff189 b.ls 0 <back> // b.plast + 1d4: 54003469 b.ls 860 <forth> // b.plast + 1d8: 5400000a b.ge 1d8 <back+0x1d8> // b.tcont + 1dc: 54fff12a b.ge 0 <back> // b.tcont + 1e0: 5400340a b.ge 860 <forth> // b.tcont + 1e4: 5400000b b.lt 1e4 <back+0x1e4> // b.tstop + 1e8: 54fff0cb b.lt 0 <back> // b.tstop + 1ec: 540033ab b.lt 860 <forth> // b.tstop + 1f0: 5400000c b.gt 1f0 <back+0x1f0> + 1f4: 54fff06c b.gt 0 <back> + 1f8: 5400334c b.gt 860 <forth> + 1fc: 5400000d b.le 1fc <back+0x1fc> + 200: 54fff00d b.le 0 <back> + 204: 540032ed b.le 860 <forth> + 208: 5400000e b.al 208 <back+0x208> + 20c: 54ffefae b.al 0 <back> + 210: 5400328e b.al 860 <forth> + 214: 5400000f b.nv 214 <back+0x214> + 218: 54ffef4f b.nv 0 <back> + 21c: 5400322f b.nv 860 <forth> + 220: d40d2881 svc #0x6944 + 224: d40ea5c2 hvc #0x752e + 228: d40518a3 smc #0x28c5 + 22c: d42eca40 brk #0x7652 + 230: d44a2e60 hlt #0x5173 + 234: d503201f nop + 238: d69f03e0 eret + 23c: d6bf03e0 drps + 240: d5033fdf isb + 244: d5033d9f dsb ld + 248: d5033bbf dmb ish + 24c: d61f0120 br x9 + 250: d63f0120 blr x9 + 254: c8027d7d stxr w2, x29, [x11] + 258: c816ff85 stlxr w22, x5, [x28] + 25c: c85f7e8e ldxr x14, [x20] + 260: c85ffe7d ldaxr x29, [x19] + 264: c89ffea6 stlr x6, [x21] + 268: c8dffc73 ldar x19, [x3] + 26c: 880c7f63 stxr w12, w3, [x27] + 270: 8811fdfa stlxr w17, w26, [x15] + 274: 885f7dcd ldxr w13, [x14] + 278: 885fff4c ldaxr w12, [x26] + 27c: 889ffe28 stlr w8, [x17] + 280: 88dfffd5 ldar w21, [x30] + 284: 48007d6f stxrh w0, w15, [x11] + 288: 4811fc34 stlxrh w17, w20, [x1] + 28c: 485f7d1d ldxrh w29, [x8] + 290: 485ffd91 ldaxrh w17, [x12] + 294: 489ffc8b stlrh w11, [x4] + 298: 48dffc90 ldarh w16, [x4] + 29c: 080e7c85 stxrb w14, w5, [x4] + 2a0: 081bfe11 stlxrb w27, w17, [x16] + 2a4: 085f7f66 ldxrb w6, [x27] + 2a8: 085fff1b ldaxrb w27, [x24] + 2ac: 089ffe8a stlrb w10, [x20] + 2b0: 08dfff49 ldarb w9, [x26] + 2b4: c87f7b85 ldxp x5, x30, [x28] + 2b8: c87fa66a ldaxp x10, x9, [x19] + 2bc: c82b5590 stxp w11, x16, x21, [x12] + 2c0: c82adc94 stlxp w10, x20, x23, [x4] + 2c4: 887f0416 ldxp w22, w1, [x0] + 2c8: 887f8503 ldaxp w3, w1, [x8] + 2cc: 88205fc9 stxp w0, w9, w23, [x30] + 2d0: 8837c560 stlxp w23, w0, w17, [x11] + 2d4: f81e1146 stur x6, [x10, #-31] + 2d8: b81fb007 stur w7, [x0, #-5] + 2dc: 381f3205 sturb w5, [x16, #-13] + 2e0: 7801f27e sturh w30, [x19, #31] + 2e4: f8477130 ldur x16, [x9, #119] + 2e8: b843b208 ldur w8, [x16, #59] + 2ec: 385f918a ldurb w10, [x12, #-7] + 2f0: 785da12e ldurh w14, [x9, #-38] + 2f4: 389f83d8 ldursb x24, [x30, #-8] + 2f8: 78817087 ldursh x7, [x4, #23] + 2fc: 78dd91d1 ldursh w17, [x14, #-39] + 300: b89e136b ldursw x11, [x27, #-31] + 304: fc4410ec ldur d12, [x7, #65] + 308: bc5fe200 ldur s0, [x16, #-2] + 30c: fc15f2ed stur d13, [x23, #-161] + 310: bc1c2075 stur s21, [x3, #-62] + 314: f8064ca2 str x2, [x5, #100]! + 318: b81a4c29 str w9, [x1, #-92]! + 31c: 381fbfdb strb w27, [x30, #-5]! + 320: 7800cdfb strh w27, [x15, #12]! + 324: f852ce24 ldr x4, [x17, #-212]! + 328: b841eef5 ldr w21, [x23, #30]! + 32c: 385f9e2d ldrb w13, [x17, #-7]! + 330: 785cec19 ldrh w25, [x0, #-50]! + 334: 389ebea1 ldrsb x1, [x21, #-21]! + 338: 789caebc ldrsh x28, [x21, #-54]! + 33c: 78c02c8b ldrsh w11, [x4, #2]! + 340: b883dd31 ldrsw x17, [x9, #61]! + 344: fc427e7d ldr d29, [x19, #39]! + 348: bc5abed6 ldr s22, [x22, #-85]! + 34c: fc11ff29 str d9, [x25, #-225]! + 350: bc1f1c49 str s9, [x2, #-15]! + 354: f81be6ed str x13, [x23], #-66 + 358: b800a611 str w17, [x16], #10 + 35c: 381e05c1 strb w1, [x14], #-32 + 360: 78006411 strh w17, [x0], #6 + 364: f855473b ldr x27, [x25], #-172 + 368: b85da72d ldr w13, [x25], #-38 + 36c: 385e372b ldrb w11, [x25], #-29 + 370: 784144be ldrh w30, [x5], #20 + 374: 389f94e9 ldrsb x9, [x7], #-7 + 378: 789c2460 ldrsh x0, [x3], #-62 + 37c: 78c1f5c7 ldrsh w7, [x14], #31 + 380: b8827771 ldrsw x17, [x27], #39 + 384: fc515491 ldr d17, [x4], #-235 + 388: bc4226ba ldr s26, [x21], #34 + 38c: fc1c7625 str d5, [x17], #-57 + 390: bc1935ad str s13, [x13], #-109 + 394: f824da06 str x6, [x16, w4, sxtw #3] + 398: b834db09 str w9, [x24, w20, sxtw #2] + 39c: 38237ba3 strb w3, [x29, x3, lsl #0] + 3a0: 783e6a2a strh w10, [x17, x30] + 3a4: f867497b ldr x27, [x11, w7, uxtw] + 3a8: b87949ee ldr w14, [x15, w25, uxtw] + 3ac: 387379d8 ldrb w24, [x14, x19, lsl #0] + 3b0: 7866c810 ldrh w16, [x0, w6, sxtw] + 3b4: 38acd98a ldrsb x10, [x12, w12, sxtw #0] + 3b8: 78b0499a ldrsh x26, [x12, w16, uxtw] + 3bc: 78ee781a ldrsh w26, [x0, x14, lsl #1] + 3c0: b8bbf971 ldrsw x17, [x11, x27, sxtx #2] + 3c4: fc73d803 ldr d3, [x0, w19, sxtw #3] + 3c8: bc6979fa ldr s26, [x15, x9, lsl #2] + 3cc: fc30e9ab str d11, [x13, x16, sxtx] + 3d0: bc355a7a str s26, [x19, w21, uxtw #2] + 3d4: f91886a8 str x8, [x21, #12552] + 3d8: b918ef6a str w10, [x27, #6380] + 3dc: 391b15db strb w27, [x14, #1733] + 3e0: 791ac0f0 strh w16, [x7, #3424] + 3e4: f958753b ldr x27, [x9, #12520] + 3e8: b95a1958 ldr w24, [x10, #6680] + 3ec: 395b3f18 ldrb w24, [x24, #1743] + 3f0: 795800b4 ldrh w20, [x5, #3072] + 3f4: 39988891 ldrsb x17, [x4, #1570] + 3f8: 799a81ae ldrsh x14, [x13, #3392] + 3fc: 79dd172a ldrsh w10, [x25, #3722] + 400: b9981342 ldrsw x2, [x26, #6160] + 404: fd5d21da ldr d26, [x14, #14912] + 408: bd5e7c9c ldr s28, [x4, #7804] + 40c: fd1b526e str d14, [x19, #13984] + 410: bd18df97 str s23, [x28, #6364] + 414: 58002268 ldr x8, 860 <forth> + 418: 18ffdf51 ldr w17, 0 <back> + 41c: f8951080 prfum pldl1keep, [x4, #-175] + 420: d8000000 prfm pldl1keep, 420 <back+0x420> + 424: f8a4c900 prfm pldl1keep, [x8, w4, sxtw] + 428: f999e180 prfm pldl1keep, [x12, #13248] + 42c: 1a150374 adc w20, w27, w21 + 430: 3a060227 adcs w7, w17, w6 + 434: 5a1900c5 sbc w5, w6, w25 + 438: 7a0e017e sbcs w30, w11, w14 + 43c: 9a0b0223 adc x3, x17, x11 + 440: ba110159 adcs x25, x10, x17 + 444: da170207 sbc x7, x16, x23 + 448: fa050144 sbcs x4, x10, x5 + 44c: 0b2973c9 add w9, w30, w9, uxtx #4 + 450: 2b30a8a0 adds w0, w5, w16, sxth #2 + 454: cb3b8baf sub x15, x29, w27, sxtb #2 + 458: 6b21f12b subs w11, w9, w1, sxtx #4 + 45c: 8b264f02 add x2, x24, w6, uxtw #3 + 460: ab3a70d3 adds x19, x6, x26, uxtx #4 + 464: cb39ef48 sub x8, x26, x25, sxtx #3 + 468: eb29329a subs x26, x20, w9, uxth #4 + 46c: 3a5a41a7 ccmn w13, w26, #0x7, mi // mi = first + 470: 7a54310f ccmp w8, w20, #0xf, cc // cc = lo, ul, last + 474: ba4302c8 ccmn x22, x3, #0x8, eq // eq = none + 478: fa58a04a ccmp x2, x24, #0xa, ge // ge = tcont + 47c: 3a50490d ccmn w8, #0x10, #0xd, mi // mi = first + 480: 7a4c0a01 ccmp w16, #0xc, #0x1, eq // eq = none + 484: ba5f79e3 ccmn x15, #0x1f, #0x3, vc + 488: fa4c0aef ccmp x23, #0xc, #0xf, eq // eq = none + 48c: 1a9a30ee csel w14, w7, w26, cc // cc = lo, ul, last + 490: 1a9ed763 csinc w3, w27, w30, le + 494: 5a9702ab csinv w11, w21, w23, eq // eq = none + 498: 5a95c7da csneg w26, w30, w21, gt + 49c: 9a8d835c csel x28, x26, x13, hi // hi = pmore + 4a0: 9a909471 csinc x17, x3, x16, ls // ls = plast + 4a4: da8380ab csinv x11, x5, x3, hi // hi = pmore + 4a8: da93c461 csneg x1, x3, x19, gt + 4ac: 5ac00120 rbit w0, w9 + 4b0: 5ac005da rev16 w26, w14 + 4b4: 5ac00a2d rev w13, w17 + 4b8: 5ac0128b clz w11, w20 + 4bc: 5ac0163c cls w28, w17 + 4c0: dac0008d rbit x13, x4 + 4c4: dac007c1 rev16 x1, x30 + 4c8: dac009cd rev32 x13, x14 + 4cc: dac00d05 rev x5, x8 + 4d0: dac01322 clz x2, x25 + 4d4: dac01514 cls x20, x8 + 4d8: 1adb0b35 udiv w21, w25, w27 + 4dc: 1ad00d4d sdiv w13, w10, w16 + 4e0: 1ad1203c lsl w28, w1, w17 + 4e4: 1aca26f9 lsr w25, w23, w10 + 4e8: 1ac72867 asr w7, w3, w7 + 4ec: 1ace2fce ror w14, w30, w14 + 4f0: 9acf0acc udiv x12, x22, x15 + 4f4: 9acd0f22 sdiv x2, x25, x13 + 4f8: 9ad522e7 lsl x7, x23, x21 + 4fc: 9ac0258b lsr x11, x12, x0 + 500: 9adc293e asr x30, x9, x28 + 504: 9ad62cad ror x13, x5, x22 + 508: 9bc47ea5 umulh x5, x21, x4 + 50c: 9b477c51 smulh x17, x2, x7 + 510: 1b11318c madd w12, w12, w17, w12 + 514: 1b01edfe msub w30, w15, w1, w27 + 518: 9b117662 madd x2, x19, x17, x29 + 51c: 9b03fae4 msub x4, x23, x3, x30 + 520: 9b313eef smaddl x15, w23, w17, x15 + 524: 9b21b59b smsubl x27, w12, w1, x13 + 528: 9bac45a6 umaddl x6, w13, w12, x17 + 52c: 9ba6a839 umsubl x25, w1, w6, x10 + 530: 1e240871 fmul s17, s3, s4 + 534: 1e3518b0 fdiv s16, s5, s21 + 538: 1e312b63 fadd s3, s27, s17 + 53c: 1e2f3959 fsub s25, s10, s15 + 540: 1e200a2a fmul s10, s17, s0 + 544: 1e630b5c fmul d28, d26, d3 + 548: 1e7b1804 fdiv d4, d0, d27 + 54c: 1e6229dc fadd d28, d14, d2 + 550: 1e773b4c fsub d12, d26, d23 + 554: 1e610bcf fmul d15, d30, d1 + 558: 1f0534a4 fmadd s4, s5, s5, s13 + 55c: 1f1c85b5 fmsub s21, s13, s28, s1 + 560: 1f3d1c71 fnmadd s17, s3, s29, s7 + 564: 1f3d6b37 fnmadd s23, s25, s29, s26 + 568: 1f5e68ee fmadd d14, d7, d30, d26 + 56c: 1f4aa4f6 fmsub d22, d7, d10, d9 + 570: 1f6e24e7 fnmadd d7, d7, d14, d9 + 574: 1f6f630e fnmadd d14, d24, d15, d24 + 578: 1e204056 fmov s22, s2 + 57c: 1e20c060 fabs s0, s3 + 580: 1e214229 fneg s9, s17 + 584: 1e21c178 fsqrt s24, s11 + 588: 1e22c32f fcvt d15, s25 + 58c: 1e604064 fmov d4, d3 + 590: 1e60c2da fabs d26, d22 + 594: 1e61427e fneg d30, d19 + 598: 1e61c1cc fsqrt d12, d14 + 59c: 1e6240f1 fcvt s17, d7 + 5a0: 1e3801d8 fcvtzs w24, s14 + 5a4: 9e38034d fcvtzs x13, s26 + 5a8: 1e780022 fcvtzs w2, d1 + 5ac: 9e780165 fcvtzs x5, d11 + 5b0: 1e22026e scvtf s14, w19 + 5b4: 9e2202c1 scvtf s1, x22 + 5b8: 1e62023b scvtf d27, w17 + 5bc: 9e620136 scvtf d22, x9 + 5c0: 1e26006e fmov w14, s3 + 5c4: 9e66022c fmov x12, d17 + 5c8: 1e270368 fmov s8, w27 + 5cc: 9e67039d fmov d29, x28 + 5d0: 1e3e2000 fcmp s0, s30 + 5d4: 1e692180 fcmp d12, d9 + 5d8: 1e202148 fcmp s10, #0.0 + 5dc: 1e602328 fcmp d25, #0.0 + 5e0: 292e7b68 stp w8, w30, [x27, #-144] + 5e4: 294a4f15 ldp w21, w19, [x24, #80] + 5e8: 69626c50 ldpsw x16, x27, [x2, #-240] + 5ec: a93814d5 stp x21, x5, [x6, #-128] + 5f0: a97e679d ldp x29, x25, [x28, #-32] + 5f4: 29903408 stp w8, w13, [x0, #128]! + 5f8: 29ec5039 ldp w25, w20, [x1, #-160]! + 5fc: 69fc62ce ldpsw x14, x24, [x22, #-32]! + 600: a98504d1 stp x17, x1, [x6, #80]! + 604: a9fc4735 ldp x21, x17, [x25, #-64]! + 608: 28b05691 stp w17, w21, [x20], #-128 + 60c: 28c8705c ldp w28, w28, [x2], #64 + 610: 68e07953 ldpsw x19, x30, [x10], #-256 + 614: a8bf3e31 stp x17, x15, [x17], #-16 + 618: a8fe0331 ldp x17, x0, [x25], #-32 + 61c: 283c170e stnp w14, w5, [x24, #-32] + 620: 284e4c37 ldnp w23, w19, [x1, #112] + 624: a80419cb stnp x11, x6, [x14, #64] + 628: a8722f62 ldnp x2, x11, [x27, #-224] + 62c: 0c407230 ld1 {v16.8b}, [x17] + 630: 4cdfa13d ld1 {v29.16b, v30.16b}, [x9], #32 + 634: 0cd56f1e ld1 {v30.1d, v31.1d, v0.1d}, [x24], x21 + 638: 4cdf2440 ld1 {v0.8h-v3.8h}, [x2], #64 + 63c: 0d40c134 ld1r {v20.8b}, [x9] + 640: 4ddfc811 ld1r {v17.4s}, [x0], #4 + 644: 0ddaced5 ld1r {v21.1d}, [x22], x26 + 648: 4c408f33 ld2 {v19.2d, v20.2d}, [x25] + 64c: 0cdf84aa ld2 {v10.4h, v11.4h}, [x5], #16 + 650: 4d60c30a ld2r {v10.16b, v11.16b}, [x24] + 654: 0dffcbad ld2r {v13.2s, v14.2s}, [x29], #8 + 658: 4de2cf96 ld2r {v22.2d, v23.2d}, [x28], x2 + 65c: 4ccb489e ld3 {v30.4s, v31.4s, v0.4s}, [x4], x11 + 660: 0c40481d ld3 {v29.2s-v31.2s}, [x0] + 664: 4d40e777 ld3r {v23.8h-v25.8h}, [x27] + 668: 4ddfe943 ld3r {v3.4s-v5.4s}, [x10], #12 + 66c: 0dd6edd3 ld3r {v19.1d-v21.1d}, [x14], x22 + 670: 4cdf040e ld4 {v14.8h-v17.8h}, [x0], #64 + 674: 0cd902de ld4 {v30.8b, v31.8b, v0.8b, v1.8b}, [x22], x25 + 678: 0d60e019 ld4r {v25.8b-v28.8b}, [x0] + 67c: 0dffe50a ld4r {v10.4h-v13.4h}, [x8], #8 + 680: 0dfce8c1 ld4r {v1.2s-v4.2s}, [x6], x28 + 684: ba5fd3e3 ccmn xzr, xzr, #0x3, le + 688: 3a5f03e5 ccmn wzr, wzr, #0x5, eq // eq = none + 68c: fa411be4 ccmp xzr, #0x1, #0x4, ne // ne = any + 690: 7a42cbe2 ccmp wzr, #0x2, #0x2, gt + 694: 93df03ff ror xzr, xzr, #0 + 698: c820ffff stlxp w0, xzr, xzr, [sp] + 69c: 8822fc7f stlxp w2, wzr, wzr, [x3] + 6a0: c8247cbf stxp w4, xzr, xzr, [x5] + 6a4: 88267fff stxp w6, wzr, wzr, [sp] + 6a8: 4e010fe0 dup v0.16b, wzr + 6ac: 4e081fe1 mov v1.d[0], xzr + 6b0: 4e0c1fe1 mov v1.s[1], wzr + 6b4: 4e0a1fe1 mov v1.h[2], wzr + 6b8: 4e071fe1 mov v1.b[3], wzr + 6bc: 4cc0ac3f ld1 {v31.2d, v0.2d}, [x1], x0 + 6c0: 1e601000 fmov d0, #2.000000000000000000e+00 + 6c4: 1e603000 fmov d0, #2.125000000000000000e+00 + 6c8: 1e621000 fmov d0, #4.000000000000000000e+00 + 6cc: 1e623000 fmov d0, #4.250000000000000000e+00 + 6d0: 1e641000 fmov d0, #8.000000000000000000e+00 + 6d4: 1e643000 fmov d0, #8.500000000000000000e+00 + 6d8: 1e661000 fmov d0, #1.600000000000000000e+01 + 6dc: 1e663000 fmov d0, #1.700000000000000000e+01 + 6e0: 1e681000 fmov d0, #1.250000000000000000e-01 + 6e4: 1e683000 fmov d0, #1.328125000000000000e-01 + 6e8: 1e6a1000 fmov d0, #2.500000000000000000e-01 + 6ec: 1e6a3000 fmov d0, #2.656250000000000000e-01 + 6f0: 1e6c1000 fmov d0, #5.000000000000000000e-01 + 6f4: 1e6c3000 fmov d0, #5.312500000000000000e-01 + 6f8: 1e6e1000 fmov d0, #1.000000000000000000e+00 + 6fc: 1e6e3000 fmov d0, #1.062500000000000000e+00 + 700: 1e701000 fmov d0, #-2.000000000000000000e+00 + 704: 1e703000 fmov d0, #-2.125000000000000000e+00 + 708: 1e721000 fmov d0, #-4.000000000000000000e+00 + 70c: 1e723000 fmov d0, #-4.250000000000000000e+00 + 710: 1e741000 fmov d0, #-8.000000000000000000e+00 + 714: 1e743000 fmov d0, #-8.500000000000000000e+00 + 718: 1e761000 fmov d0, #-1.600000000000000000e+01 + 71c: 1e763000 fmov d0, #-1.700000000000000000e+01 + 720: 1e781000 fmov d0, #-1.250000000000000000e-01 + 724: 1e783000 fmov d0, #-1.328125000000000000e-01 + 728: 1e7a1000 fmov d0, #-2.500000000000000000e-01 + 72c: 1e7a3000 fmov d0, #-2.656250000000000000e-01 + 730: 1e7c1000 fmov d0, #-5.000000000000000000e-01 + 734: 1e7c3000 fmov d0, #-5.312500000000000000e-01 + 738: 1e7e1000 fmov d0, #-1.000000000000000000e+00 + 73c: 1e7e3000 fmov d0, #-1.062500000000000000e+00 + 740: f83081f4 swp x16, x20, [x15] + 744: f8220387 ldadd x2, x7, [x28] + 748: f834132a ldclr x20, x10, [x25] + 74c: f836204b ldeor x22, x11, [x2] + 750: f821326a ldset x1, x10, [x19] + 754: f82e5075 ldsmin x14, x21, [x3] + 758: f83c41bb ldsmax x28, x27, [x13] + 75c: f83172be ldumin x17, x30, [x21] + 760: f83b63b0 ldumax x27, x16, [x29] + 764: f8be8009 swpa x30, x9, [x0] + 768: f8bc039b ldadda x28, x27, [x28] + 76c: f8b51159 ldclra x21, x25, [x10] + 770: f8bf21f4 ldeora xzr, x20, [x15] + 774: f8a131d9 ldseta x1, x25, [x14] + 778: f8b553ba ldsmina x21, x26, [x29] + 77c: f8a8433d ldsmaxa x8, x29, [x25] + 780: f8ad7322 ldumina x13, x2, [x25] + 784: f8af6017 ldumaxa x15, x23, [x0] + 788: f8e38041 swpal x3, x1, [x2] + 78c: f8fc0283 ldaddal x28, x3, [x20] + 790: f8ee11df ldclral x14, xzr, [x14] + 794: f8e7205c ldeoral x7, x28, [x2] + 798: f8e030ab ldsetal x0, x11, [x5] + 79c: f8eb528e ldsminal x11, x14, [x20] + 7a0: f8ff4044 ldsmaxal xzr, x4, [x2] + 7a4: f8fa72c0 lduminal x26, x0, [x22] + 7a8: f8f161a1 ldumaxal x17, x1, [x13] + 7ac: f877829a swpl x23, x26, [x20] + 7b0: f86e018b ldaddl x14, x11, [x12] + 7b4: f86c11ff stclrl x12, [x15] + 7b8: f87b210e ldeorl x27, x14, [x8] + 7bc: f86a333e ldsetl x10, x30, [x25] + 7c0: f8765207 ldsminl x22, x7, [x16] + 7c4: f8614110 ldsmaxl x1, x16, [x8] + 7c8: f8617341 lduminl x1, x1, [x26] + 7cc: f86061f7 ldumaxl x0, x23, [x15] + 7d0: b82b8110 swp w11, w16, [x8] + 7d4: b82101c7 ldadd w1, w7, [x14] + 7d8: b830113f stclr w16, [x9] + 7dc: b83621a6 ldeor w22, w6, [x13] + 7e0: b82b308d ldset w11, w13, [x4] + 7e4: b8305016 ldsmin w16, w22, [x0] + 7e8: b83c415f stsmax w28, [x10] + 7ec: b8307105 ldumin w16, w5, [x8] + 7f0: b83a61f4 ldumax w26, w20, [x15] + 7f4: b8bb8206 swpa w27, w6, [x16] + 7f8: b8bf005f ldadda wzr, wzr, [x2] + 7fc: b8b8111c ldclra w24, w28, [x8] + 800: b8af22e9 ldeora w15, w9, [x23] + 804: b8ba30e2 ldseta w26, w2, [x7] + 808: b8a351f1 ldsmina w3, w17, [x15] + 80c: b8b342a5 ldsmaxa w19, w5, [x21] + 810: b8a7719a ldumina w7, w26, [x12] + 814: b8ac63a7 ldumaxa w12, w7, [x29] + 818: b8e98288 swpal w9, w8, [x20] + 81c: b8e803df ldaddal w8, wzr, [x30] + 820: b8e01186 ldclral w0, w6, [x12] + 824: b8f12057 ldeoral w17, w23, [x2] + 828: b8e0303e ldsetal w0, w30, [x1] + 82c: b8f651e3 ldsminal w22, w3, [x15] + 830: b8f941b5 ldsmaxal w25, w21, [x13] + 834: b8ed7378 lduminal w13, w24, [x27] + 838: b8f46163 ldumaxal w20, w3, [x11] + 83c: b86382ad swpl w3, w13, [x21] + 840: b87a034f ldaddl w26, w15, [x26] + 844: b8691053 ldclrl w9, w19, [x2] + 848: b87820fd ldeorl w24, w29, [x7] + 84c: b87d31f9 ldsetl w29, w25, [x15] + 850: b86b50fe ldsminl w11, w30, [x7] + 854: b86b40c2 ldsmaxl w11, w2, [x6] + 858: b87071cb lduminl w16, w11, [x14] + 85c: b8656168 ldumaxl w5, w8, [x11] */ static const unsigned int insns[] = { - 0x8b50798f, 0xcb4381e1, 0xab05372d, 0xeb864796, - 0x0b961920, 0x4b195473, 0x2b0b5264, 0x6b9300f8, - 0x8a0bc0fe, 0xaa0f3118, 0xca170531, 0xea44dd6e, - 0x0a4c44f3, 0x2a8b7373, 0x4a567c7e, 0x6a9c0353, - 0x8a3accdd, 0xaa318f7a, 0xca2e1495, 0xeaa015e2, - 0x0a2274e2, 0x2a751598, 0x4a3309fe, 0x6ab172fe, - 0x110a5284, 0x310b1942, 0x5103d353, 0x710125bc, - 0x910d7bc2, 0xb108fa1b, 0xd1093536, 0xf10ae824, - 0x120e667c, 0x321f6cbb, 0x520f6a9e, 0x72136f56, - 0x927e4ce5, 0xb278b4ed, 0xd24c6527, 0xf2485803, + 0x8b18ec0f, 0xcb9636d1, 0xab1ce74a, 0xeb184a19, + 0x0b1c1ca8, 0x4b817388, 0x2b01004c, 0x6b5164b7, + 0x8a0d5595, 0xaa9791f5, 0xca9bc316, 0xea82d1f6, + 0x0a980e21, 0x2a862c45, 0x4a453037, 0x6a8e5180, + 0x8a621cc1, 0xaa24bd1e, 0xcab4d6d1, 0xeaa591fd, + 0x0a7d6efe, 0x2a2253ac, 0x4aa61187, 0x6aa755b0, + 0x110b5a25, 0x31056e0a, 0x510f48ba, 0x710ac715, + 0x910f6e0a, 0xb10a65ef, 0xd1009e98, 0xf10131aa, + 0x121d4e67, 0x32043e25, 0x52132390, 0x72160b0e, + 0x9273e76e, 0xb256416c, 0xd24b5002, 0xf266da8d, 0x14000000, 0x17ffffd7, 0x140001ee, 0x94000000, - 0x97ffffd4, 0x940001eb, 0x34000010, 0x34fffa30, - 0x34003d10, 0x35000013, 0x35fff9d3, 0x35003cb3, - 0xb4000005, 0xb4fff965, 0xb4003c45, 0xb5000004, - 0xb5fff904, 0xb5003be4, 0x1000001b, 0x10fff8bb, - 0x10003b9b, 0x90000010, 0x3640001c, 0x3647f83c, - 0x36403b1c, 0x37080001, 0x370ff7c1, 0x37083aa1, - 0x12a437f4, 0x528c9d67, 0x72838bb1, 0x92c1062e, - 0xd287da49, 0xf2a6d153, 0x93465ac9, 0x330b0013, - 0x530b4e6a, 0x934545e4, 0xb35370a3, 0xd3510b8c, - 0x13960c0f, 0x93ceddc6, 0x54000000, 0x54fff5a0, + 0x97ffffd4, 0x940001eb, 0x3400000f, 0x34fffa2f, + 0x34003d0f, 0x3500001c, 0x35fff9dc, 0x35003cbc, + 0xb400001b, 0xb4fff97b, 0xb4003c5b, 0xb5000000, + 0xb5fff900, 0xb5003be0, 0x1000000d, 0x10fff8ad, + 0x10003b8d, 0x90000003, 0x36380015, 0x363ff835, + 0x36383b15, 0x3748000f, 0x374ff7cf, 0x37483aaf, + 0x12a14bee, 0x5283bb51, 0x72858ebb, 0x92c98881, + 0xd2aa50d4, 0xf2afd9d4, 0x935c504d, 0x33133e90, + 0x5309196b, 0x93595482, 0xb3424e0d, 0xd3481728, + 0x138a3b7d, 0x93c66286, 0x54000000, 0x54fff5a0, 0x54003880, 0x54000001, 0x54fff541, 0x54003821, 0x54000002, 0x54fff4e2, 0x540037c2, 0x54000002, 0x54fff482, 0x54003762, 0x54000003, 0x54fff423, @@ -1336,77 +1336,77 @@ 0x5400000c, 0x54fff06c, 0x5400334c, 0x5400000d, 0x54fff00d, 0x540032ed, 0x5400000e, 0x54ffefae, 0x5400328e, 0x5400000f, 0x54ffef4f, 0x5400322f, - 0xd40ac601, 0xd40042a2, 0xd404dac3, 0xd4224d40, - 0xd44219c0, 0xd503201f, 0xd69f03e0, 0xd6bf03e0, - 0xd5033fdf, 0xd503339f, 0xd50335bf, 0xd61f0280, - 0xd63f0040, 0xc8127c17, 0xc81efec5, 0xc85f7d05, - 0xc85ffe14, 0xc89ffd66, 0xc8dfff66, 0x880a7cb1, - 0x8816fd89, 0x885f7d1b, 0x885ffc57, 0x889fffba, - 0x88dffd4d, 0x48197f7c, 0x481dfd96, 0x485f7f96, - 0x485fffc3, 0x489ffdf8, 0x48dfff5b, 0x080b7e6a, - 0x0817fedb, 0x085f7e18, 0x085ffc38, 0x089fffa5, - 0x08dffe18, 0xc87f6239, 0xc87fb276, 0xc820573a, - 0xc821aca6, 0x887f388d, 0x887f88d1, 0x882f2643, - 0x88329131, 0xf81cf2b7, 0xb803f055, 0x39002f9b, - 0x781f31fd, 0xf85d33ce, 0xb843539d, 0x39401f54, - 0x785ce059, 0x389f1143, 0x788131ee, 0x78dfb17d, - 0xb89b90af, 0xfc403193, 0xbc42a36c, 0xfc07d396, - 0xbc1ec1f8, 0xf81e8f88, 0xb8025de6, 0x38007c27, - 0x7801ee20, 0xf8454fb9, 0xb85cce9a, 0x385e7fba, - 0x7841af24, 0x389ebd1c, 0x789fadd1, 0x78c0aefc, - 0xb89c0f7e, 0xfc50efd4, 0xbc414f71, 0xfc011c67, - 0xbc1f0d6d, 0xf81c3526, 0xb81e34b0, 0x3800f7bd, - 0x78012684, 0xf842e653, 0xb8417456, 0x385e2467, - 0x785e358b, 0x389e34c8, 0x788046f8, 0x78c00611, - 0xb89f8680, 0xfc582454, 0xbc5987d3, 0xfc076624, - 0xbc190675, 0xf833785a, 0xb82fd809, 0x3821799a, - 0x782a7975, 0xf870eaf0, 0xb871d96a, 0x386b7aed, - 0x7875689b, 0x38afd91a, 0x78a2c955, 0x78ee6bc8, - 0xb8b4f9dd, 0xfc76eb7e, 0xbc76692d, 0xfc31db28, - 0xbc255b01, 0xf91c52aa, 0xb91c3fb2, 0x391f8877, - 0x791ac97c, 0xf95c1758, 0xb95b3c55, 0x395ce0a4, - 0x795851ce, 0x399e9f64, 0x79993764, 0x79d9af8a, - 0xb99eea2a, 0xfd5a2f8d, 0xbd5dac78, 0xfd1e0182, - 0xbd195c31, 0x58000010, 0x1800000d, 0xf8981240, - 0xd8ffdf00, 0xf8a27a80, 0xf99af920, 0x1a0202e8, - 0x3a130078, 0x5a1d0316, 0x7a03036c, 0x9a0102eb, - 0xba1700bd, 0xda0c0329, 0xfa16000c, 0x0b23459a, - 0x2b328a14, 0xcb274bde, 0x6b222eab, 0x8b214b42, - 0xab34a7b2, 0xcb24520e, 0xeb378e20, 0x3a565283, - 0x7a420321, 0xba58c247, 0xfa4d5106, 0x3a426924, - 0x7a5b0847, 0xba413a02, 0xfa5fba23, 0x1a979377, - 0x1a86640a, 0x5a89300b, 0x5a923771, 0x9a8b720c, - 0x9a868786, 0xda9a736d, 0xda9256dd, 0x5ac0026c, - 0x5ac00657, 0x5ac00b89, 0x5ac01262, 0x5ac017b9, - 0xdac002e4, 0xdac0065d, 0xdac00907, 0xdac00e2d, - 0xdac01011, 0xdac01752, 0x1ad0098b, 0x1ac70d24, - 0x1ad020ec, 0x1ad72613, 0x1ac62887, 0x1ad72e95, - 0x9adc0990, 0x9acd0d84, 0x9ac721a9, 0x9acf277c, - 0x9ace2bd4, 0x9ade2e4e, 0x9bc77d63, 0x9b587e97, - 0x1b1524a2, 0x1b04a318, 0x9b0f4d8b, 0x9b0ce73d, - 0x9b2c5971, 0x9b34c87c, 0x9bbc6887, 0x9bb19556, - 0x1e310871, 0x1e261a2b, 0x1e2928fd, 0x1e333987, - 0x1e230ae0, 0x1e75087a, 0x1e651a60, 0x1e692b40, - 0x1e753ab9, 0x1e7309b0, 0x1f00425d, 0x1f1d95b7, - 0x1f2a38e9, 0x1f2f5f99, 0x1f5545a6, 0x1f429ea3, - 0x1f65472a, 0x1f7449ce, 0x1e20404f, 0x1e20c0f2, - 0x1e2140c3, 0x1e21c02c, 0x1e22c009, 0x1e6040a4, - 0x1e60c1e3, 0x1e614331, 0x1e61c30c, 0x1e6240b5, - 0x1e3802a4, 0x9e38007b, 0x1e78011d, 0x9e7802a9, - 0x1e2203b4, 0x9e220107, 0x1e6202ac, 0x9e6202b0, - 0x1e2600b2, 0x9e660119, 0x1e270352, 0x9e670160, - 0x1e262200, 0x1e7d2200, 0x1e2023c8, 0x1e602128, - 0x293e119b, 0x294a2543, 0x69480c70, 0xa934726a, - 0xa97448f3, 0x298243ca, 0x29e21242, 0x69c64db8, - 0xa9800311, 0xa9f4686e, 0x288a0416, 0x28fe2812, - 0x68fe62d8, 0xa885308c, 0xa8f12664, 0x282468d2, - 0x284e5035, 0xa8327699, 0xa84716e1, 0x0c407284, - 0x4cdfa158, 0x0ccf6cd8, 0x4cdf2483, 0x0d40c0c2, - 0x4ddfc9cd, 0x0dd8ceaf, 0x4c408ea9, 0x0cdf86bd, - 0x4d60c1c8, 0x0dffca87, 0x4de3cc7c, 0x4cdd497b, - 0x0c404950, 0x4d40e595, 0x4ddfeba4, 0x0dd3ed38, - 0x4cdf046a, 0x0cc9039b, 0x0d60e3d5, 0x0dffe5d7, - 0x0df4e9a4, 0xba5fd3e3, 0x3a5f03e5, 0xfa411be4, + 0xd40d2881, 0xd40ea5c2, 0xd40518a3, 0xd42eca40, + 0xd44a2e60, 0xd503201f, 0xd69f03e0, 0xd6bf03e0, + 0xd5033fdf, 0xd5033d9f, 0xd5033bbf, 0xd61f0120, + 0xd63f0120, 0xc8027d7d, 0xc816ff85, 0xc85f7e8e, + 0xc85ffe7d, 0xc89ffea6, 0xc8dffc73, 0x880c7f63, + 0x8811fdfa, 0x885f7dcd, 0x885fff4c, 0x889ffe28, + 0x88dfffd5, 0x48007d6f, 0x4811fc34, 0x485f7d1d, + 0x485ffd91, 0x489ffc8b, 0x48dffc90, 0x080e7c85, + 0x081bfe11, 0x085f7f66, 0x085fff1b, 0x089ffe8a, + 0x08dfff49, 0xc87f7b85, 0xc87fa66a, 0xc82b5590, + 0xc82adc94, 0x887f0416, 0x887f8503, 0x88205fc9, + 0x8837c560, 0xf81e1146, 0xb81fb007, 0x381f3205, + 0x7801f27e, 0xf8477130, 0xb843b208, 0x385f918a, + 0x785da12e, 0x389f83d8, 0x78817087, 0x78dd91d1, + 0xb89e136b, 0xfc4410ec, 0xbc5fe200, 0xfc15f2ed, + 0xbc1c2075, 0xf8064ca2, 0xb81a4c29, 0x381fbfdb, + 0x7800cdfb, 0xf852ce24, 0xb841eef5, 0x385f9e2d, + 0x785cec19, 0x389ebea1, 0x789caebc, 0x78c02c8b, + 0xb883dd31, 0xfc427e7d, 0xbc5abed6, 0xfc11ff29, + 0xbc1f1c49, 0xf81be6ed, 0xb800a611, 0x381e05c1, + 0x78006411, 0xf855473b, 0xb85da72d, 0x385e372b, + 0x784144be, 0x389f94e9, 0x789c2460, 0x78c1f5c7, + 0xb8827771, 0xfc515491, 0xbc4226ba, 0xfc1c7625, + 0xbc1935ad, 0xf824da06, 0xb834db09, 0x38237ba3, + 0x783e6a2a, 0xf867497b, 0xb87949ee, 0x387379d8, + 0x7866c810, 0x38acd98a, 0x78b0499a, 0x78ee781a, + 0xb8bbf971, 0xfc73d803, 0xbc6979fa, 0xfc30e9ab, + 0xbc355a7a, 0xf91886a8, 0xb918ef6a, 0x391b15db, + 0x791ac0f0, 0xf958753b, 0xb95a1958, 0x395b3f18, + 0x795800b4, 0x39988891, 0x799a81ae, 0x79dd172a, + 0xb9981342, 0xfd5d21da, 0xbd5e7c9c, 0xfd1b526e, + 0xbd18df97, 0x58002268, 0x18ffdf51, 0xf8951080, + 0xd8000000, 0xf8a4c900, 0xf999e180, 0x1a150374, + 0x3a060227, 0x5a1900c5, 0x7a0e017e, 0x9a0b0223, + 0xba110159, 0xda170207, 0xfa050144, 0x0b2973c9, + 0x2b30a8a0, 0xcb3b8baf, 0x6b21f12b, 0x8b264f02, + 0xab3a70d3, 0xcb39ef48, 0xeb29329a, 0x3a5a41a7, + 0x7a54310f, 0xba4302c8, 0xfa58a04a, 0x3a50490d, + 0x7a4c0a01, 0xba5f79e3, 0xfa4c0aef, 0x1a9a30ee, + 0x1a9ed763, 0x5a9702ab, 0x5a95c7da, 0x9a8d835c, + 0x9a909471, 0xda8380ab, 0xda93c461, 0x5ac00120, + 0x5ac005da, 0x5ac00a2d, 0x5ac0128b, 0x5ac0163c, + 0xdac0008d, 0xdac007c1, 0xdac009cd, 0xdac00d05, + 0xdac01322, 0xdac01514, 0x1adb0b35, 0x1ad00d4d, + 0x1ad1203c, 0x1aca26f9, 0x1ac72867, 0x1ace2fce, + 0x9acf0acc, 0x9acd0f22, 0x9ad522e7, 0x9ac0258b, + 0x9adc293e, 0x9ad62cad, 0x9bc47ea5, 0x9b477c51, + 0x1b11318c, 0x1b01edfe, 0x9b117662, 0x9b03fae4, + 0x9b313eef, 0x9b21b59b, 0x9bac45a6, 0x9ba6a839, + 0x1e240871, 0x1e3518b0, 0x1e312b63, 0x1e2f3959, + 0x1e200a2a, 0x1e630b5c, 0x1e7b1804, 0x1e6229dc, + 0x1e773b4c, 0x1e610bcf, 0x1f0534a4, 0x1f1c85b5, + 0x1f3d1c71, 0x1f3d6b37, 0x1f5e68ee, 0x1f4aa4f6, + 0x1f6e24e7, 0x1f6f630e, 0x1e204056, 0x1e20c060, + 0x1e214229, 0x1e21c178, 0x1e22c32f, 0x1e604064, + 0x1e60c2da, 0x1e61427e, 0x1e61c1cc, 0x1e6240f1, + 0x1e3801d8, 0x9e38034d, 0x1e780022, 0x9e780165, + 0x1e22026e, 0x9e2202c1, 0x1e62023b, 0x9e620136, + 0x1e26006e, 0x9e66022c, 0x1e270368, 0x9e67039d, + 0x1e3e2000, 0x1e692180, 0x1e202148, 0x1e602328, + 0x292e7b68, 0x294a4f15, 0x69626c50, 0xa93814d5, + 0xa97e679d, 0x29903408, 0x29ec5039, 0x69fc62ce, + 0xa98504d1, 0xa9fc4735, 0x28b05691, 0x28c8705c, + 0x68e07953, 0xa8bf3e31, 0xa8fe0331, 0x283c170e, + 0x284e4c37, 0xa80419cb, 0xa8722f62, 0x0c407230, + 0x4cdfa13d, 0x0cd56f1e, 0x4cdf2440, 0x0d40c134, + 0x4ddfc811, 0x0ddaced5, 0x4c408f33, 0x0cdf84aa, + 0x4d60c30a, 0x0dffcbad, 0x4de2cf96, 0x4ccb489e, + 0x0c40481d, 0x4d40e777, 0x4ddfe943, 0x0dd6edd3, + 0x4cdf040e, 0x0cd902de, 0x0d60e019, 0x0dffe50a, + 0x0dfce8c1, 0xba5fd3e3, 0x3a5f03e5, 0xfa411be4, 0x7a42cbe2, 0x93df03ff, 0xc820ffff, 0x8822fc7f, 0xc8247cbf, 0x88267fff, 0x4e010fe0, 0x4e081fe1, 0x4e0c1fe1, 0x4e0a1fe1, 0x4e071fe1, 0x4cc0ac3f, @@ -1418,24 +1418,24 @@ 0x1e741000, 0x1e743000, 0x1e761000, 0x1e763000, 0x1e781000, 0x1e783000, 0x1e7a1000, 0x1e7a3000, 0x1e7c1000, 0x1e7c3000, 0x1e7e1000, 0x1e7e3000, - 0xf8358305, 0xf82d01ed, 0xf8361353, 0xf839234a, - 0xf82531fb, 0xf8335165, 0xf83a4080, 0xf83673d7, - 0xf832611c, 0xf8ad837d, 0xf8ab01a5, 0xf8a112b8, - 0xf8bb2311, 0xf8b230be, 0xf8a75336, 0xf8a4427a, - 0xf8a6707e, 0xf8b860b7, 0xf8f88392, 0xf8f300ff, - 0xf8ed1386, 0xf8e822af, 0xf8e2302d, 0xf8f1533d, - 0xf8f941d2, 0xf8ff7366, 0xf8f061e5, 0xf86b8072, - 0xf87a0054, 0xf86b1164, 0xf87e22f3, 0xf86331cf, - 0xf87e5296, 0xf8674305, 0xf87771f0, 0xf86b6013, - 0xb83c803c, 0xb82b0195, 0xb83d1240, 0xb8252320, - 0xb82e3340, 0xb83c53b2, 0xb82f43a1, 0xb828739a, - 0xb831608e, 0xb8b88039, 0xb8aa0231, 0xb8bd12b4, - 0xb8bd2189, 0xb8ab30a6, 0xb8b552a7, 0xb8aa4197, - 0xb8b57145, 0xb8be6254, 0xb8ed80b7, 0xb8ef00b8, - 0xb8e9132a, 0xb8f42231, 0xb8ec33d2, 0xb8e35323, - 0xb8fa4159, 0xb8e273eb, 0xb8e760a2, 0xb8608287, - 0xb865005f, 0xb87b1379, 0xb87e2358, 0xb86f32c2, - 0xb86053e3, 0xb86f4154, 0xb87671d5, 0xb866605e, + 0xf83081f4, 0xf8220387, 0xf834132a, 0xf836204b, + 0xf821326a, 0xf82e5075, 0xf83c41bb, 0xf83172be, + 0xf83b63b0, 0xf8be8009, 0xf8bc039b, 0xf8b51159, + 0xf8bf21f4, 0xf8a131d9, 0xf8b553ba, 0xf8a8433d, + 0xf8ad7322, 0xf8af6017, 0xf8e38041, 0xf8fc0283, + 0xf8ee11df, 0xf8e7205c, 0xf8e030ab, 0xf8eb528e, + 0xf8ff4044, 0xf8fa72c0, 0xf8f161a1, 0xf877829a, + 0xf86e018b, 0xf86c11ff, 0xf87b210e, 0xf86a333e, + 0xf8765207, 0xf8614110, 0xf8617341, 0xf86061f7, + 0xb82b8110, 0xb82101c7, 0xb830113f, 0xb83621a6, + 0xb82b308d, 0xb8305016, 0xb83c415f, 0xb8307105, + 0xb83a61f4, 0xb8bb8206, 0xb8bf005f, 0xb8b8111c, + 0xb8af22e9, 0xb8ba30e2, 0xb8a351f1, 0xb8b342a5, + 0xb8a7719a, 0xb8ac63a7, 0xb8e98288, 0xb8e803df, + 0xb8e01186, 0xb8f12057, 0xb8e0303e, 0xb8f651e3, + 0xb8f941b5, 0xb8ed7378, 0xb8f46163, 0xb86382ad, + 0xb87a034f, 0xb8691053, 0xb87820fd, 0xb87d31f9, + 0xb86b50fe, 0xb86b40c2, 0xb87071cb, 0xb8656168, }; // END Generated code -- do not edit @@ -1532,7 +1532,7 @@ } } -void Assembler::adrp(Register reg1, const Address &dest, uintptr_t &byte_offset) { +void Assembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) { ShouldNotReachHere(); } @@ -1702,7 +1702,7 @@ } bool Assembler::operand_valid_for_add_sub_immediate(int64_t imm) { - uint64_t uimm = (uint64_t)uabs(imm); + uint64_t uimm = (uint64_t)uabs((jlong)imm); if (uimm < (1 << 12)) return true; if (uimm < (1 << 24) @@ -1783,3 +1783,7 @@ ival = fp_immediate_for_encoding(value, 0); return val; } + +address Assembler::locate_next_instruction(address inst) { + return inst + Assembler::instruction_size; +}
diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index 8a2dd3f..ccb8d75 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp
@@ -28,6 +28,19 @@ #include "asm/register.hpp" +#ifdef __GNUC__ + +// __nop needs volatile so that compiler doesn't optimize it away +#define NOP() asm volatile ("nop"); + +#elif defined(_MSC_VER) + +// Use MSVC instrinsic: https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=vs-2019#I +#define NOP() __nop(); + +#endif + + // definitions of various symbolic names for machine registers // First intercalls between C and Java which use 8 general registers @@ -201,7 +214,7 @@ static void patch(address a, int msb, int lsb, uint64_t val) { int nbits = msb - lsb + 1; - guarantee(val < (1U << nbits), "Field too big for insn"); + guarantee(val < (1ULL << nbits), "Field too big for insn"); assert_cond(msb >= lsb); unsigned mask = checked_cast<unsigned>(right_n_bits(nbits)); val <<= lsb; @@ -380,9 +393,15 @@ : _base(r), _index(noreg), _offset(0), _mode(base_plus_offset), _target(0) { } Address(Register r, int o) : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } - Address(Register r, int64_t o) + Address(Register r, long o) : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } - Address(Register r, uint64_t o) + Address(Register r, long long o) + : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } + Address(Register r, unsigned int o) + : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } + Address(Register r, unsigned long o) + : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } + Address(Register r, unsigned long long o) : _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { } #ifdef ASSERT Address(Register r, ByteSize disp) @@ -417,8 +436,8 @@ } Register base() const { - guarantee((_mode == base_plus_offset | _mode == base_plus_offset_reg - | _mode == post | _mode == post_reg), + guarantee((_mode == base_plus_offset || _mode == base_plus_offset_reg + || _mode == post || _mode == post_reg), "wrong mode"); return _base; } @@ -612,7 +631,7 @@ void emit_long(jint x) { if ((uintptr_t)pc() == asm_bp) - asm volatile ("nop"); + NOP(); AbstractAssembler::emit_int32(x); } #else @@ -644,6 +663,8 @@ return Address(Post(base, idx)); } + static address locate_next_instruction(address inst); + Instruction_aarch64* current; void set_current(Instruction_aarch64* i) { current = i; } @@ -1512,6 +1533,11 @@ #undef INSN +#ifdef _WIN64 +// In MSVC, `mvn` is defined as a macro and it affects compilation +#undef mvn +#endif + // Aliases for short forms of orn void mvn(Register Rd, Register Rm, enum shift_kind kind = LSL, unsigned shift = 0) {
diff --git a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp index 7d4b50f..102d431 100644 --- a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp
@@ -44,13 +44,13 @@ pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of registers used during code emission - pd_nof_caller_save_cpu_regs_frame_map = 19 - 2, // number of registers killed by calls + pd_nof_caller_save_cpu_regs_frame_map = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), // number of registers killed by calls pd_nof_caller_save_fpu_regs_frame_map = 32, // number of registers killed by calls - pd_first_callee_saved_reg = 19 - 2, - pd_last_callee_saved_reg = 26 - 2, + pd_first_callee_saved_reg = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), + pd_last_callee_saved_reg = 26 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), - pd_last_allocatable_cpu_reg = 16, + pd_last_allocatable_cpu_reg = 16 R18_RESERVED_ONLY(- 1), pd_nof_cpu_regs_reg_alloc = pd_last_allocatable_cpu_reg + 1, // number of registers that are visible to register allocator @@ -60,9 +60,9 @@ pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan pd_nof_xmm_regs_linearscan = 0, // like sparc we don't have any of these pd_first_cpu_reg = 0, - pd_last_cpu_reg = 16, + pd_last_cpu_reg = 16 R18_RESERVED_ONLY(- 1), pd_first_byte_reg = 0, - pd_last_byte_reg = 16, + pd_last_byte_reg = 16 R18_RESERVED_ONLY(- 1), pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, pd_last_fpu_reg = pd_first_fpu_reg + 31,
diff --git a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp index 3e21300..b3b8bdb 100644 --- a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp
@@ -28,3 +28,6 @@ //-------------------------------------------------------- // No FPU stack on AARCH64 + +// This include is needed to avoid MSVC error C1010 on Windows. +#include "precompiled.hpp"
diff --git a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp index 8bf36e7..62c7a86 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp
@@ -181,7 +181,10 @@ map_register(i, r15); r15_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r16); r16_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r17); r17_opr = LIR_OprFact::single_cpu(i); i++; - map_register(i, r18); r18_opr = LIR_OprFact::single_cpu(i); i++; +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp + map_register(i, r18_tls); r18_opr = LIR_OprFact::single_cpu(i); i++; +#endif map_register(i, r19); r19_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r20); r20_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r21); r21_opr = LIR_OprFact::single_cpu(i); i++; @@ -199,6 +202,11 @@ map_register(i, r8); r8_opr = LIR_OprFact::single_cpu(i); i++; // rscratch1 map_register(i, r9); r9_opr = LIR_OprFact::single_cpu(i); i++; // rscratch2 +#ifdef R18_RESERVED + // See comment in register_aarch64.hpp + map_register(i, r18_tls); r18_opr = LIR_OprFact::single_cpu(i); i++; +#endif + rscratch1_opr = r8_opr; rscratch2_opr = r9_opr; rscratch1_long_opr = LIR_OprFact::double_cpu(r8_opr->cpu_regnr(), r8_opr->cpu_regnr()); @@ -227,7 +235,10 @@ _caller_save_cpu_regs[13] = r15_opr; _caller_save_cpu_regs[14] = r16_opr; _caller_save_cpu_regs[15] = r17_opr; +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp _caller_save_cpu_regs[16] = r18_opr; +#endif for (int i = 0; i < 8; i++) { _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); @@ -253,7 +264,7 @@ r15_oop_opr = as_oop_opr(r15); r16_oop_opr = as_oop_opr(r16); r17_oop_opr = as_oop_opr(r17); - r18_oop_opr = as_oop_opr(r18); + r18_oop_opr = as_oop_opr(r18_tls); r19_oop_opr = as_oop_opr(r19); r20_oop_opr = as_oop_opr(r20); r21_oop_opr = as_oop_opr(r21);
diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index 0120ebd..fdd2c0c 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
@@ -1732,6 +1732,7 @@ default: ShouldNotReachHere(); } break; + default: ShouldNotReachHere(); } } else {
diff --git a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp index a469763..8c23214 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
@@ -584,8 +584,8 @@ case doubleTag: do_ArithmeticOp_FPU(x); return; case longTag: do_ArithmeticOp_Long(x); return; case intTag: do_ArithmeticOp_Int(x); return; + default: ShouldNotReachHere(); return; } - ShouldNotReachHere(); } // _ishl, _lshl, _ishr, _lshr, _iushr, _lushr @@ -792,9 +792,13 @@ __ abs(value.result(), dst, LIR_OprFact::illegalOpr); break; } + default: + ShouldNotReachHere(); } break; } + default: + ShouldNotReachHere(); } }
diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.cpp b/src/hotspot/cpu/aarch64/frame_aarch64.cpp index ffe14bb..383c5b9 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp
@@ -676,11 +676,12 @@ #undef DESCRIBE_FP_OFFSET -#define DESCRIBE_FP_OFFSET(name) \ - { \ - uintptr_t *p = (uintptr_t *)fp; \ - printf("0x%016lx 0x%016lx %s\n", (uintptr_t)(p + frame::name##_offset), \ - p[frame::name##_offset], #name); \ +#define DESCRIBE_FP_OFFSET(name) \ + { \ + uintptr_t *p = (uintptr_t *)fp; \ + printf(INTPTR_FORMAT " " INTPTR_FORMAT " %s\n", \ + (uintptr_t)(p + frame::name##_offset), \ + p[frame::name##_offset], #name); \ } static THREAD_LOCAL_DECL uintptr_t nextfp;
diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp index 5977764..a15e962 100644 --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -53,4 +53,13 @@ #define THREAD_LOCAL_POLL +#if defined(__APPLE__) || defined(_WIN64) +#define R18_RESERVED +#define R18_RESERVED_ONLY(code) code +#define NOT_R18_RESERVED(code) +#else +#define R18_RESERVED_ONLY(code) +#define NOT_R18_RESERVED(code) code +#endif + #endif // CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
diff --git a/src/hotspot/cpu/aarch64/icache_aarch64.hpp b/src/hotspot/cpu/aarch64/icache_aarch64.hpp index 30c7a40..4d01d11 100644 --- a/src/hotspot/cpu/aarch64/icache_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/icache_aarch64.hpp
@@ -26,19 +26,6 @@ #ifndef CPU_AARCH64_VM_ICACHE_AARCH64_HPP #define CPU_AARCH64_VM_ICACHE_AARCH64_HPP -// Interface for updating the instruction cache. Whenever the VM -// modifies code, part of the processor instruction cache potentially -// has to be flushed. - -class ICache : public AbstractICache { - public: - static void initialize(); - static void invalidate_word(address addr) { - __clear_cache((char *)addr, (char *)(addr + 3)); - } - static void invalidate_range(address start, int nbytes) { - __clear_cache((char *)start, (char *)(start + nbytes)); - } -}; +#include OS_CPU_HEADER(icache) #endif // CPU_AARCH64_VM_ICACHE_AARCH64_HPP
diff --git a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp index 7a67d95..3e38b7c 100644 --- a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp
@@ -24,6 +24,9 @@ #include <stdlib.h> #include <stdint.h> + +#include "precompiled.hpp" +#include "utilities/globalDefinitions.hpp" #include "immediate_aarch64.hpp" // there are at most 2^13 possible logical immediate encodings @@ -244,7 +247,10 @@ // constructor to initialise the lookup tables -static void initLITables() __attribute__ ((constructor)); +static void initLITables(); +// Use an empty struct with a construtor as MSVC doesn't support `__attribute__ ((constructor))` +// See https://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc +static struct initLITables_t { initLITables_t(void) { initLITables(); } } _initLITables; static void initLITables() { li_table_entry_count = 0;
diff --git a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp index 4496d39..4d3a6e6 100644 --- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp
@@ -1,6 +1,7 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -44,215 +45,133 @@ Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; } Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } +Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() { + if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { + return as_Register(_num_reg_int_args++ + c_rarg1->encoding()); + } + return noreg; +} + +FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() { + if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { + return as_FloatRegister(_num_reg_fp_args++); + } + return fnoreg; +} + +// On macos/aarch64 native stack is packed, int/float are using only 4 bytes +// on stack. Natural alignment for types are still in place, +// for example double/long should be 8 bytes aligned. + +int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset(unsigned elem_size) { + MACOS_ONLY(_stack_offset = align_up(_stack_offset, elem_size)); + int ret = _stack_offset; + _stack_offset += NOT_MACOS(wordSize) MACOS_ONLY(elem_size); + return ret; +} + InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator( const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) { _masm = new MacroAssembler(buffer); - _num_int_args = (method->is_static() ? 1 : 0); - _num_fp_args = 0; + _num_reg_int_args = (method->is_static() ? 1 : 0); + _num_reg_fp_args = 0; _stack_offset = 0; } +void InterpreterRuntime::SignatureHandlerGenerator::pass_byte() { + const Address src(from(), Interpreter::local_offset_in_bytes(offset())); + + Register reg = next_gpr(); + if (reg != noreg) { + __ ldr(reg, src); + } else { + __ ldrb(r0, src); + __ strb(r0, Address(to(), next_stack_offset(sizeof(jbyte)))); + } +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_short() { + const Address src(from(), Interpreter::local_offset_in_bytes(offset())); + + Register reg = next_gpr(); + if (reg != noreg) { + __ ldr(reg, src); + } else { + __ ldrh(r0, src); + __ strh(r0, Address(to(), next_stack_offset(sizeof(jshort)))); + } +} + void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { const Address src(from(), Interpreter::local_offset_in_bytes(offset())); - switch (_num_int_args) { - case 0: - __ ldr(c_rarg1, src); - _num_int_args++; - break; - case 1: - __ ldr(c_rarg2, src); - _num_int_args++; - break; - case 2: - __ ldr(c_rarg3, src); - _num_int_args++; - break; - case 3: - __ ldr(c_rarg4, src); - _num_int_args++; - break; - case 4: - __ ldr(c_rarg5, src); - _num_int_args++; - break; - case 5: - __ ldr(c_rarg6, src); - _num_int_args++; - break; - case 6: - __ ldr(c_rarg7, src); - _num_int_args++; - break; - default: - __ ldr(r0, src); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_int_args++; - break; + Register reg = next_gpr(); + if (reg != noreg) { + __ ldr(reg, src); + } else { + __ ldrw(r0, src); + __ strw(r0, Address(to(), next_stack_offset(sizeof(jint)))); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); - switch (_num_int_args) { - case 0: - __ ldr(c_rarg1, src); - _num_int_args++; - break; - case 1: - __ ldr(c_rarg2, src); - _num_int_args++; - break; - case 2: - __ ldr(c_rarg3, src); - _num_int_args++; - break; - case 3: - __ ldr(c_rarg4, src); - _num_int_args++; - break; - case 4: - __ ldr(c_rarg5, src); - _num_int_args++; - break; - case 5: - __ ldr(c_rarg6, src); - _num_int_args++; - break; - case 6: - __ ldr(c_rarg7, src); - _num_int_args++; - break; - default: + Register reg = next_gpr(); + if (reg != noreg) { + __ ldr(reg, src); + } else { __ ldr(r0, src); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_int_args++; - break; + __ str(r0, Address(to(), next_stack_offset(sizeof(jlong)))); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { const Address src(from(), Interpreter::local_offset_in_bytes(offset())); - if (_num_fp_args < Argument::n_float_register_parameters_c) { - __ ldrs(as_FloatRegister(_num_fp_args++), src); + FloatRegister reg = next_fpr(); + if (reg != fnoreg) { + __ ldrs(reg, src); } else { __ ldrw(r0, src); - __ strw(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_fp_args++; + __ strw(r0, Address(to(), next_stack_offset(sizeof(jfloat)))); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); - if (_num_fp_args < Argument::n_float_register_parameters_c) { - __ ldrd(as_FloatRegister(_num_fp_args++), src); + FloatRegister reg = next_fpr(); + if (reg != fnoreg) { + __ ldrd(reg, src); } else { __ ldr(r0, src); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_fp_args++; + __ str(r0, Address(to(), next_stack_offset(sizeof(jdouble)))); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { - - switch (_num_int_args) { - case 0: + Register reg = next_gpr(); + if (reg == c_rarg1) { assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); - _num_int_args++; - break; - case 1: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg2, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg2, r0); - __ bind(L); - _num_int_args++; - break; - } - case 2: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg3, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg3, r0); - __ bind(L); - _num_int_args++; - break; - } - case 3: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg4, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg4, r0); - __ bind(L); - _num_int_args++; - break; - } - case 4: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg5, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg5, r0); - __ bind(L); - _num_int_args++; - break; - } - case 5: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg6, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg6, r0); - __ bind(L); - _num_int_args++; - break; - } - case 6: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg7, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg7, r0); - __ bind(L); - _num_int_args++; - break; - } - default: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ ldr(temp(), r0); - Label L; - __ cbnz(temp(), L); - __ mov(r0, zr); - __ bind(L); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_int_args++; - break; - } + } else if (reg != noreg) { + __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); + __ mov(reg, 0); + __ ldr(temp(), r0); + Label L; + __ cbz(temp(), L); + __ mov(reg, r0); + __ bind(L); + } else { + __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); + __ ldr(temp(), r0); + Label L; + __ cbnz(temp(), L); + __ mov(r0, zr); + __ bind(L); + STATIC_ASSERT(sizeof(jobject) == wordSize); + __ str(r0, Address(to(), next_stack_offset(sizeof(jobject)))); } } @@ -277,81 +196,98 @@ : public NativeSignatureIterator { private: address _from; - intptr_t* _to; + char* _to; intptr_t* _int_args; intptr_t* _fp_args; intptr_t* _fp_identifiers; - unsigned int _num_int_args; - unsigned int _num_fp_args; + unsigned int _num_reg_int_args; + unsigned int _num_reg_fp_args; - virtual void pass_int() - { - jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); + intptr_t* single_slot_addr() { + intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); _from -= Interpreter::stackElementSize; - - if (_num_int_args < Argument::n_int_register_parameters_c-1) { - *_int_args++ = from_obj; - _num_int_args++; - } else { - *_to++ = from_obj; - _num_int_args++; - } + return from_addr; } - virtual void pass_long() - { - intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); + intptr_t* double_slot_addr() { + intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); _from -= 2*Interpreter::stackElementSize; + return from_addr; + } - if (_num_int_args < Argument::n_int_register_parameters_c-1) { - *_int_args++ = from_obj; - _num_int_args++; - } else { - *_to++ = from_obj; - _num_int_args++; + int pass_gpr(intptr_t value) { + if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { + *_int_args++ = value; + return _num_reg_int_args++; + } + return -1; + } + + int pass_fpr(intptr_t value) { + if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { + *_fp_args++ = value; + return _num_reg_fp_args++; + } + return -1; + } + + template<typename T> + void pass_stack(T value) { + MACOS_ONLY(_to = align_up(_to, sizeof(value))); + *(T *)_to = value; + _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value)); + } + + virtual void pass_byte() { + jbyte value = *(jbyte*)single_slot_addr(); + if (pass_gpr(value) < 0) { + pass_stack<>(value); } } - virtual void pass_object() - { - intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); - _from -= Interpreter::stackElementSize; - - if (_num_int_args < Argument::n_int_register_parameters_c-1) { - *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr; - _num_int_args++; - } else { - *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; - _num_int_args++; + virtual void pass_short() { + jshort value = *(jshort*)single_slot_addr(); + if (pass_gpr(value) < 0) { + pass_stack<>(value); } } - virtual void pass_float() - { - jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0)); - _from -= Interpreter::stackElementSize; - - if (_num_fp_args < Argument::n_float_register_parameters_c) { - *_fp_args++ = from_obj; - _num_fp_args++; - } else { - *_to++ = from_obj; - _num_fp_args++; + virtual void pass_int() { + jint value = *(jint*)single_slot_addr(); + if (pass_gpr(value) < 0) { + pass_stack<>(value); } } - virtual void pass_double() - { - intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); - _from -= 2*Interpreter::stackElementSize; + virtual void pass_long() { + intptr_t value = *double_slot_addr(); + if (pass_gpr(value) < 0) { + pass_stack<>(value); + } + } - if (_num_fp_args < Argument::n_float_register_parameters_c) { - *_fp_args++ = from_obj; - *_fp_identifiers |= (1ull << _num_fp_args); // mark as double - _num_fp_args++; + virtual void pass_object() { + intptr_t* addr = single_slot_addr(); + intptr_t value = *addr == 0 ? NULL : (intptr_t)addr; + if (pass_gpr(value) < 0) { + pass_stack<>(value); + } + } + + virtual void pass_float() { + jint value = *(jint*)single_slot_addr(); + if (pass_fpr(value) < 0) { + pass_stack<>(value); + } + } + + virtual void pass_double() { + intptr_t value = *double_slot_addr(); + int arg = pass_fpr(value); + if (0 <= arg) { + *_fp_identifiers |= (1ull << arg); // mark as double } else { - *_to++ = from_obj; - _num_fp_args++; + pass_stack<>(value); } } @@ -360,14 +296,14 @@ : NativeSignatureIterator(method) { _from = from; - _to = to; + _to = (char *)to; _int_args = to - (method->is_static() ? 16 : 17); _fp_args = to - 8; _fp_identifiers = to - 9; *(int*) _fp_identifiers = 0; - _num_int_args = (method->is_static() ? 1 : 0); - _num_fp_args = 0; + _num_reg_int_args = (method->is_static() ? 1 : 0); + _num_reg_fp_args = 0; } };
diff --git a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp index a403bf4..d9e9f17 100644 --- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp
@@ -1,6 +1,7 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -34,16 +35,22 @@ class SignatureHandlerGenerator: public NativeSignatureIterator { private: MacroAssembler* _masm; - unsigned int _num_fp_args; - unsigned int _num_int_args; + unsigned int _num_reg_fp_args; + unsigned int _num_reg_int_args; int _stack_offset; + void pass_byte(); + void pass_short(); void pass_int(); void pass_long(); void pass_float(); void pass_double(); void pass_object(); + Register next_gpr(); + FloatRegister next_fpr(); + int next_stack_offset(unsigned elem_size); + public: // Creation SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer);
diff --git a/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp b/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp index 655baf9..44b68eb 100644 --- a/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp
@@ -31,6 +31,7 @@ #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" #include "runtime/safepoint.hpp" +#include "runtime/threadWXSetters.inline.hpp" #define __ masm-> @@ -51,6 +52,48 @@ static const Register rcounter_addr = r6; static const Register result = r7; +// On macos/aarch64 we need to ensure WXExec mode when running generated +// FastGetXXXField, as these functions can be called from WXWrite context +// (8262896). So each FastGetXXXField is wrapped into a C++ statically +// compiled template function that optionally switches to WXExec if necessary. + +#ifdef __APPLE__ + +static address generated_fast_get_field[T_LONG + 1 - T_BOOLEAN]; + +template<int BType> struct BasicTypeToJni {}; +template<> struct BasicTypeToJni<T_BOOLEAN> { static const jboolean jni_type; }; +template<> struct BasicTypeToJni<T_BYTE> { static const jbyte jni_type; }; +template<> struct BasicTypeToJni<T_CHAR> { static const jchar jni_type; }; +template<> struct BasicTypeToJni<T_SHORT> { static const jshort jni_type; }; +template<> struct BasicTypeToJni<T_INT> { static const jint jni_type; }; +template<> struct BasicTypeToJni<T_LONG> { static const jlong jni_type; }; +template<> struct BasicTypeToJni<T_FLOAT> { static const jfloat jni_type; }; +template<> struct BasicTypeToJni<T_DOUBLE> { static const jdouble jni_type; }; + +template<int BType> +decltype(BasicTypeToJni<BType>::jni_type) static_fast_get_field_wrapper(JNIEnv *env, jobject obj, jfieldID fieldID) { + JavaThread* thread = JavaThread::thread_from_jni_environment(env); + ThreadWXEnable wx(WXExec, thread); + address get_field_addr = generated_fast_get_field[BType - T_BOOLEAN]; + return ((decltype(BasicTypeToJni<BType>::jni_type)(*)(JNIEnv *env, jobject obj, jfieldID fieldID))get_field_addr)(env, obj, fieldID); +} + +template<int BType> +address JNI_FastGetField::generate_fast_get_int_field1() { + generated_fast_get_field[BType - T_BOOLEAN] = generate_fast_get_int_field0((BasicType)BType); + return (address)static_fast_get_field_wrapper<BType>; +} + +#else // __APPLE__ + +template<int BType> +address JNI_FastGetField::generate_fast_get_int_field1() { + return generate_fast_get_int_field0((BasicType)BType); +} + +#endif // __APPLE__ + address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { const char *name; switch (type) { @@ -147,33 +190,33 @@ } address JNI_FastGetField::generate_fast_get_boolean_field() { - return generate_fast_get_int_field0(T_BOOLEAN); + return generate_fast_get_int_field1<T_BOOLEAN>(); } address JNI_FastGetField::generate_fast_get_byte_field() { - return generate_fast_get_int_field0(T_BYTE); + return generate_fast_get_int_field1<T_BYTE>(); } address JNI_FastGetField::generate_fast_get_char_field() { - return generate_fast_get_int_field0(T_CHAR); + return generate_fast_get_int_field1<T_CHAR>(); } address JNI_FastGetField::generate_fast_get_short_field() { - return generate_fast_get_int_field0(T_SHORT); + return generate_fast_get_int_field1<T_SHORT>(); } address JNI_FastGetField::generate_fast_get_int_field() { - return generate_fast_get_int_field0(T_INT); + return generate_fast_get_int_field1<T_INT>(); } address JNI_FastGetField::generate_fast_get_long_field() { - return generate_fast_get_int_field0(T_LONG); + return generate_fast_get_int_field1<T_LONG>(); } address JNI_FastGetField::generate_fast_get_float_field() { - return generate_fast_get_int_field0(T_FLOAT); + return generate_fast_get_int_field1<T_FLOAT>(); } address JNI_FastGetField::generate_fast_get_double_field() { - return generate_fast_get_int_field0(T_DOUBLE); + return generate_fast_get_int_field1<T_DOUBLE>(); }
diff --git a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp index e477ca5..0b928f2 100644 --- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp
@@ -21,6 +21,7 @@ * questions. */ +#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "jvmci/jvmciCodeInstaller.hpp" #include "jvmci/jvmciRuntime.hpp"
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 578e0d1..4bab77d 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -297,7 +297,7 @@ ldr(rscratch1, Address(rthread, Thread::polling_page_offset())); tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path); } else { - unsigned long offset; + uint64_t offset; adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset); ldrw(rscratch1, Address(rscratch1, offset)); assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code"); @@ -405,7 +405,7 @@ assert(CodeCache::find_blob(entry.target()) != NULL, "destination of far call not found in code cache"); if (far_branches()) { - uintptr_t offset; + uint64_t offset; // We can use ADRP here because we know that the total size of // the code cache cannot exceed 2Gb. adrp(tmp, entry, offset); @@ -423,7 +423,7 @@ assert(CodeCache::find_blob(entry.target()) != NULL, "destination of far call not found in code cache"); if (far_branches()) { - uintptr_t offset; + uint64_t offset; // We can use ADRP here because we know that the total size of // the code cache cannot exceed 2Gb. adrp(tmp, entry, offset); @@ -1492,7 +1492,7 @@ #ifndef PRODUCT { char buffer[64]; - snprintf(buffer, sizeof(buffer), "0x%"PRIX64, imm64); + snprintf(buffer, sizeof(buffer), "0x%" PRIX64, (uint64_t)imm64); block_comment(buffer); } #endif @@ -1555,7 +1555,7 @@ #ifndef PRODUCT { char buffer[64]; - snprintf(buffer, sizeof(buffer), "0x%"PRIX64, imm64); + snprintf(buffer, sizeof(buffer), "0x%" PRIX64, imm64); block_comment(buffer); } #endif @@ -1668,7 +1668,7 @@ #ifndef PRODUCT { char buffer[64]; - snprintf(buffer, sizeof(buffer), "0x%"PRIX32, imm32); + snprintf(buffer, sizeof(buffer), "0x%" PRIX32, imm32); block_comment(buffer); } #endif @@ -1832,7 +1832,7 @@ return true; } else { assert(size_in_bytes == 8 || size_in_bytes == 4, "only 8 bytes or 4 bytes load/store is supported."); - const unsigned mask = size_in_bytes - 1; + const uint64_t mask = size_in_bytes - 1; if (adr.getMode() == Address::base_plus_offset && (adr.offset() & mask) == 0) { // only supports base_plus_offset. code()->set_last_insn(pc()); @@ -2040,11 +2040,17 @@ void MacroAssembler::pusha() { - push(0x7fffffff, sp); + push(RegSet::range(r0, r30), sp); } void MacroAssembler::popa() { - pop(0x7fffffff, sp); + pop(RegSet::range(r0, r17), sp); +#ifdef R18_RESERVED + ldp(zr, r19, Address(post(sp, 2 * wordSize))); + pop(RegSet::range(r20, r30), sp); +#else + pop(RegSet::range(r18_tls, r30), sp); +#endif } // Push lots of registers in the bit set supplied. Don't push sp. @@ -2496,43 +2502,43 @@ #endif if (os::message_box(msg, "Execution stopped, print registers?")) { ttyLocker ttyl; - tty->print_cr(" pc = 0x%016lx", pc); + tty->print_cr(" pc = 0x%016" PRIx64, pc); #ifndef PRODUCT tty->cr(); findpc(pc); tty->cr(); #endif - tty->print_cr(" r0 = 0x%016lx", regs[0]); - tty->print_cr(" r1 = 0x%016lx", regs[1]); - tty->print_cr(" r2 = 0x%016lx", regs[2]); - tty->print_cr(" r3 = 0x%016lx", regs[3]); - tty->print_cr(" r4 = 0x%016lx", regs[4]); - tty->print_cr(" r5 = 0x%016lx", regs[5]); - tty->print_cr(" r6 = 0x%016lx", regs[6]); - tty->print_cr(" r7 = 0x%016lx", regs[7]); - tty->print_cr(" r8 = 0x%016lx", regs[8]); - tty->print_cr(" r9 = 0x%016lx", regs[9]); - tty->print_cr("r10 = 0x%016lx", regs[10]); - tty->print_cr("r11 = 0x%016lx", regs[11]); - tty->print_cr("r12 = 0x%016lx", regs[12]); - tty->print_cr("r13 = 0x%016lx", regs[13]); - tty->print_cr("r14 = 0x%016lx", regs[14]); - tty->print_cr("r15 = 0x%016lx", regs[15]); - tty->print_cr("r16 = 0x%016lx", regs[16]); - tty->print_cr("r17 = 0x%016lx", regs[17]); - tty->print_cr("r18 = 0x%016lx", regs[18]); - tty->print_cr("r19 = 0x%016lx", regs[19]); - tty->print_cr("r20 = 0x%016lx", regs[20]); - tty->print_cr("r21 = 0x%016lx", regs[21]); - tty->print_cr("r22 = 0x%016lx", regs[22]); - tty->print_cr("r23 = 0x%016lx", regs[23]); - tty->print_cr("r24 = 0x%016lx", regs[24]); - tty->print_cr("r25 = 0x%016lx", regs[25]); - tty->print_cr("r26 = 0x%016lx", regs[26]); - tty->print_cr("r27 = 0x%016lx", regs[27]); - tty->print_cr("r28 = 0x%016lx", regs[28]); - tty->print_cr("r30 = 0x%016lx", regs[30]); - tty->print_cr("r31 = 0x%016lx", regs[31]); + tty->print_cr(" r0 = 0x%016" PRIx64, regs[0]); + tty->print_cr(" r1 = 0x%016" PRIx64, regs[1]); + tty->print_cr(" r2 = 0x%016" PRIx64, regs[2]); + tty->print_cr(" r3 = 0x%016" PRIx64, regs[3]); + tty->print_cr(" r4 = 0x%016" PRIx64, regs[4]); + tty->print_cr(" r5 = 0x%016" PRIx64, regs[5]); + tty->print_cr(" r6 = 0x%016" PRIx64, regs[6]); + tty->print_cr(" r7 = 0x%016" PRIx64, regs[7]); + tty->print_cr(" r8 = 0x%016" PRIx64, regs[8]); + tty->print_cr(" r9 = 0x%016" PRIx64, regs[9]); + tty->print_cr("r10 = 0x%016" PRIx64, regs[10]); + tty->print_cr("r11 = 0x%016" PRIx64, regs[11]); + tty->print_cr("r12 = 0x%016" PRIx64, regs[12]); + tty->print_cr("r13 = 0x%016" PRIx64, regs[13]); + tty->print_cr("r14 = 0x%016" PRIx64, regs[14]); + tty->print_cr("r15 = 0x%016" PRIx64, regs[15]); + tty->print_cr("r16 = 0x%016" PRIx64, regs[16]); + tty->print_cr("r17 = 0x%016" PRIx64, regs[17]); + tty->print_cr("r18 = 0x%016" PRIx64, regs[18]); + tty->print_cr("r19 = 0x%016" PRIx64, regs[19]); + tty->print_cr("r20 = 0x%016" PRIx64, regs[20]); + tty->print_cr("r21 = 0x%016" PRIx64, regs[21]); + tty->print_cr("r22 = 0x%016" PRIx64, regs[22]); + tty->print_cr("r23 = 0x%016" PRIx64, regs[23]); + tty->print_cr("r24 = 0x%016" PRIx64, regs[24]); + tty->print_cr("r25 = 0x%016" PRIx64, regs[25]); + tty->print_cr("r26 = 0x%016" PRIx64, regs[26]); + tty->print_cr("r27 = 0x%016" PRIx64, regs[27]); + tty->print_cr("r28 = 0x%016" PRIx64, regs[28]); + tty->print_cr("r30 = 0x%016" PRIx64, regs[30]); + tty->print_cr("r31 = 0x%016" PRIx64, regs[31]); BREAKPOINT; } ThreadStateTransition::transition(thread, _thread_in_vm, saved_state); @@ -2544,9 +2550,17 @@ } } +RegSet MacroAssembler::call_clobbered_registers() { + RegSet regs = RegSet::range(r0, r17) - RegSet::of(rscratch1, rscratch2); +#ifndef R18_RESERVED + regs += r18_tls; +#endif + return regs; +} + void MacroAssembler::push_call_clobbered_registers() { int step = 4 * wordSize; - push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp); + push(call_clobbered_registers(), sp); sub(sp, sp, step); mov(rscratch1, -step); // Push v0-v7, v16-v31. @@ -2566,12 +2580,12 @@ as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize))); } - pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp); + pop(call_clobbered_registers() - RegSet::of(rscratch1, rscratch2), sp); } void MacroAssembler::push_CPU_state(bool save_vectors) { int step = (save_vectors ? 8 : 4) * wordSize; - push(0x3fffffff, sp); // integer registers except lr & sp + push(RegSet::range(r0, r29), sp); // integer registers except lr & sp mov(rscratch1, -step); sub(sp, sp, step); for (int i = 28; i >= 4; i -= 4) { @@ -2586,7 +2600,15 @@ for (int i = 0; i <= 28; i += 4) ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2), as_FloatRegister(i+3), restore_vectors ? T2D : T1D, Address(post(sp, step))); - pop(0x3fffffff, sp); // integer registers except lr & sp + + // integer registers except lr & sp + pop(RegSet::range(r0, r17), sp); +#ifdef R18_RESERVED + ldp(zr, r19, Address(post(sp, 2 * wordSize))); + pop(RegSet::range(r20, r29), sp); +#else + pop(RegSet::range(r18_tls, r29), sp); +#endif } /** @@ -2752,7 +2774,7 @@ // Overwrite previous generated binary. code_section()->set_end(prev); - const int sz = prev_ldst->size_in_bytes(); + const size_t sz = prev_ldst->size_in_bytes(); assert(sz == 8 || sz == 4, "only supports 64/32bit merging."); if (!is_store) { BLOCK_COMMENT("merged ldr pair"); @@ -4199,7 +4221,7 @@ if (SafepointMechanism::uses_thread_local_poll()) { ldr(dest, Address(rthread, Thread::polling_page_offset())); } else { - unsigned long off; + uint64_t off; adrp(dest, Address(page, rtype), off); assert(off == 0, "polling page must be page aligned"); } @@ -4797,7 +4819,7 @@ Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2, FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, int ae) { Label DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, TAIL, STUB, - DIFFERENCE, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT, + DIFF, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT, SHORT_LOOP_START, TAIL_CHECK; const int STUB_THRESHOLD = 64 + 8; @@ -4884,7 +4906,7 @@ adds(cnt2, cnt2, isUL ? 4 : 8); br(GE, TAIL); eor(rscratch2, tmp1, tmp2); - cbnz(rscratch2, DIFFERENCE); + cbnz(rscratch2, DIFF); // main loop bind(NEXT_WORD); if (str1_isL == str2_isL) { @@ -4910,10 +4932,10 @@ eor(rscratch2, tmp1, tmp2); cbz(rscratch2, NEXT_WORD); - b(DIFFERENCE); + b(DIFF); bind(TAIL); eor(rscratch2, tmp1, tmp2); - cbnz(rscratch2, DIFFERENCE); + cbnz(rscratch2, DIFF); // Last longword. In the case where length == 4 we compare the // same longword twice, but that's still faster than another // conditional branch. @@ -4937,7 +4959,7 @@ // Find the first different characters in the longwords and // compute their difference. - bind(DIFFERENCE); + bind(DIFF); rev(rscratch2, rscratch2); clz(rscratch2, rscratch2); andr(rscratch2, rscratch2, isLL ? -8 : -16);
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 9a18e79..7e23c16 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
@@ -27,6 +27,7 @@ #define CPU_AARCH64_VM_MACROASSEMBLER_AARCH64_HPP #include "asm/assembler.inline.hpp" +#include "runtime/vm_version.hpp" // MacroAssembler extends Assembler by frequently used macros. // @@ -88,7 +89,7 @@ = (operand_valid_for_logical_immediate(false /*is32*/, (uint64_t)Universe::narrow_klass_base()) && ((uint64_t)Universe::narrow_klass_base() - > (1UL << log2_intptr(Universe::narrow_klass_range())))); + > (1ULL << log2_intptr(checked_cast<uintptr_t>(Universe::narrow_klass_range()))))); } // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code. @@ -185,7 +186,15 @@ mov(rscratch2, call_site); } +// Microsoft's MSVC team thinks that the __FUNCSIG__ is approximately (sympathy for calling conventions) equivalent to __PRETTY_FUNCTION__ +// Also, from Clang patch: "It is very similar to GCC's PRETTY_FUNCTION, except it prints the calling convention." +// https://reviews.llvm.org/D3311 + +#ifdef _WIN64 +#define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__) +#else #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__) +#endif // aliases defined in AARCH64 spec @@ -460,6 +469,8 @@ void push(RegSet regs, Register stack) { if (regs.bits()) push(regs.bits(), stack); } void pop(RegSet regs, Register stack) { if (regs.bits()) pop(regs.bits(), stack); } + static RegSet call_clobbered_registers(); + // Push and pop everything that might be clobbered by a native // runtime call except rscratch1 and rscratch2. (They are always // scratch, so we don't have to protect them.) Only save the lower @@ -470,31 +481,20 @@ // now mov instructions for loading absolute addresses and 32 or // 64 bit integers - inline void mov(Register dst, address addr) - { - mov_immediate64(dst, (uint64_t)addr); - } + inline void mov(Register dst, address addr) { mov_immediate64(dst, (uint64_t)addr); } - inline void mov(Register dst, uint64_t imm64) - { - mov_immediate64(dst, imm64); - } + inline void mov(Register dst, int imm64) { mov_immediate64(dst, (uint64_t)imm64); } + inline void mov(Register dst, long imm64) { mov_immediate64(dst, (uint64_t)imm64); } + inline void mov(Register dst, long long imm64) { mov_immediate64(dst, (uint64_t)imm64); } + inline void mov(Register dst, unsigned int imm64) { mov_immediate64(dst, (uint64_t)imm64); } + inline void mov(Register dst, unsigned long imm64) { mov_immediate64(dst, (uint64_t)imm64); } + inline void mov(Register dst, unsigned long long imm64) { mov_immediate64(dst, (uint64_t)imm64); } inline void movw(Register dst, uint32_t imm32) { mov_immediate32(dst, imm32); } - inline void mov(Register dst, int64_t l) - { - mov(dst, (uint64_t)l); - } - - inline void mov(Register dst, int i) - { - mov(dst, (int64_t)i); - } - void mov(Register dst, RegisterOrConstant src) { if (src.is_register()) mov(dst, src.as_register()); @@ -514,10 +514,10 @@ // Generalized Test Bit And Branch, including a "far" variety which // spans more than 32KiB. - void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool far = false) { + void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool isfar = false) { assert(cond == EQ || cond == NE, "must be"); - if (far) + if (isfar) cond = ~cond; void (Assembler::* branch)(Register Rt, int bitpos, Label &L); @@ -526,7 +526,7 @@ else branch = &Assembler::tbnz; - if (far) { + if (isfar) { Label L; (this->*branch)(Rt, bitpos, L); b(dest); @@ -1300,6 +1300,24 @@ Register zlen, Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5, Register tmp6, Register tmp7); void mul_add(Register out, Register in, Register offs, Register len, Register k); + void ghash_multiply(FloatRegister result_lo, FloatRegister result_hi, + FloatRegister a, FloatRegister b, FloatRegister a1_xor_a0, + FloatRegister tmp1, FloatRegister tmp2, FloatRegister tmp3); + void ghash_reduce(FloatRegister result, FloatRegister lo, FloatRegister hi, + FloatRegister p, FloatRegister z, FloatRegister t1); + void ghash_processBlocks_wide(address p, Register state, Register subkeyH, + Register data, Register blocks, int unrolls); + void ghash_modmul (FloatRegister result, + FloatRegister result_lo, FloatRegister result_hi, FloatRegister b, + FloatRegister a, FloatRegister vzr, FloatRegister a1_xor_a0, FloatRegister p, + FloatRegister t1, FloatRegister t2, FloatRegister t3); + + void aesenc_loadkeys(Register key, Register keylen); + void aesecb_encrypt(Register from, Register to, Register keylen, + FloatRegister data = v0, int unrolls = 1); + void aesecb_decrypt(Register from, Register to, Register key, Register keylen); + void aes_round(FloatRegister input, FloatRegister subkey); + // ISB may be needed because of a safepoint void maybe_isb() { isb(); }
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp new file mode 100644 index 0000000..588ef67 --- /dev/null +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp
@@ -0,0 +1,685 @@ +/* + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "asm/assembler.hpp" +#include "asm/assembler.inline.hpp" +#include "macroAssembler_aarch64.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/stubRoutines.hpp" + +void MacroAssembler::aesecb_decrypt(Register from, Register to, Register key, Register keylen) { + Label L_doLast; + + ld1(v0, T16B, from); // get 16 bytes of input + + ld1(v5, T16B, post(key, 16)); + rev32(v5, T16B, v5); + + ld1(v1, v2, v3, v4, T16B, post(key, 64)); + rev32(v1, T16B, v1); + rev32(v2, T16B, v2); + rev32(v3, T16B, v3); + rev32(v4, T16B, v4); + aesd(v0, v1); + aesimc(v0, v0); + aesd(v0, v2); + aesimc(v0, v0); + aesd(v0, v3); + aesimc(v0, v0); + aesd(v0, v4); + aesimc(v0, v0); + + ld1(v1, v2, v3, v4, T16B, post(key, 64)); + rev32(v1, T16B, v1); + rev32(v2, T16B, v2); + rev32(v3, T16B, v3); + rev32(v4, T16B, v4); + aesd(v0, v1); + aesimc(v0, v0); + aesd(v0, v2); + aesimc(v0, v0); + aesd(v0, v3); + aesimc(v0, v0); + aesd(v0, v4); + aesimc(v0, v0); + + ld1(v1, v2, T16B, post(key, 32)); + rev32(v1, T16B, v1); + rev32(v2, T16B, v2); + + cmpw(keylen, 44); + br(Assembler::EQ, L_doLast); + + aesd(v0, v1); + aesimc(v0, v0); + aesd(v0, v2); + aesimc(v0, v0); + + ld1(v1, v2, T16B, post(key, 32)); + rev32(v1, T16B, v1); + rev32(v2, T16B, v2); + + cmpw(keylen, 52); + br(Assembler::EQ, L_doLast); + + aesd(v0, v1); + aesimc(v0, v0); + aesd(v0, v2); + aesimc(v0, v0); + + ld1(v1, v2, T16B, post(key, 32)); + rev32(v1, T16B, v1); + rev32(v2, T16B, v2); + + bind(L_doLast); + + aesd(v0, v1); + aesimc(v0, v0); + aesd(v0, v2); + + eor(v0, T16B, v0, v5); + + st1(v0, T16B, to); + + // Preserve the address of the start of the key + sub(key, key, keylen, LSL, exact_log2(sizeof (jint))); +} + +// Load expanded key into v17..v31 +void MacroAssembler::aesenc_loadkeys(Register key, Register keylen) { + Label L_loadkeys_44, L_loadkeys_52; + cmpw(keylen, 52); + br(Assembler::LO, L_loadkeys_44); + br(Assembler::EQ, L_loadkeys_52); + + ld1(v17, v18, T16B, post(key, 32)); + rev32(v17, T16B, v17); + rev32(v18, T16B, v18); + bind(L_loadkeys_52); + ld1(v19, v20, T16B, post(key, 32)); + rev32(v19, T16B, v19); + rev32(v20, T16B, v20); + bind(L_loadkeys_44); + ld1(v21, v22, v23, v24, T16B, post(key, 64)); + rev32(v21, T16B, v21); + rev32(v22, T16B, v22); + rev32(v23, T16B, v23); + rev32(v24, T16B, v24); + ld1(v25, v26, v27, v28, T16B, post(key, 64)); + rev32(v25, T16B, v25); + rev32(v26, T16B, v26); + rev32(v27, T16B, v27); + rev32(v28, T16B, v28); + ld1(v29, v30, v31, T16B, post(key, 48)); + rev32(v29, T16B, v29); + rev32(v30, T16B, v30); + rev32(v31, T16B, v31); + + // Preserve the address of the start of the key + sub(key, key, keylen, LSL, exact_log2(sizeof (jint))); +} + +// NeoverseTM N1Software Optimization Guide: +// Adjacent AESE/AESMC instruction pairs and adjacent AESD/AESIMC +// instruction pairs will exhibit the performance characteristics +// described in Section 4.6. +void MacroAssembler::aes_round(FloatRegister input, FloatRegister subkey) { + aese(input, subkey); aesmc(input, input); +} + +// KernelGenerator +// +// The abstract base class of an unrolled function generator. +// Subclasses override generate(), length(), and next() to generate +// unrolled and interleaved functions. +// +// The core idea is that a subclass defines a method which generates +// the base case of a function and a method to generate a clone of it, +// shifted to a different set of registers. KernelGenerator will then +// generate several interleaved copies of the function, with each one +// using a different set of registers. + +// The subclass must implement three methods: length(), which is the +// number of instruction bundles in the intrinsic, generate(int n) +// which emits the nth instruction bundle in the intrinsic, and next() +// which takes an instance of the generator and returns a version of it, +// shifted to a new set of registers. + +class KernelGenerator: public MacroAssembler { +protected: + const int _unrolls; +public: + KernelGenerator(Assembler *as, int unrolls) + : MacroAssembler(as->code()), _unrolls(unrolls) { } + virtual void generate(int index) = 0; + virtual int length() = 0; + virtual KernelGenerator *next() = 0; + int unrolls() { return _unrolls; } + void unroll(); +}; + +void KernelGenerator::unroll() { + ResourceMark rm; + KernelGenerator **generators + = NEW_RESOURCE_ARRAY(KernelGenerator *, unrolls()); + + generators[0] = this; + for (int i = 1; i < unrolls(); i++) { + generators[i] = generators[i-1]->next(); + } + + for (int j = 0; j < length(); j++) { + for (int i = 0; i < unrolls(); i++) { + generators[i]->generate(j); + } + } +} + +// An unrolled and interleaved generator for AES encryption. +class AESKernelGenerator: public KernelGenerator { + Register _from, _to; + const Register _keylen; + FloatRegister _data; + const FloatRegister _subkeys; + bool _once; + Label _rounds_44, _rounds_52; + +public: + AESKernelGenerator(Assembler *as, int unrolls, + Register from, Register to, Register keylen, FloatRegister data, + FloatRegister subkeys, bool once = true) + : KernelGenerator(as, unrolls), + _from(from), _to(to), _keylen(keylen), _data(data), + _subkeys(subkeys), _once(once) { + } + + virtual void generate(int index) { + switch (index) { + case 0: + if (_from != noreg) { + ld1(_data, T16B, _from); // get 16 bytes of input + } + break; + case 1: + if (_once) { + cmpw(_keylen, 52); + br(Assembler::LO, _rounds_44); + br(Assembler::EQ, _rounds_52); + } + break; + case 2: aes_round(_data, _subkeys + 0); break; + case 3: aes_round(_data, _subkeys + 1); break; + case 4: + if (_once) bind(_rounds_52); + break; + case 5: aes_round(_data, _subkeys + 2); break; + case 6: aes_round(_data, _subkeys + 3); break; + case 7: + if (_once) bind(_rounds_44); + break; + case 8: aes_round(_data, _subkeys + 4); break; + case 9: aes_round(_data, _subkeys + 5); break; + case 10: aes_round(_data, _subkeys + 6); break; + case 11: aes_round(_data, _subkeys + 7); break; + case 12: aes_round(_data, _subkeys + 8); break; + case 13: aes_round(_data, _subkeys + 9); break; + case 14: aes_round(_data, _subkeys + 10); break; + case 15: aes_round(_data, _subkeys + 11); break; + case 16: aes_round(_data, _subkeys + 12); break; + case 17: aese(_data, _subkeys + 13); break; + case 18: eor(_data, T16B, _data, _subkeys + 14); break; + case 19: + if (_to != noreg) { + st1(_data, T16B, _to); + } + break; + default: ShouldNotReachHere(); + } + } + + virtual KernelGenerator *next() { + return new AESKernelGenerator(this, _unrolls, + _from, _to, _keylen, + _data + 1, _subkeys, /*once*/false); + } + + virtual int length() { return 20; } +}; + +// Uses expanded key in v17..v31 +// Returns encrypted values in inputs. +// If to != noreg, store value at to; likewise from +// Preserves key, keylen +// Increments from, to +// Input data in v0, v1, ... +// unrolls controls the number of times to unroll the generated function +void MacroAssembler::aesecb_encrypt(Register from, Register to, Register keylen, + FloatRegister data, int unrolls) { + AESKernelGenerator(this, unrolls, from, to, keylen, data, v17) .unroll(); +} + +// ghash_multiply and ghash_reduce are the non-unrolled versions of +// the GHASH function generators. +void MacroAssembler::ghash_multiply(FloatRegister result_lo, FloatRegister result_hi, + FloatRegister a, FloatRegister b, FloatRegister a1_xor_a0, + FloatRegister tmp1, FloatRegister tmp2, FloatRegister tmp3) { + // Karatsuba multiplication performs a 128*128 -> 256-bit + // multiplication in three 128-bit multiplications and a few + // additions. + // + // (C1:C0) = A1*B1, (D1:D0) = A0*B0, (E1:E0) = (A0+A1)(B0+B1) + // (A1:A0)(B1:B0) = C1:(C0+C1+D1+E1):(D1+C0+D0+E0):D0 + // + // Inputs: + // + // A0 in a.d[0] (subkey) + // A1 in a.d[1] + // (A1+A0) in a1_xor_a0.d[0] + // + // B0 in b.d[0] (state) + // B1 in b.d[1] + + ext(tmp1, T16B, b, b, 0x08); + pmull2(result_hi, T1Q, b, a, T2D); // A1*B1 + eor(tmp1, T16B, tmp1, b); // (B1+B0) + pmull(result_lo, T1Q, b, a, T1D); // A0*B0 + pmull(tmp2, T1Q, tmp1, a1_xor_a0, T1D); // (A1+A0)(B1+B0) + + ext(tmp1, T16B, result_lo, result_hi, 0x08); + eor(tmp3, T16B, result_hi, result_lo); // A1*B1+A0*B0 + eor(tmp2, T16B, tmp2, tmp1); + eor(tmp2, T16B, tmp2, tmp3); + + // Register pair <result_hi:result_lo> holds the result of carry-less multiplication + ins(result_hi, D, tmp2, 0, 1); + ins(result_lo, D, tmp2, 1, 0); +} + +void MacroAssembler::ghash_reduce(FloatRegister result, FloatRegister lo, FloatRegister hi, + FloatRegister p, FloatRegister vzr, FloatRegister t1) { + const FloatRegister t0 = result; + + // The GCM field polynomial f is z^128 + p(z), where p = + // z^7+z^2+z+1. + // + // z^128 === -p(z) (mod (z^128 + p(z))) + // + // so, given that the product we're reducing is + // a == lo + hi * z^128 + // substituting, + // === lo - hi * p(z) (mod (z^128 + p(z))) + // + // we reduce by multiplying hi by p(z) and subtracting the result + // from (i.e. XORing it with) lo. Because p has no nonzero high + // bits we can do this with two 64-bit multiplications, lo*p and + // hi*p. + + pmull2(t0, T1Q, hi, p, T2D); + ext(t1, T16B, t0, vzr, 8); + eor(hi, T16B, hi, t1); + ext(t1, T16B, vzr, t0, 8); + eor(lo, T16B, lo, t1); + pmull(t0, T1Q, hi, p, T1D); + eor(result, T16B, lo, t0); +} + +class GHASHMultiplyGenerator: public KernelGenerator { + FloatRegister _result_lo, _result_hi, _b, + _a, _vzr, _a1_xor_a0, _p, + _tmp1, _tmp2, _tmp3; + +public: + GHASHMultiplyGenerator(Assembler *as, int unrolls, + FloatRegister result_lo, FloatRegister result_hi, + /* offsetted registers */ + FloatRegister b, + /* non-offsetted (shared) registers */ + FloatRegister a, FloatRegister a1_xor_a0, FloatRegister p, FloatRegister vzr, + /* offseted (temp) registers */ + FloatRegister tmp1, FloatRegister tmp2, FloatRegister tmp3) + : KernelGenerator(as, unrolls), + _result_lo(result_lo), _result_hi(result_hi), _b(b), + _a(a), _vzr(vzr), _a1_xor_a0(a1_xor_a0), _p(p), + _tmp1(tmp1), _tmp2(tmp2), _tmp3(tmp3) { } + + static const int register_stride = 7; + + virtual void generate(int index) { + // Karatsuba multiplication performs a 128*128 -> 256-bit + // multiplication in three 128-bit multiplications and a few + // additions. + // + // (C1:C0) = A1*B1, (D1:D0) = A0*B0, (E1:E0) = (A0+A1)(B0+B1) + // (A1:A0)(B1:B0) = C1:(C0+C1+D1+E1):(D1+C0+D0+E0):D0 + // + // Inputs: + // + // A0 in a.d[0] (subkey) + // A1 in a.d[1] + // (A1+A0) in a1_xor_a0.d[0] + // + // B0 in b.d[0] (state) + // B1 in b.d[1] + + switch (index) { + case 0: ext(_tmp1, T16B, _b, _b, 0x08); break; + case 1: pmull2(_result_hi, T1Q, _b, _a, T2D); // A1*B1 + break; + case 2: eor(_tmp1, T16B, _tmp1, _b); // (B1+B0) + break; + case 3: pmull(_result_lo, T1Q, _b, _a, T1D); // A0*B0 + break; + case 4: pmull(_tmp2, T1Q, _tmp1, _a1_xor_a0, T1D); // (A1+A0)(B1+B0) + break; + + case 5: ext(_tmp1, T16B, _result_lo, _result_hi, 0x08); break; + case 6: eor(_tmp3, T16B, _result_hi, _result_lo); // A1*B1+A0*B0 + break; + case 7: eor(_tmp2, T16B, _tmp2, _tmp1); break; + case 8: eor(_tmp2, T16B, _tmp2, _tmp3); break; + + // Register pair <_result_hi:_result_lo> holds the _result of carry-less multiplication + case 9: ins(_result_hi, D, _tmp2, 0, 1); break; + case 10: ins(_result_lo, D, _tmp2, 1, 0); break; + default: ShouldNotReachHere(); + } + } + + virtual KernelGenerator *next() { + GHASHMultiplyGenerator *result + = new GHASHMultiplyGenerator(this, _unrolls, _result_lo, _result_hi, + _b, _a, _a1_xor_a0, _p, _vzr, + _tmp1, _tmp2, _tmp3); + result->_result_lo += register_stride; + result->_result_hi += register_stride; + result->_b += register_stride; + result->_tmp1 += register_stride; + result->_tmp2 += register_stride; + result->_tmp3 += register_stride; + return result; + } + + virtual int length() { return 11; } +}; + +// Reduce the 128-bit product in hi:lo by the GCM field polynomial. +// The FloatRegister argument called data is optional: if it is a +// valid register, we interleave LD1 instructions with the +// reduction. This is to reduce latency next time around the loop. +class GHASHReduceGenerator: public KernelGenerator { + FloatRegister _result, _lo, _hi, _p, _vzr, _data, _t1; + int _once; +public: + GHASHReduceGenerator(Assembler *as, int unrolls, + /* offsetted registers */ + FloatRegister result, FloatRegister lo, FloatRegister hi, + /* non-offsetted (shared) registers */ + FloatRegister p, FloatRegister vzr, FloatRegister data, + /* offseted (temp) registers */ + FloatRegister t1) + : KernelGenerator(as, unrolls), + _result(result), _lo(lo), _hi(hi), + _p(p), _vzr(vzr), _data(data), _t1(t1), _once(true) { } + + static const int register_stride = 7; + + virtual void generate(int index) { + const FloatRegister t0 = _result; + + switch (index) { + // The GCM field polynomial f is z^128 + p(z), where p = + // z^7+z^2+z+1. + // + // z^128 === -p(z) (mod (z^128 + p(z))) + // + // so, given that the product we're reducing is + // a == lo + hi * z^128 + // substituting, + // === lo - hi * p(z) (mod (z^128 + p(z))) + // + // we reduce by multiplying hi by p(z) and subtracting the _result + // from (i.e. XORing it with) lo. Because p has no nonzero high + // bits we can do this with two 64-bit multiplications, lo*p and + // hi*p. + + case 0: pmull2(t0, T1Q, _hi, _p, T2D); break; + case 1: ext(_t1, T16B, t0, _vzr, 8); break; + case 2: eor(_hi, T16B, _hi, _t1); break; + case 3: ext(_t1, T16B, _vzr, t0, 8); break; + case 4: eor(_lo, T16B, _lo, _t1); break; + case 5: pmull(t0, T1Q, _hi, _p, T1D); break; + case 6: eor(_result, T16B, _lo, t0); break; + default: ShouldNotReachHere(); + } + + // Sprinkle load instructions into the generated instructions + if (_data->is_valid() && _once) { + assert(length() >= unrolls(), "not enough room for inteleaved loads"); + if (index < unrolls()) { + ld1((_data + index*register_stride), T16B, post(r2, 0x10)); + } + } + } + + virtual KernelGenerator *next() { + GHASHReduceGenerator *result + = new GHASHReduceGenerator(this, _unrolls, + _result, _lo, _hi, _p, _vzr, _data, _t1); + result->_result += register_stride; + result->_hi += register_stride; + result->_lo += register_stride; + result->_t1 += register_stride; + result->_once = false; + return result; + } + + int length() { return 7; } +}; + +// Perform a GHASH multiply/reduce on a single FloatRegister. +void MacroAssembler::ghash_modmul(FloatRegister result, + FloatRegister result_lo, FloatRegister result_hi, FloatRegister b, + FloatRegister a, FloatRegister vzr, FloatRegister a1_xor_a0, FloatRegister p, + FloatRegister t1, FloatRegister t2, FloatRegister t3) { + ghash_multiply(result_lo, result_hi, a, b, a1_xor_a0, t1, t2, t3); + ghash_reduce(result, result_lo, result_hi, p, vzr, t1); +} + +// Interleaved GHASH processing. +// +// Clobbers all vector registers. +// +void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register state, + Register subkeyH, + Register data, Register blocks, int unrolls) { + int register_stride = 7; + + // Bafflingly, GCM uses little-endian for the byte order, but + // big-endian for the bit order. For example, the polynomial 1 is + // represented as the 16-byte string 80 00 00 00 | 12 bytes of 00. + // + // So, we must either reverse the bytes in each word and do + // everything big-endian or reverse the bits in each byte and do + // it little-endian. On AArch64 it's more idiomatic to reverse + // the bits in each byte (we have an instruction, RBIT, to do + // that) and keep the data in little-endian bit order throught the + // calculation, bit-reversing the inputs and outputs. + + assert(unrolls * register_stride < 32, "out of registers"); + + FloatRegister a1_xor_a0 = v28; + FloatRegister Hprime = v29; + FloatRegister vzr = v30; + FloatRegister p = v31; + eor(vzr, T16B, vzr, vzr); // zero register + + ldrq(p, field_polynomial); // The field polynomial + + ldrq(v0, Address(state)); + ldrq(Hprime, Address(subkeyH)); + + rev64(v0, T16B, v0); // Bit-reverse words in state and subkeyH + rbit(v0, T16B, v0); + rev64(Hprime, T16B, Hprime); + rbit(Hprime, T16B, Hprime); + + // Powers of H -> Hprime + + Label already_calculated, done; + { + // The first time around we'll have to calculate H**2, H**3, etc. + // Look at the largest power of H in the subkeyH array to see if + // it's already been calculated. + ldp(rscratch1, rscratch2, Address(subkeyH, 16 * (unrolls - 1))); + orr(rscratch1, rscratch1, rscratch2); + cbnz(rscratch1, already_calculated); + + orr(v6, T16B, Hprime, Hprime); // Start with H in v6 and Hprime + for (int i = 1; i < unrolls; i++) { + ext(a1_xor_a0, T16B, Hprime, Hprime, 0x08); // long-swap subkeyH into a1_xor_a0 + eor(a1_xor_a0, T16B, a1_xor_a0, Hprime); // xor subkeyH into subkeyL (Karatsuba: (A1+A0)) + ghash_modmul(/*result*/v6, /*result_lo*/v5, /*result_hi*/v4, /*b*/v6, + Hprime, vzr, a1_xor_a0, p, + /*temps*/v1, v3, v2); + rev64(v1, T16B, v6); + rbit(v1, T16B, v1); + strq(v1, Address(subkeyH, 16 * i)); + } + b(done); + } + { + bind(already_calculated); + + // Load the largest power of H we need into v6. + ldrq(v6, Address(subkeyH, 16 * (unrolls - 1))); + rev64(v6, T16B, v6); + rbit(v6, T16B, v6); + } + bind(done); + + orr(Hprime, T16B, v6, v6); // Move H ** unrolls into Hprime + + // Hprime contains (H ** 1, H ** 2, ... H ** unrolls) + // v0 contains the initial state. Clear the others. + for (int i = 1; i < unrolls; i++) { + int ofs = register_stride * i; + eor(ofs+v0, T16B, ofs+v0, ofs+v0); // zero each state register + } + + ext(a1_xor_a0, T16B, Hprime, Hprime, 0x08); // long-swap subkeyH into a1_xor_a0 + eor(a1_xor_a0, T16B, a1_xor_a0, Hprime); // xor subkeyH into subkeyL (Karatsuba: (A1+A0)) + + // Load #unrolls blocks of data + for (int ofs = 0; ofs < unrolls * register_stride; ofs += register_stride) { + ld1(v2+ofs, T16B, post(data, 0x10)); + } + + // Register assignments, replicated across 4 clones, v0 ... v23 + // + // v0: input / output: current state, result of multiply/reduce + // v1: temp + // v2: input: one block of data (the ciphertext) + // also used as a temp once the data has been consumed + // v3: temp + // v4: output: high part of product + // v5: output: low part ... + // v6: unused + // + // Not replicated: + // + // v28: High part of H xor low part of H' + // v29: H' (hash subkey) + // v30: zero + // v31: Reduction polynomial of the Galois field + + // Inner loop. + // Do the whole load/add/multiply/reduce over all our data except + // the last few rows. + { + Label L_ghash_loop; + bind(L_ghash_loop); + + // Prefetching doesn't help here. In fact, on Neoverse N1 it's worse. + // prfm(Address(data, 128), PLDL1KEEP); + + // Xor data into current state + for (int ofs = 0; ofs < unrolls * register_stride; ofs += register_stride) { + rbit((v2+ofs), T16B, (v2+ofs)); + eor((v2+ofs), T16B, v0+ofs, (v2+ofs)); // bit-swapped data ^ bit-swapped state + } + + // Generate fully-unrolled multiply-reduce in two stages. + + (new GHASHMultiplyGenerator(this, unrolls, + /*result_lo*/v5, /*result_hi*/v4, /*data*/v2, + Hprime, a1_xor_a0, p, vzr, + /*temps*/v1, v3, /* reuse b*/v2))->unroll(); + + // NB: GHASHReduceGenerator also loads the next #unrolls blocks of + // data into v0, v0+ofs, the current state. + (new GHASHReduceGenerator (this, unrolls, + /*result*/v0, /*lo*/v5, /*hi*/v4, p, vzr, + /*data*/v2, /*temp*/v3))->unroll(); + + sub(blocks, blocks, unrolls); + cmp(blocks, (unsigned char)(unrolls * 2)); + br(GE, L_ghash_loop); + } + + // Merge the #unrolls states. Note that the data for the next + // iteration has already been loaded into v4, v4+ofs, etc... + + // First, we multiply/reduce each clone by the appropriate power of H. + for (int i = 0; i < unrolls; i++) { + int ofs = register_stride * i; + ldrq(Hprime, Address(subkeyH, 16 * (unrolls - i - 1))); + + rbit(v2+ofs, T16B, v2+ofs); + eor(v2+ofs, T16B, ofs+v0, v2+ofs); // bit-swapped data ^ bit-swapped state + + rev64(Hprime, T16B, Hprime); + rbit(Hprime, T16B, Hprime); + ext(a1_xor_a0, T16B, Hprime, Hprime, 0x08); // long-swap subkeyH into a1_xor_a0 + eor(a1_xor_a0, T16B, a1_xor_a0, Hprime); // xor subkeyH into subkeyL (Karatsuba: (A1+A0)) + ghash_modmul(/*result*/v0+ofs, /*result_lo*/v5+ofs, /*result_hi*/v4+ofs, /*b*/v2+ofs, + Hprime, vzr, a1_xor_a0, p, + /*temps*/v1+ofs, v3+ofs, /* reuse b*/v2+ofs); + } + + // Then we sum the results. + for (int i = 0; i < unrolls - 1; i++) { + int ofs = register_stride * i; + eor(v0, T16B, v0, v0 + register_stride + ofs); + } + + sub(blocks, blocks, (unsigned char)unrolls); + + // And finally bit-reverse the state back to big endian. + rev64(v0, T16B, v0); + rbit(v0, T16B, v0); + st1(v0, T16B, state); +}
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp index d84915e..290ee8a 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp
@@ -689,7 +689,7 @@ RECOMP_FOR1_CHECK; Register tmp2 = r1, n = r2, jv = r4, tmp5 = r5, jx = r6, tmp3 = r7, iqBase = r10, ih = r11, tmp4 = r12, tmp1 = r13, - jz = r14, j = r15, twoOverPiBase = r16, i = r17, qBase = r18; + jz = r14, j = r15, twoOverPiBase = r16, i = r17, qBase = r19; // jp = jk == init_jk[prec] = init_jk[2] == {2,3,4,6}[2] == 4 // jx = nx - 1 lea(twoOverPiBase, ExternalAddress(two_over_pi)); @@ -1421,6 +1421,12 @@ Label DONE, ARG_REDUCTION, TINY_X, RETURN_SIN, EARLY_CASE; Register X = r0, absX = r1, n = r2, ix = r3; FloatRegister y0 = v4, y1 = v5; + + enter(); + // r19 is used in TemplateInterpreterGenerator::generate_math_entry + RegSet saved_regs = RegSet::of(r19); + push (saved_regs, sp); + block_comment("check |x| ~< pi/4, NaN, Inf and |x| < 2**-27 cases"); { fmovd(X, v0); mov(rscratch2, 0x3e400000); @@ -1438,14 +1444,14 @@ // Set last bit unconditionally to make it NaN orr(r10, r10, 1); fmovd(v0, r10); - ret(lr); + b(DONE); } block_comment("kernel_sin/kernel_cos: if(ix<0x3e400000) {<fast return>}"); { bind(TINY_X); if (isCos) { fmovd(v0, 1.0); } - ret(lr); + b(DONE); } bind(ARG_REDUCTION); /* argument reduction needed */ block_comment("n = __ieee754_rem_pio2(x,y);"); { @@ -1465,7 +1471,7 @@ tbz(n, 1, DONE); } fnegd(v0, v0); - ret(lr); + b(DONE); bind(RETURN_SIN); generate_kernel_sin(y0, true, dsin_coef); if (isCos) { @@ -1474,7 +1480,7 @@ tbz(n, 1, DONE); } fnegd(v0, v0); - ret(lr); + b(DONE); } bind(EARLY_CASE); eor(y1, T8B, y1, y1); @@ -1484,5 +1490,7 @@ generate_kernel_sin(v0, false, dsin_coef); } bind(DONE); + pop(saved_regs, sp); + leave(); ret(lr); }
diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp index a1166c6..555baa1 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
@@ -681,7 +681,7 @@ return 0; } } - size_t size_in_bytes() { return 1 << size(); } + size_t size_in_bytes() { return 1ULL << size(); } bool is_not_pre_post_index() { return (is_ldst_ur() || is_ldst_unsigned_offset()); } bool is_load() { assert(Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b01 ||
diff --git a/src/hotspot/cpu/aarch64/register_aarch64.cpp b/src/hotspot/cpu/aarch64/register_aarch64.cpp index 36cbe3f..c39ed85 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.cpp
@@ -38,7 +38,7 @@ "c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7", "rscratch1", "rscratch2", "r10", "r11", "r12", "r13", "r14", "r15", "r16", - "r17", "r18", "r19", + "r17", "r18_tls", "r19", "resp", "rdispatch", "rbcp", "r23", "rlocals", "rmonitors", "rcpool", "rheapbase", "rthread", "rfp", "lr", "sp" };
diff --git a/src/hotspot/cpu/aarch64/register_aarch64.hpp b/src/hotspot/cpu/aarch64/register_aarch64.hpp index 458a797..20f5491 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.hpp
@@ -91,7 +91,18 @@ CONSTANT_REGISTER_DECLARATION(Register, r15, (15)); CONSTANT_REGISTER_DECLARATION(Register, r16, (16)); CONSTANT_REGISTER_DECLARATION(Register, r17, (17)); -CONSTANT_REGISTER_DECLARATION(Register, r18, (18)); + +// In the ABI for Windows+AArch64 the register r18 is used to store the pointer +// to the current thread's TEB (where TLS variables are stored). We could +// carefully save and restore r18 at key places, however Win32 Structured +// Exception Handling (SEH) is using TLS to unwind the stack. If r18 is used +// for any other purpose at the time of an exception happening, SEH would not +// be able to unwind the stack properly and most likely crash. +// +// It's easier to avoid allocating r18 altogether. +// +// See https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#integer-registers +CONSTANT_REGISTER_DECLARATION(Register, r18_tls, (18)); CONSTANT_REGISTER_DECLARATION(Register, r19, (19)); CONSTANT_REGISTER_DECLARATION(Register, r20, (20)); CONSTANT_REGISTER_DECLARATION(Register, r21, (21)); @@ -207,6 +218,8 @@ static const int max_fpr; }; +class RegSetIterator; + // A set of registers class RegSet { uint32_t _bitset; @@ -234,6 +247,11 @@ return *this; } + RegSet &operator-=(const RegSet aSet) { + *this = *this - aSet; + return *this; + } + static RegSet of(Register r1) { return RegSet(r1); } @@ -260,6 +278,49 @@ } uint32_t bits() const { return _bitset; } + +private: + + Register first() { + uint32_t first = _bitset & -_bitset; + return first ? as_Register(exact_log2(first)) : noreg; + } + +public: + + friend class RegSetIterator; + + RegSetIterator begin(); }; +class RegSetIterator { + RegSet _regs; + +public: + RegSetIterator(RegSet x): _regs(x) {} + RegSetIterator(const RegSetIterator& mit) : _regs(mit._regs) {} + + RegSetIterator& operator++() { + Register r = _regs.first(); + if (r != noreg) + _regs -= r; + return *this; + } + + bool operator==(const RegSetIterator& rhs) const { + return _regs.bits() == rhs._regs.bits(); + } + bool operator!=(const RegSetIterator& rhs) const { + return ! (rhs == *this); + } + + Register operator*() { + return _regs.first(); + } +}; + +inline RegSetIterator RegSet::begin() { + return RegSetIterator(*this); +} + #endif // CPU_AARCH64_VM_REGISTER_AARCH64_HPP
diff --git a/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp b/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp index c181090..17d3bae 100644 --- a/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp
@@ -50,7 +50,7 @@ REGISTER_DEFINITION(Register, r15); REGISTER_DEFINITION(Register, r16); REGISTER_DEFINITION(Register, r17); -REGISTER_DEFINITION(Register, r18); +REGISTER_DEFINITION(Register, r18_tls); // see comment in register_aarch64.hpp REGISTER_DEFINITION(Register, r19); REGISTER_DEFINITION(Register, r20); REGISTER_DEFINITION(Register, r21);
diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 325c15c..9a26c7c 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp
@@ -1,6 +1,7 @@ /* * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -715,7 +716,7 @@ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); } -int SharedRuntime::c_calling_convention(const BasicType *sig_bt, +static int c_calling_convention_priv(const BasicType *sig_bt, VMRegPair *regs, VMRegPair *regs2, int total_args_passed) { @@ -746,6 +747,11 @@ if (int_args < Argument::n_int_register_parameters_c) { regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); } else { +#ifdef __APPLE__ + // Less-than word types are stored one after another. + // The code is unable to handle this so bailout. + return -1; +#endif regs[i].set1(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -768,6 +774,11 @@ if (fp_args < Argument::n_float_register_parameters_c) { regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); } else { +#ifdef __APPLE__ + // Less-than word types are stored one after another. + // The code is unable to handle this so bailout. + return -1; +#endif regs[i].set1(VMRegImpl::stack2reg(stk_args)); stk_args += 2; } @@ -794,6 +805,16 @@ return stk_args; } +int SharedRuntime::c_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + VMRegPair *regs2, + int total_args_passed) +{ + int result = c_calling_convention_priv(sig_bt, regs, regs2, total_args_passed); + guarantee(result >= 0, "Unsupported arguments configuration"); + return result; +} + // On 64 bit we will store integer like items to the stack as // 64 bits items (sparc abi) even though java would only store // 32bits for a parameter. On 32bit it will simply be 32 bits @@ -1340,7 +1361,11 @@ // Now figure out where the args must be stored and how much stack space // they require. int out_arg_slots; - out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); + out_arg_slots = c_calling_convention_priv(out_sig_bt, out_regs, NULL, total_c_args); + + if (out_arg_slots < 0) { + return NULL; + } // Compute framesize for the wrapper. We need to handlize all oops in // incoming registers @@ -1473,7 +1498,7 @@ // Generate stack overflow check if (UseStackBanging) { - __ bang_stack_with_offset(JavaThread::stack_shadow_zone_size()); + __ bang_stack_with_offset(checked_cast<int>(JavaThread::stack_shadow_zone_size())); } else { Unimplemented(); } @@ -2421,7 +2446,7 @@ __ sub(sp, sp, r19); // Push interpreter frames in a loop - __ mov(rscratch1, (address)0xDEADDEAD); // Make a recognizable pattern + __ mov(rscratch1, (uint64_t)0xDEADDEAD); // Make a recognizable pattern __ mov(rscratch2, rscratch1); Label loop; __ bind(loop);
diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index f4a68a3..bd4b5d7 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
@@ -1073,7 +1073,7 @@ Label copy4, copy8, copy16, copy32, copy80, copy128, copy_big, finish; const Register t2 = r5, t3 = r6, t4 = r7, t5 = r8; const Register t6 = r9, t7 = r10, t8 = r11, t9 = r12; - const Register send = r17, dend = r18; + const Register send = r17, dend = r16; if (PrefetchCopyIntervalInBytes > 0) __ prfm(Address(s, 0), PLDL1KEEP); @@ -1286,23 +1286,27 @@ void clobber_registers() { #ifdef ASSERT + RegSet clobbered + = MacroAssembler::call_clobbered_registers() - rscratch1; __ mov(rscratch1, (uint64_t)0xdeadbeef); __ orr(rscratch1, rscratch1, rscratch1, Assembler::LSL, 32); - for (Register r = r3; r <= r18; r++) - if (r != rscratch1) __ mov(r, rscratch1); + for (RegSetIterator it = clobbered.begin(); *it != noreg; ++it) { + __ mov(*it, rscratch1); + } #endif + } // Scan over array at a for count oops, verifying each one. // Preserves a and count, clobbers rscratch1 and rscratch2. - void verify_oop_array (size_t size, Register a, Register count, Register temp) { + void verify_oop_array (int size, Register a, Register count, Register temp) { Label loop, end; __ mov(rscratch1, a); __ mov(rscratch2, zr); __ bind(loop); __ cmp(rscratch2, count); __ br(Assembler::HS, end); - if (size == (size_t)wordSize) { + if (size == wordSize) { __ ldr(temp, Address(a, rscratch2, Address::lsl(exact_log2(size)))); __ verify_oop(temp); } else { @@ -1334,7 +1338,7 @@ // used by generate_conjoint_int_oop_copy(). // address generate_disjoint_copy(size_t size, bool aligned, bool is_oop, address *entry, - const char *name, bool dest_uninitialized = false) { + const char *name, bool dest_uninitialized = false) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_reg = RegSet::of(s, d, count); __ align(CodeEntryAlignment); @@ -1363,12 +1367,12 @@ // save regs before copy_memory __ push(RegSet::of(d, count), sp); } - copy_memory(aligned, s, d, count, rscratch1, size); + copy_memory(aligned, s, d, count, rscratch1, checked_cast<int>(size)); if (is_oop) { __ pop(RegSet::of(d, count), sp); if (VerifyOops) - verify_oop_array(size, d, count, r16); + verify_oop_array(checked_cast<int>(size), d, count, r16); } bs->arraycopy_epilogue(_masm, decorators, is_oop, d, count, rscratch1, RegSet()); @@ -1394,7 +1398,7 @@ // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // - address generate_conjoint_copy(size_t size, bool aligned, bool is_oop, address nooverlap_target, + address generate_conjoint_copy(int size, bool aligned, bool is_oop, address nooverlap_target, address *entry, const char *name, bool dest_uninitialized = false) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; @@ -1640,7 +1644,7 @@ address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name, bool dest_uninitialized) { const bool is_oop = true; - const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + const int size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); return generate_disjoint_copy(size, aligned, is_oop, entry, name, dest_uninitialized); } @@ -1658,7 +1662,7 @@ address nooverlap_target, address *entry, const char *name, bool dest_uninitialized) { const bool is_oop = true; - const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + const int size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry, name, dest_uninitialized); } @@ -1713,10 +1717,10 @@ RegSet wb_pre_saved_regs = RegSet::range(c_rarg0, c_rarg4); RegSet wb_post_saved_regs = RegSet::of(count); - // Registers used as temps (r18, r19, r20 are save-on-entry) + // Registers used as temps (r19, r20, r21, r22 are save-on-entry) + const Register copied_oop = r22; // actual oop copied const Register count_save = r21; // orig elementscount const Register start_to = r20; // destination array start address - const Register copied_oop = r18; // actual oop copied const Register r19_klass = r19; // oop._klass //--------------------------------------------------------------- @@ -1753,8 +1757,7 @@ // Empty array: Nothing to do. __ cbz(count, L_done); - - __ push(RegSet::of(r18, r19, r20, r21), sp); + __ push(RegSet::of(r19, r20, r21, r22), sp); #ifdef ASSERT BLOCK_COMMENT("assert consistent ckoff/ckval"); @@ -1823,7 +1826,7 @@ bs->arraycopy_epilogue(_masm, decorators, is_oop, start_to, count_save, rscratch1, wb_post_saved_regs); __ bind(L_done_pop); - __ pop(RegSet::of(r18, r19, r20, r21), sp); + __ pop(RegSet::of(r19, r20, r21, r22), sp); inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); __ bind(L_done); @@ -1999,7 +2002,7 @@ // registers used as temp const Register scratch_length = r16; // elements count to copy const Register scratch_src_klass = r17; // array klass - const Register lh = r18; // layout helper + const Register lh = r15; // layout helper // if (length < 0) return -1; __ movw(scratch_length, length); // length (elements count, 32-bits value) @@ -2070,7 +2073,7 @@ // const Register rscratch1_offset = rscratch1; // array offset - const Register r18_elsize = lh; // element size + const Register r15_elsize = lh; // element size __ ubfx(rscratch1_offset, lh, Klass::_lh_header_size_shift, exact_log2(Klass::_lh_header_size_mask+1)); // array_offset @@ -2091,8 +2094,8 @@ // The possible values of elsize are 0-3, i.e. exact_log2(element // size in bytes). We do a simple bitwise binary search. __ BIND(L_copy_bytes); - __ tbnz(r18_elsize, 1, L_copy_ints); - __ tbnz(r18_elsize, 0, L_copy_shorts); + __ tbnz(r15_elsize, 1, L_copy_ints); + __ tbnz(r15_elsize, 0, L_copy_shorts); __ lea(from, Address(src, src_pos));// src_addr __ lea(to, Address(dst, dst_pos));// dst_addr __ movw(count, scratch_length); // length @@ -2105,7 +2108,7 @@ __ b(RuntimeAddress(short_copy_entry)); __ BIND(L_copy_ints); - __ tbnz(r18_elsize, 0, L_copy_longs); + __ tbnz(r15_elsize, 0, L_copy_longs); __ lea(from, Address(src, src_pos, Address::lsl(2)));// src_addr __ lea(to, Address(dst, dst_pos, Address::lsl(2)));// dst_addr __ movw(count, scratch_length); // length @@ -2116,8 +2119,8 @@ { BLOCK_COMMENT("assert long copy {"); Label L; - __ andw(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> r18_elsize - __ cmpw(r18_elsize, LogBytesPerLong); + __ andw(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> r15_elsize + __ cmpw(r15_elsize, LogBytesPerLong); __ br(Assembler::EQ, L); __ stop("must be long copy, but elsize is wrong"); __ bind(L); @@ -2135,8 +2138,8 @@ Label L_plain_copy, L_checkcast_copy; // test array classes for subtyping - __ load_klass(r18, dst); - __ cmp(scratch_src_klass, r18); // usual case is exact equality + __ load_klass(r15, dst); + __ cmp(scratch_src_klass, r15); // usual case is exact equality __ br(Assembler::NE, L_checkcast_copy); // Identically typed arrays can be copied without element-wise checks. @@ -2152,17 +2155,17 @@ __ b(RuntimeAddress(oop_copy_entry)); __ BIND(L_checkcast_copy); - // live at this point: scratch_src_klass, scratch_length, r18 (dst_klass) + // live at this point: scratch_src_klass, scratch_length, r15 (dst_klass) { // Before looking at dst.length, make sure dst is also an objArray. - __ ldrw(rscratch1, Address(r18, lh_offset)); + __ ldrw(rscratch1, Address(r15, lh_offset)); __ movw(rscratch2, objArray_lh); __ eorw(rscratch1, rscratch1, rscratch2); __ cbnzw(rscratch1, L_failed); // It is safe to examine both src.length and dst.length. arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, - r18, L_failed); + r15, L_failed); __ load_klass(dst_klass, dst); // reload @@ -2879,6 +2882,265 @@ return start; } + // CTR AES crypt. + // Arguments: + // + // Inputs: + // c_rarg0 - source byte array address + // c_rarg1 - destination byte array address + // c_rarg2 - K (key) in little endian int array + // c_rarg3 - counter vector byte array address + // c_rarg4 - input length + // c_rarg5 - saved encryptedCounter start + // c_rarg6 - saved used length + // + // Output: + // r0 - input length + // + address generate_counterMode_AESCrypt() { + const Register in = c_rarg0; + const Register out = c_rarg1; + const Register key = c_rarg2; + const Register counter = c_rarg3; + const Register saved_len = c_rarg4, len = r10; + const Register saved_encrypted_ctr = c_rarg5; + const Register used_ptr = c_rarg6, used = r12; + + const Register offset = r7; + const Register keylen = r11; + + const unsigned char block_size = 16; + const int bulk_width = 4; + // NB: bulk_width can be 4 or 8. 8 gives slightly faster + // performance with larger data sizes, but it also means that the + // fast path isn't used until you have at least 8 blocks, and up + // to 127 bytes of data will be executed on the slow path. For + // that reason, and also so as not to blow away too much icache, 4 + // blocks seems like a sensible compromise. + + // Algorithm: + // + // if (len == 0) { + // goto DONE; + // } + // int result = len; + // do { + // if (used >= blockSize) { + // if (len >= bulk_width * blockSize) { + // CTR_large_block(); + // if (len == 0) + // goto DONE; + // } + // for (;;) { + // 16ByteVector v0 = counter; + // embeddedCipher.encryptBlock(v0, 0, encryptedCounter, 0); + // used = 0; + // if (len < blockSize) + // break; /* goto NEXT */ + // 16ByteVector v1 = load16Bytes(in, offset); + // v1 = v1 ^ encryptedCounter; + // store16Bytes(out, offset); + // used = blockSize; + // offset += blockSize; + // len -= blockSize; + // if (len == 0) + // goto DONE; + // } + // } + // NEXT: + // out[outOff++] = (byte)(in[inOff++] ^ encryptedCounter[used++]); + // len--; + // } while (len != 0); + // DONE: + // return result; + // + // CTR_large_block() + // Wide bulk encryption of whole blocks. + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt"); + const address start = __ pc(); + __ enter(); + + Label DONE, CTR_large_block, large_block_return; + __ ldrw(used, Address(used_ptr)); + __ cbzw(saved_len, DONE); + + __ mov(len, saved_len); + __ mov(offset, 0); + + // Compute #rounds for AES based on the length of the key array + __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); + + __ aesenc_loadkeys(key, keylen); + + { + Label L_CTR_loop, NEXT; + + __ bind(L_CTR_loop); + + __ cmp(used, block_size); + __ br(__ LO, NEXT); + + // Maybe we have a lot of data + __ subsw(rscratch1, len, bulk_width * block_size); + __ br(__ HS, CTR_large_block); + __ BIND(large_block_return); + __ cbzw(len, DONE); + + // Setup the counter + __ movi(v4, __ T4S, 0); + __ movi(v5, __ T4S, 1); + __ ins(v4, __ S, v5, 3, 3); // v4 contains { 0, 0, 0, 1 } + + __ ld1(v0, __ T16B, counter); // Load the counter into v0 + __ rev32(v16, __ T16B, v0); + __ addv(v16, __ T4S, v16, v4); + __ rev32(v16, __ T16B, v16); + __ st1(v16, __ T16B, counter); // Save the incremented counter back + + { + // We have fewer than bulk_width blocks of data left. Encrypt + // them one by one until there is less than a full block + // remaining, being careful to save both the encrypted counter + // and the counter. + + Label inner_loop; + __ bind(inner_loop); + // Counter to encrypt is in v0 + __ aesecb_encrypt(noreg, noreg, keylen); + __ st1(v0, __ T16B, saved_encrypted_ctr); + + // Do we have a remaining full block? + + __ mov(used, 0); + __ cmp(len, block_size); + __ br(__ LO, NEXT); + + // Yes, we have a full block + __ ldrq(v1, Address(in, offset)); + __ eor(v1, __ T16B, v1, v0); + __ strq(v1, Address(out, offset)); + __ mov(used, block_size); + __ add(offset, offset, block_size); + + __ subw(len, len, block_size); + __ cbzw(len, DONE); + + // Increment the counter, store it back + __ orr(v0, __ T16B, v16, v16); + __ rev32(v16, __ T16B, v16); + __ addv(v16, __ T4S, v16, v4); + __ rev32(v16, __ T16B, v16); + __ st1(v16, __ T16B, counter); // Save the incremented counter back + + __ b(inner_loop); + } + + __ BIND(NEXT); + + // Encrypt a single byte, and loop. + // We expect this to be a rare event. + __ ldrb(rscratch1, Address(in, offset)); + __ ldrb(rscratch2, Address(saved_encrypted_ctr, used)); + __ eor(rscratch1, rscratch1, rscratch2); + __ strb(rscratch1, Address(out, offset)); + __ add(offset, offset, 1); + __ add(used, used, 1); + __ subw(len, len,1); + __ cbnzw(len, L_CTR_loop); + } + + __ bind(DONE); + __ strw(used, Address(used_ptr)); + __ mov(r0, saved_len); + + __ leave(); // required for proper stackwalking of RuntimeStub frame + __ ret(lr); + + // Bulk encryption + + __ BIND (CTR_large_block); + assert(bulk_width == 4 || bulk_width == 8, "must be"); + + if (bulk_width == 8) { + __ sub(sp, sp, 4 * 16); + __ st1(v12, v13, v14, v15, __ T16B, Address(sp)); + } + __ sub(sp, sp, 4 * 16); + __ st1(v8, v9, v10, v11, __ T16B, Address(sp)); + RegSet saved_regs = (RegSet::of(in, out, offset) + + RegSet::of(saved_encrypted_ctr, used_ptr, len)); + __ push(saved_regs, sp); + __ andr(len, len, -16 * bulk_width); // 8/4 encryptions, 16 bytes per encryption + __ add(in, in, offset); + __ add(out, out, offset); + + // Keys should already be loaded into the correct registers + + __ ld1(v0, __ T16B, counter); // v0 contains the first counter + __ rev32(v16, __ T16B, v0); // v16 contains byte-reversed counter + + // AES/CTR loop + { + Label L_CTR_loop; + __ BIND(L_CTR_loop); + + // Setup the counters + __ movi(v8, __ T4S, 0); + __ movi(v9, __ T4S, 1); + __ ins(v8, __ S, v9, 3, 3); // v8 contains { 0, 0, 0, 1 } + + for (FloatRegister f = v0; f < v0 + bulk_width; f++) { + __ rev32(f, __ T16B, v16); + __ addv(v16, __ T4S, v16, v8); + } + + __ ld1(v8, v9, v10, v11, __ T16B, __ post(in, 4 * 16)); + + // Encrypt the counters + __ aesecb_encrypt(noreg, noreg, keylen, v0, bulk_width); + + if (bulk_width == 8) { + __ ld1(v12, v13, v14, v15, __ T16B, __ post(in, 4 * 16)); + } + + // XOR the encrypted counters with the inputs + for (int i = 0; i < bulk_width; i++) { + __ eor(v0 + i, __ T16B, v0 + i, v8 + i); + } + + // Write the encrypted data + __ st1(v0, v1, v2, v3, __ T16B, __ post(out, 4 * 16)); + if (bulk_width == 8) { + __ st1(v4, v5, v6, v7, __ T16B, __ post(out, 4 * 16)); + } + + __ subw(len, len, 16 * bulk_width); + __ cbnzw(len, L_CTR_loop); + } + + // Save the counter back where it goes + __ rev32(v16, __ T16B, v16); + __ st1(v16, __ T16B, counter); + + __ pop(saved_regs, sp); + + __ ld1(v8, v9, v10, v11, __ T16B, __ post(sp, 4 * 16)); + if (bulk_width == 8) { + __ ld1(v12, v13, v14, v15, __ T16B, __ post(sp, 4 * 16)); + } + + __ andr(rscratch1, len, -16 * bulk_width); + __ sub(len, len, rscratch1); + __ add(offset, offset, rscratch1); + __ mov(used, 16); + __ strw(used, Address(used_ptr)); + __ b(large_block_return); + + return start; + } + // Arguments: // // Inputs: @@ -4685,6 +4947,55 @@ return start; } + address generate_ghash_processBlocks_wide() { + address small = generate_ghash_processBlocks(); + + StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks_wide"); + __ align(wordSize * 2); + address p = __ pc(); + __ emit_int64(0x87); // The low-order bits of the field + // polynomial (i.e. p = z^7+z^2+z+1) + // repeated in the low and high parts of a + // 128-bit vector + __ emit_int64(0x87); + + __ align(CodeEntryAlignment); + address start = __ pc(); + + Register state = c_rarg0; + Register subkeyH = c_rarg1; + Register data = c_rarg2; + Register blocks = c_rarg3; + + const int unroll = 4; + + __ cmp(blocks, (unsigned char)(unroll * 2)); + __ br(__ LT, small); + + if (unroll > 1) { + // Save state before entering routine + __ sub(sp, sp, 4 * 16); + __ st1(v12, v13, v14, v15, __ T16B, Address(sp)); + __ sub(sp, sp, 4 * 16); + __ st1(v8, v9, v10, v11, __ T16B, Address(sp)); + } + + __ ghash_processBlocks_wide(p, state, subkeyH, data, blocks, unroll); + + if (unroll > 1) { + // And restore state + __ ld1(v8, v9, v10, v11, __ T16B, __ post(sp, 4 * 16)); + __ ld1(v12, v13, v14, v15, __ T16B, __ post(sp, 4 * 16)); + } + + __ cmp(blocks, 0u); + __ br(__ GT, small); + + __ ret(lr); + + return start; + } + #ifdef LINUX // ARMv8.1 LSE versions of the atomic stubs used by Atomic::PlatformXX. @@ -5115,42 +5426,42 @@ // Register allocation - Register reg = c_rarg0; - Pa_base = reg; // Argument registers + RegSetIterator regs = (RegSet::range(r0, r26) - r18_tls).begin(); + Pa_base = *regs; // Argument registers if (squaring) Pb_base = Pa_base; else - Pb_base = ++reg; - Pn_base = ++reg; - Rlen= ++reg; - inv = ++reg; - Pm_base = ++reg; + Pb_base = *++regs; + Pn_base = *++regs; + Rlen= *++regs; + inv = *++regs; + Pm_base = *++regs; // Working registers: - Ra = ++reg; // The current digit of a, b, n, and m. - Rb = ++reg; - Rm = ++reg; - Rn = ++reg; + Ra = *++regs; // The current digit of a, b, n, and m. + Rb = *++regs; + Rm = *++regs; + Rn = *++regs; - Pa = ++reg; // Pointers to the current/next digit of a, b, n, and m. - Pb = ++reg; - Pm = ++reg; - Pn = ++reg; + Pa = *++regs; // Pointers to the current/next digit of a, b, n, and m. + Pb = *++regs; + Pm = *++regs; + Pn = *++regs; - t0 = ++reg; // Three registers which form a - t1 = ++reg; // triple-precision accumuator. - t2 = ++reg; + t0 = *++regs; // Three registers which form a + t1 = *++regs; // triple-precision accumuator. + t2 = *++regs; - Ri = ++reg; // Inner and outer loop indexes. - Rj = ++reg; + Ri = *++regs; // Inner and outer loop indexes. + Rj = *++regs; - Rhi_ab = ++reg; // Product registers: low and high parts - Rlo_ab = ++reg; // of a*b and m*n. - Rhi_mn = ++reg; - Rlo_mn = ++reg; + Rhi_ab = *++regs; // Product registers: low and high parts + Rlo_ab = *++regs; // of a*b and m*n. + Rhi_mn = *++regs; + Rlo_mn = *++regs; // r19 and up are callee-saved. - _toSave = RegSet::range(r19, reg) + Pm_base; + _toSave = RegSet::range(r19, *regs) + Pm_base; } private: @@ -6047,7 +6358,11 @@ // generate GHASH intrinsics code if (UseGHASHIntrinsics) { - StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + if (UseAESCTRIntrinsics) { + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks_wide(); + } else { + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } } if (UseBASE64Intrinsics) { @@ -6061,6 +6376,10 @@ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt(); } + if (UseAESCTRIntrinsics) { + StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt(); + } + if (UseSHA1Intrinsics) { StubRoutines::_sha1_implCompress = generate_sha1_implCompress(false, "sha1_implCompress"); StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB");
diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp index 4e5930b..fe350d8 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp
@@ -36,7 +36,7 @@ enum platform_dependent_constants { code_size1 = 19000, // simply increase if too small (assembler will crash if too small) - code_size2 = 28000 // simply increase if too small (assembler will crash if too small) + code_size2 = 32000 // simply increase if too small (assembler will crash if too small) }; class aarch64 {
diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index 6b12b9c..21ba661 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
@@ -1125,7 +1125,7 @@ // an interpreter frame with greater than a page of locals, so each page // needs to be checked. Only true for non-native. if (UseStackBanging) { - const int n_shadow_pages = JavaThread::stack_shadow_zone_size() / os::vm_page_size(); + const int n_shadow_pages = checked_cast<int>(JavaThread::stack_shadow_zone_size() / os::vm_page_size()); const int start_page = native_call ? n_shadow_pages : 1; const int page_size = os::vm_page_size(); for (int pages = start_page; pages <= n_shadow_pages ; pages++) { @@ -1458,11 +1458,12 @@ __ cmp(rscratch1, JavaThread::stack_guard_yellow_reserved_disabled); __ br(Assembler::NE, no_reguard); - __ pusha(); // XXX only save smashed registers + __ push_call_clobbered_registers(); __ mov(c_rarg0, rthread); __ mov(rscratch2, CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); __ blr(rscratch2); - __ popa(); // XXX only restore smashed registers + __ pop_call_clobbered_registers(); + __ bind(no_reguard); }
diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp index dfd2040..6fd216b 100644 --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
@@ -94,10 +94,6 @@ return iaddress(r); } -static inline Address at_rsp() { - return Address(esp, 0); -} - // At top of Java expression stack which may be different than esp(). It // isn't for category 1 objects. static inline Address at_tos () { @@ -2323,6 +2319,7 @@ switch (code) { case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break; case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break; + default: break; } assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); @@ -2947,6 +2944,7 @@ case Bytecodes::_fast_dputfield: __ pop_d(); break; case Bytecodes::_fast_fputfield: __ pop_f(); break; case Bytecodes::_fast_lputfield: __ pop_l(r0); break; + default: break; } __ bind(L2); }
diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 32dd246..0136f24 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
@@ -24,100 +24,35 @@ */ #include "precompiled.hpp" -#include "asm/macroAssembler.hpp" -#include "asm/macroAssembler.inline.hpp" -#include "memory/resourceArea.hpp" +#include "runtime/arguments.hpp" +#include "runtime/globals_extension.hpp" #include "runtime/java.hpp" -#include "runtime/stubCodeGenerator.hpp" +#include "runtime/os.hpp" #include "runtime/vm_version.hpp" +#include "utilities/formatBuffer.hpp" #include "utilities/macros.hpp" #include OS_HEADER_INLINE(os) -#include <sys/auxv.h> -#include <asm/hwcap.h> - -#ifndef HWCAP_AES -#define HWCAP_AES (1<<3) -#endif - -#ifndef HWCAP_PMULL -#define HWCAP_PMULL (1<<4) -#endif - -#ifndef HWCAP_SHA1 -#define HWCAP_SHA1 (1<<5) -#endif - -#ifndef HWCAP_SHA2 -#define HWCAP_SHA2 (1<<6) -#endif - -#ifndef HWCAP_CRC32 -#define HWCAP_CRC32 (1<<7) -#endif - -#ifndef HWCAP_ATOMICS -#define HWCAP_ATOMICS (1<<8) -#endif - int VM_Version::_cpu; int VM_Version::_model; int VM_Version::_model2; int VM_Version::_variant; int VM_Version::_revision; int VM_Version::_stepping; -VM_Version::PsrInfo VM_Version::_psr_info = { 0, }; -static BufferBlob* stub_blob; -static const int stub_size = 550; +int VM_Version::_zva_length; +int VM_Version::_dcache_line_size; +int VM_Version::_icache_line_size; -extern "C" { - typedef void (*getPsrInfo_stub_t)(void*); -} -static getPsrInfo_stub_t getPsrInfo_stub = NULL; - - -class VM_Version_StubGenerator: public StubCodeGenerator { - public: - - VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} - - address generate_getPsrInfo() { - StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub"); -# define __ _masm-> - address start = __ pc(); - - // void getPsrInfo(VM_Version::PsrInfo* psr_info); - - address entry = __ pc(); - - __ enter(); - - __ get_dczid_el0(rscratch1); - __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::dczid_el0_offset()))); - - __ get_ctr_el0(rscratch1); - __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::ctr_el0_offset()))); - - __ leave(); - __ ret(lr); - -# undef __ - - return start; - } -}; - - -void VM_Version::get_processor_features() { +void VM_Version::initialize() { _supports_cx8 = true; _supports_atomic_getset4 = true; _supports_atomic_getadd4 = true; _supports_atomic_getset8 = true; _supports_atomic_getadd8 = true; - getPsrInfo_stub(&_psr_info); + get_os_cpu_info(); int dcache_line = VM_Version::dcache_line_size(); @@ -163,34 +98,6 @@ ContendedPaddingWidth = dcache_line; } - uint64_t auxv = getauxval(AT_HWCAP); - - char buf[512]; - - _features = auxv; - - int cpu_lines = 0; - if (FILE *f = fopen("/proc/cpuinfo", "r")) { - char buf[128], *p; - while (fgets(buf, sizeof (buf), f) != NULL) { - if ((p = strchr(buf, ':')) != NULL) { - long v = strtol(p+1, NULL, 0); - if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) { - _cpu = v; - cpu_lines++; - } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) { - _variant = v; - } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) { - if (_model != v) _model2 = _model; - _model = v; - } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) { - _revision = v; - } - } - } - fclose(f); - } - // Enable vendor specific features // ThunderX @@ -256,27 +163,28 @@ } if (_cpu == CPU_ARM && (_model == 0xd07 || _model2 == 0xd07)) _features |= CPU_STXR_PREFETCH; - // If an olde style /proc/cpuinfo (cpu_lines == 1) then if _model is an A57 (0xd07) + // If an olde style /proc/cpuinfo (cores == 1) then if _model is an A57 (0xd07) // we assume the worst and assume we could be on a big little system and have // undisclosed A53 cores which we could be swapped to at any stage - if (_cpu == CPU_ARM && cpu_lines == 1 && _model == 0xd07) _features |= CPU_A53MAC; + if (_cpu == CPU_ARM && os::processor_count() == 1 && _model == 0xd07) _features |= CPU_A53MAC; + char buf[512]; sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision); if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2); - if (auxv & HWCAP_ASIMD) strcat(buf, ", simd"); - if (auxv & HWCAP_CRC32) strcat(buf, ", crc"); - if (auxv & HWCAP_AES) strcat(buf, ", aes"); - if (auxv & HWCAP_SHA1) strcat(buf, ", sha1"); - if (auxv & HWCAP_SHA2) strcat(buf, ", sha256"); - if (auxv & HWCAP_ATOMICS) strcat(buf, ", lse"); + if (_features & CPU_ASIMD) strcat(buf, ", simd"); + if (_features & CPU_CRC32) strcat(buf, ", crc"); + if (_features & CPU_AES) strcat(buf, ", aes"); + if (_features & CPU_SHA1) strcat(buf, ", sha1"); + if (_features & CPU_SHA2) strcat(buf, ", sha256"); + if (_features & CPU_LSE) strcat(buf, ", lse"); _features_string = os::strdup(buf); if (FLAG_IS_DEFAULT(UseCRC32)) { - UseCRC32 = (auxv & HWCAP_CRC32) != 0; + UseCRC32 = (_features & CPU_CRC32) != 0; } - if (UseCRC32 && (auxv & HWCAP_CRC32) == 0) { + if (UseCRC32 && (_features & CPU_CRC32) == 0) { warning("UseCRC32 specified, but not supported on this CPU"); FLAG_SET_DEFAULT(UseCRC32, false); } @@ -290,7 +198,7 @@ FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); } - if (auxv & HWCAP_ATOMICS) { + if (_features & CPU_LSE) { if (FLAG_IS_DEFAULT(UseLSE)) FLAG_SET_DEFAULT(UseLSE, true); } else { @@ -300,7 +208,7 @@ } } - if (auxv & HWCAP_AES) { + if (_features & CPU_AES) { UseAES = UseAES || FLAG_IS_DEFAULT(UseAES); UseAESIntrinsics = UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics)); @@ -308,6 +216,9 @@ warning("UseAESIntrinsics enabled, but UseAES not, enabling"); UseAES = true; } + if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics)) { + FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); + } } else { if (UseAES) { warning("AES instructions are not available on this CPU"); @@ -317,18 +228,17 @@ warning("AES intrinsics are not available on this CPU"); FLAG_SET_DEFAULT(UseAESIntrinsics, false); } - } - - if (UseAESCTRIntrinsics) { - warning("AES/CTR intrinsics are not available on this CPU"); - FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); + if (UseAESCTRIntrinsics) { + warning("AES/CTR intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); + } } if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) { UseCRC32Intrinsics = true; } - if (auxv & HWCAP_CRC32) { + if (_features & CPU_CRC32) { if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) { FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true); } @@ -341,7 +251,7 @@ FLAG_SET_DEFAULT(UseFMA, true); } - if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) { + if (_features & (CPU_SHA1 | CPU_SHA2)) { if (FLAG_IS_DEFAULT(UseSHA)) { FLAG_SET_DEFAULT(UseSHA, true); } @@ -350,7 +260,7 @@ FLAG_SET_DEFAULT(UseSHA, false); } - if (UseSHA && (auxv & HWCAP_SHA1)) { + if (UseSHA && (_features & CPU_SHA1)) { if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) { FLAG_SET_DEFAULT(UseSHA1Intrinsics, true); } @@ -359,7 +269,7 @@ FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); } - if (UseSHA && (auxv & HWCAP_SHA2)) { + if (UseSHA && (_features & CPU_SHA2)) { if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) { FLAG_SET_DEFAULT(UseSHA256Intrinsics, true); } @@ -377,7 +287,7 @@ FLAG_SET_DEFAULT(UseSHA, false); } - if (auxv & HWCAP_PMULL) { + if (_features & CPU_PMULL) { if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { FLAG_SET_DEFAULT(UseGHASHIntrinsics, true); } @@ -439,22 +349,6 @@ OptoScheduling = true; } #endif -} - -void VM_Version::initialize() { - ResourceMark rm; - - stub_blob = BufferBlob::create("getPsrInfo_stub", stub_size); - if (stub_blob == NULL) { - vm_exit_during_initialization("Unable to allocate getPsrInfo_stub"); - } - - CodeBuffer c(stub_blob); - VM_Version_StubGenerator g(&c); - getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t, - g.generate_getPsrInfo()); - - get_processor_features(); UNSUPPORTED_OPTION(CriticalJNINatives); }
diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp index dcb6342..8c9676a 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
@@ -41,12 +41,12 @@ static int _revision; static int _stepping; - struct PsrInfo { - uint32_t dczid_el0; - uint32_t ctr_el0; - }; - static PsrInfo _psr_info; - static void get_processor_features(); + static int _zva_length; + static int _dcache_line_size; + static int _icache_line_size; + + // Read additional info using OS-specific interfaces + static void get_os_cpu_info(); public: // Initialization @@ -67,6 +67,9 @@ return false; } + // Arm can assign codes that are not published in the manual. + // Apple's code is defined in + // https://github.com/apple/darwin-xnu/blob/33eb983/osfmk/arm/cpuid.h#L62 enum Family { CPU_ARM = 'A', CPU_BROADCOM = 'B', @@ -79,6 +82,7 @@ CPU_QUALCOM = 'Q', CPU_MARVELL = 'V', CPU_INTEL = 'i', + CPU_APPLE = 'a', }; enum Feature_Flag { @@ -91,6 +95,7 @@ CPU_SHA2 = (1<<6), CPU_CRC32 = (1<<7), CPU_LSE = (1<<8), + // flags above must follow Linux HWCAP CPU_STXR_PREFETCH= (1 << 29), CPU_A53MAC = (1 << 30), CPU_DMB_ATOMICS = (1 << 31), @@ -101,24 +106,20 @@ static int cpu_model2() { return _model2; } static int cpu_variant() { return _variant; } static int cpu_revision() { return _revision; } - static ByteSize dczid_el0_offset() { return byte_offset_of(PsrInfo, dczid_el0); } - static ByteSize ctr_el0_offset() { return byte_offset_of(PsrInfo, ctr_el0); } - static bool is_zva_enabled() { - // Check the DZP bit (bit 4) of dczid_el0 is zero - // and block size (bit 0~3) is not zero. - return ((_psr_info.dczid_el0 & 0x10) == 0 && - (_psr_info.dczid_el0 & 0xf) != 0); - } + + static bool is_zva_enabled() { return 0 <= _zva_length; } static int zva_length() { assert(is_zva_enabled(), "ZVA not available"); - return 4 << (_psr_info.dczid_el0 & 0xf); + return _zva_length; } - static int icache_line_size() { - return (1 << (_psr_info.ctr_el0 & 0x0f)) * 4; - } - static int dcache_line_size() { - return (1 << ((_psr_info.ctr_el0 >> 16) & 0x0f)) * 4; - } + + static int icache_line_size() { return _icache_line_size; } + static int dcache_line_size() { return _dcache_line_size; } + +#ifdef __APPLE__ + // Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64) + static bool is_cpu_emulated(); +#endif }; #endif // CPU_AARCH64_VM_VM_VERSION_AARCH64_HPP
diff --git a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp index ebabc37..8db351a 100644 --- a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp
@@ -22,6 +22,7 @@ * */ +#include "precompiled.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "runtime/os.inline.hpp"
diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index fe89bb2..51f2d9c 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad
@@ -5317,7 +5317,7 @@ // Must be safe to execute with invalid address (cannot fault). instruct prefetchAlloc_mp( memoryP mem ) %{ - predicate(os::is_MP()); + predicate(VM_Version::has_multiprocessing_extensions()); match( PrefetchAllocation mem ); ins_cost(MEMORY_REF_COST); size(4); @@ -5334,7 +5334,7 @@ %} instruct prefetchAlloc_sp( memoryP mem ) %{ - predicate(!os::is_MP()); + predicate(!VM_Version::has_multiprocessing_extensions()); match( PrefetchAllocation mem ); ins_cost(MEMORY_REF_COST); size(4);
diff --git a/src/hotspot/cpu/arm/assembler_arm_32.cpp b/src/hotspot/cpu/arm/assembler_arm_32.cpp index 0166d85..46e74cf 100644 --- a/src/hotspot/cpu/arm/assembler_arm_32.cpp +++ b/src/hotspot/cpu/arm/assembler_arm_32.cpp
@@ -47,7 +47,7 @@ // Convert the raw encoding form into the form expected by the // constructor for Address. Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) { - RelocationHolder rspec; + RelocationHolder rspec = RelocationHolder::none; if (disp_reloc != relocInfo::none) { rspec = Relocation::spec_simple(disp_reloc); }
diff --git a/src/hotspot/cpu/arm/assembler_arm_32.hpp b/src/hotspot/cpu/arm/assembler_arm_32.hpp index afac7b4..6354bd9 100644 --- a/src/hotspot/cpu/arm/assembler_arm_32.hpp +++ b/src/hotspot/cpu/arm/assembler_arm_32.hpp
@@ -434,7 +434,9 @@ } void pldw(Address addr) { - assert(VM_Version::arm_arch() >= 7 && os::is_MP(), "no pldw on this processor"); + assert(!VM_Version::is_initialized() || + (VM_Version::arm_arch() >= 7 && VM_Version::has_multiprocessing_extensions()), + "PLDW is available on ARMv7 with Multiprocessing Extensions only"); emit_int32(0xf510f000 | addr.encoding2()); }
diff --git a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp index 6180516..f0a7229 100644 --- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
@@ -2201,6 +2201,9 @@ } else { assert(right->is_constant(), "must be"); const uint c = (uint)right->as_constant_ptr()->as_jint(); + if (!Assembler::is_arith_imm_in_range(c)) { + BAILOUT("illegal arithmetic operand"); + } switch (code) { case lir_logic_and: __ and_32(res, lreg, c); break; case lir_logic_or: __ orr_32(res, lreg, c); break; @@ -2396,8 +2399,8 @@ __ teq(xhi, yhi); __ teq(xlo, ylo, eq); } else { - __ subs(xlo, xlo, ylo); - __ sbcs(xhi, xhi, yhi); + __ subs(Rtemp, xlo, ylo); + __ sbcs(Rtemp, xhi, yhi); } } else { ShouldNotReachHere();
diff --git a/src/hotspot/cpu/arm/vm_version_arm.hpp b/src/hotspot/cpu/arm/vm_version_arm.hpp index 3659682..06508e9 100644 --- a/src/hotspot/cpu/arm/vm_version_arm.hpp +++ b/src/hotspot/cpu/arm/vm_version_arm.hpp
@@ -54,6 +54,7 @@ static bool has_simd() { return _has_simd; } static bool has_vfp() { return has_simd(); } static bool simd_math_is_compliant() { return true; } + static bool has_multiprocessing_extensions() { return true; } static bool prefer_moves_over_load_literal() { return true; } @@ -64,6 +65,7 @@ vfp = 0, vfp3_32 = 1, simd = 2, + mp_ext = 3 }; enum Feature_Flag_Set { @@ -73,6 +75,7 @@ vfp_m = 1 << vfp, vfp3_32_m = 1 << vfp3_32, simd_m = 1 << simd, + mp_ext_m = 1 << mp_ext }; // The value stored by "STR PC, [addr]" instruction can be either @@ -115,6 +118,7 @@ static bool has_vfp() { return (_features & vfp_m) != 0; } static bool has_vfp3_32() { return (_features & vfp3_32_m) != 0; } static bool has_simd() { return (_features & simd_m) != 0; } + static bool has_multiprocessing_extensions() { return (_features & mp_ext_m) != 0; } static bool simd_math_is_compliant() { return false; }
diff --git a/src/hotspot/cpu/arm/vm_version_arm_32.cpp b/src/hotspot/cpu/arm/vm_version_arm_32.cpp index 4e58162..14aaddd 100644 --- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp +++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp
@@ -40,6 +40,7 @@ typedef int (*get_cpu_info_t)(); typedef bool (*check_vfp_t)(double *d); typedef bool (*check_simd_t)(); + typedef bool (*check_mp_ext_t)(int *addr); } #define __ _masm-> @@ -95,6 +96,20 @@ return start; }; + + address generate_check_mp_ext() { + StubCodeMark mark(this, "VM_Version", "check_mp_ext"); + address start = __ pc(); + + // PLDW is available with Multiprocessing Extensions only + __ pldw(Address(R0)); + // Return true if instruction caused no signals + __ mov(R0, 1); + // JVM_handle_linux_signal moves PC here if SIGILL happens + __ bx(LR); + + return start; + }; }; #undef __ @@ -103,6 +118,7 @@ extern "C" address check_vfp3_32_fault_instr; extern "C" address check_vfp_fault_instr; extern "C" address check_simd_fault_instr; +extern "C" address check_mp_ext_fault_instr; void VM_Version::early_initialize() { @@ -165,6 +181,13 @@ #endif #endif + address check_mp_ext_pc = g.generate_check_mp_ext(); + check_mp_ext_t check_mp_ext = CAST_TO_FN_PTR(check_mp_ext_t, check_mp_ext_pc); + check_mp_ext_fault_instr = (address)check_mp_ext; + int dummy_local_variable; + if (check_mp_ext(&dummy_local_variable)) { + _features |= mp_ext_m; + } if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { warning("AES intrinsics are not available on this CPU"); @@ -247,11 +270,12 @@ && _supports_atomic_getset8 && _supports_atomic_getadd8, "C2: atomic operations must be supported"); #endif char buf[512]; - jio_snprintf(buf, sizeof(buf), "(ARMv%d)%s%s%s", + jio_snprintf(buf, sizeof(buf), "(ARMv%d)%s%s%s%s", _arm_arch, (has_vfp() ? ", vfp" : ""), (has_vfp3_32() ? ", vfp3-32" : ""), - (has_simd() ? ", simd" : "")); + (has_simd() ? ", simd" : ""), + (has_multiprocessing_extensions() ? ", mp_ext" : "")); // buf is started with ", " or is empty _features_string = os::strdup(buf);
diff --git a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp index 73aa063..214cb59 100644 --- a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp
@@ -55,8 +55,6 @@ if (_info->deoptimize_on_exception()) { address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); - // May be used by optimizations like LoopInvariantCodeMotion or RangeCheckEliminator. - DEBUG_ONLY( __ untested("RangeCheckStub: predicate_failed_trap_id"); ) //__ load_const_optimized(R0, a); __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a)); __ mtctr(R0);
diff --git a/src/hotspot/cpu/ppc/frame_ppc.cpp b/src/hotspot/cpu/ppc/frame_ppc.cpp index 1778c75..c9fc6f2 100644 --- a/src/hotspot/cpu/ppc/frame_ppc.cpp +++ b/src/hotspot/cpu/ppc/frame_ppc.cpp
@@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2017 SAP SE. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,6 @@ #endif // ASSERT bool frame::safe_for_sender(JavaThread *thread) { - bool safe = false; address sp = (address)_sp; address fp = (address)_fp; address unextended_sp = (address)_unextended_sp; @@ -76,29 +75,23 @@ // An fp must be within the stack and above (but not equal) sp. bool fp_safe = (fp <= thread->stack_base()) && (fp > sp); - // An interpreter fp must be within the stack and above (but not equal) sp. - // Moreover, it must be at least the size of the ijava_state structure. - bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) && - ((fp - sp) >= ijava_state_size); + // An interpreter fp must be fp_safe. + // Moreover, it must be at a distance at least the size of the ijava_state structure. + bool fp_interp_safe = fp_safe && ((fp - sp) >= ijava_state_size); // We know sp/unextended_sp are safe, only fp is questionable here // If the current frame is known to the code cache then we can attempt to - // to construct the sender and do some validation of it. This goes a long way + // construct the sender and do some validation of it. This goes a long way // toward eliminating issues when we get in frame construction code if (_cb != NULL ){ - // Entry frame checks - if (is_entry_frame()) { - // An entry frame must have a valid fp. - return fp_safe && is_entry_frame_valid(thread); - } - // Now check if the frame is complete and the test is - // reliable. Unfortunately we can only check frame completeness for - // runtime stubs and nmethods. Other generic buffer blobs are more - // problematic so we just assume they are OK. Adapter blobs never have a - // complete frame and are never OK + // First check if the frame is complete and the test is reliable. + // Unfortunately we can only check frame completeness for runtime stubs + // and nmethods. Other generic buffer blobs are more problematic + // so we just assume they are OK. + // Adapter blobs never have a complete frame and are never OK if (!_cb->is_frame_complete_at(_pc)) { if (_cb->is_compiled() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { return false; @@ -110,10 +103,23 @@ return false; } + // Entry frame checks + if (is_entry_frame()) { + // An entry frame must have a valid fp. + return fp_safe && is_entry_frame_valid(thread); + } + if (is_interpreted_frame() && !fp_interp_safe) { return false; } + // At this point, there still is a chance that fp_safe is false. + // In particular, (fp == NULL) might be true. So let's check and + // bail out before we actually dereference from fp. + if (!fp_safe) { + return false; + } + abi_minframe* sender_abi = (abi_minframe*) fp; intptr_t* sender_sp = (intptr_t*) fp; address sender_pc = (address) sender_abi->lr;; @@ -274,8 +280,60 @@ } bool frame::is_interpreted_frame_valid(JavaThread* thread) const { - // Is there anything to do? assert(is_interpreted_frame(), "Not an interpreted frame"); + // These are reasonable sanity checks + if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { + return false; + } + if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { + return false; + } + int min_frame_slots = (abi_minframe_size + ijava_state_size) / sizeof(intptr_t); + if (fp() - min_frame_slots < sp()) { + return false; + } + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (fp() <= sp()) { // this attempts to deal with unsigned comparison above + return false; + } + + // do some validation of frame elements + + // first the method + + Method* m = *interpreter_frame_method_addr(); + + // validate the method we'd find in this potential sender + if (!Method::is_valid_method(m)) return false; + + // stack frames shouldn't be much larger than max_stack elements + // this test requires the use of unextended_sp which is the sp as seen by + // the current frame, and not sp which is the "raw" pc which could point + // further because of local variables of the callee method inserted after + // method arguments + if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { + return false; + } + + // validate bci/bcx + + address bcp = interpreter_frame_bcp(); + if (m->validate_bci_from_bcp(bcp) < 0) { + return false; + } + + // validate constantPoolCache* + ConstantPoolCache* cp = *interpreter_frame_cache_addr(); + if (MetaspaceObj::is_valid(cp) == false) return false; + + // validate locals + + address locals = (address) *interpreter_frame_locals_addr(); + + if (locals > thread->stack_base() || locals < (address) fp()) return false; + + // We'd have to be pretty unlucky to be mislead at this point return true; }
diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index fb58373..dc54e4f 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad
@@ -4085,7 +4085,7 @@ // The `sig' array is to be updated. sig[j] represents the location // of the j-th argument, either a register or a stack slot. - // Comment taken from i486.ad: + // Comment taken from x86_32.ad: // Body of function which returns an integer array locating // arguments either in registers or in stack slots. Passed an array // of ideal registers called "sig" and a "length" count. Stack-slot @@ -4097,7 +4097,7 @@ SharedRuntime::java_calling_convention(sig_bt, regs, length, false); %} - // Comment taken from i486.ad: + // Comment taken from x86_32.ad: // Body of function which returns an integer array locating // arguments either in registers or in stack slots. Passed an array // of ideal registers called "sig" and a "length" count. Stack-slot
diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp index 9735171..033e283 100644 --- a/src/hotspot/cpu/s390/frame_s390.cpp +++ b/src/hotspot/cpu/s390/frame_s390.cpp
@@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019, SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 SAP SE. 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 @@ -52,7 +52,6 @@ // Profiling/safepoint support bool frame::safe_for_sender(JavaThread *thread) { - bool safe = false; address sp = (address)_sp; address fp = (address)_fp; address unextended_sp = (address)_unextended_sp; @@ -80,29 +79,23 @@ // An fp must be within the stack and above (but not equal) sp. bool fp_safe = (fp <= thread->stack_base()) && (fp > sp); - // An interpreter fp must be within the stack and above (but not equal) sp. - // Moreover, it must be at least the size of the z_ijava_state structure. - bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) && - ((fp - sp) >= z_ijava_state_size); + // An interpreter fp must be fp_safe. + // Moreover, it must be at a distance at least the size of the z_ijava_state structure. + bool fp_interp_safe = fp_safe && ((fp - sp) >= z_ijava_state_size); // We know sp/unextended_sp are safe, only fp is questionable here // If the current frame is known to the code cache then we can attempt to - // to construct the sender and do some validation of it. This goes a long way + // construct the sender and do some validation of it. This goes a long way // toward eliminating issues when we get in frame construction code if (_cb != NULL ) { - // Entry frame checks - if (is_entry_frame()) { - // An entry frame must have a valid fp. - return fp_safe && is_entry_frame_valid(thread); - } - // Now check if the frame is complete and the test is - // reliable. Unfortunately we can only check frame completeness for - // runtime stubs. Other generic buffer blobs are more - // problematic so we just assume they are OK. Adapter blobs never have a - // complete frame and are never OK. nmethods should be OK on s390. + // First check if the frame is complete and the test is reliable. + // Unfortunately we can only check frame completeness for runtime stubs. + // Other generic buffer blobs are more problematic so we just assume they are OK. + // Adapter blobs never have a complete frame and are never OK. + // nmethods should be OK on s390. if (!_cb->is_frame_complete_at(_pc)) { if (_cb->is_adapter_blob() || _cb->is_runtime_stub()) { return false; @@ -114,13 +107,26 @@ return false; } + // Entry frame checks + if (is_entry_frame()) { + // An entry frame must have a valid fp. + return fp_safe && is_entry_frame_valid(thread); + } + if (is_interpreted_frame() && !fp_interp_safe) { return false; } - z_abi_160* sender_abi = (z_abi_160*) fp; - intptr_t* sender_sp = (intptr_t*) sender_abi->callers_sp; - address sender_pc = (address) sender_abi->return_pc; + // At this point, there still is a chance that fp_safe is false. + // In particular, (fp == NULL) might be true. So let's check and + // bail out before we actually dereference from fp. + if (!fp_safe) { + return false; + } + + z_abi_16* sender_abi = (z_abi_16*) fp; + intptr_t* sender_sp = (intptr_t*) fp; + address sender_pc = (address) sender_abi->return_pc; // We must always be able to find a recognizable pc. CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc); @@ -143,7 +149,7 @@ // sender_fp must be within the stack and above (but not // equal) current frame's fp. if (sender_fp > thread->stack_base() || sender_fp <= fp) { - return false; + return false; } // If the potential sender is the interpreter then we can do some more checking. @@ -289,8 +295,58 @@ } bool frame::is_interpreted_frame_valid(JavaThread* thread) const { - // Is there anything to do? assert(is_interpreted_frame(), "Not an interpreted frame"); + // These are reasonable sanity checks + if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { + return false; + } + if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { + return false; + } + int min_frame_slots = (z_abi_16_size + z_ijava_state_size) / sizeof(intptr_t); + if (fp() - min_frame_slots < sp()) { + return false; + } + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (fp() <= sp()) { // this attempts to deal with unsigned comparison above + return false; + } + + // do some validation of frame elements + + // first the method + // Need to use "unchecked" versions to avoid "z_istate_magic_number" assertion. + Method* m = (Method*)(ijava_state_unchecked()->method); + + // validate the method we'd find in this potential sender + if (!Method::is_valid_method(m)) return false; + + // stack frames shouldn't be much larger than max_stack elements + // this test requires the use of unextended_sp which is the sp as seen by + // the current frame, and not sp which is the "raw" pc which could point + // further because of local variables of the callee method inserted after + // method arguments + if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { + return false; + } + + // validate bci/bcx + address bcp = (address)(ijava_state_unchecked()->bcp); + if (m->validate_bci_from_bcp(bcp) < 0) { + return false; + } + + // validate constantPoolCache* + ConstantPoolCache* cp = (ConstantPoolCache*)(ijava_state_unchecked()->cpoolCache); + if (MetaspaceObj::is_valid(cp) == false) return false; + + // validate locals + address locals = (address)(ijava_state_unchecked()->locals); + + if (locals > thread->stack_base() || locals < (address) fp()) return false; + + // We'd have to be pretty unlucky to be mislead at this point return true; }
diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 373675c..22201db 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp
@@ -186,7 +186,7 @@ // Address. An index of 4 (rsp) corresponds to having no index, so convert // that to noreg for the Address constructor. Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) { - RelocationHolder rspec; + RelocationHolder rspec = RelocationHolder::none; if (disp_reloc != relocInfo::none) { rspec = Relocation::spec_simple(disp_reloc); }
diff --git a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp index 231e5a1..905708a 100644 --- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp
@@ -188,8 +188,32 @@ LIR_Address* addr; if (index_opr->is_constant()) { int elem_size = type2aelembytes(type); - addr = new LIR_Address(array_opr, - offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); +#ifdef _LP64 + jint index = index_opr->as_jint(); + jlong disp = offset_in_bytes + (jlong)(index) * elem_size; + if (disp > max_jint) { + // Displacement overflow. Cannot directly use instruction with 32-bit displacement for 64-bit addresses. + // Convert array index to long to do array offset computation with 64-bit values. + index_opr = new_register(T_LONG); + __ move(LIR_OprFact::longConst(index), index_opr); + addr = new LIR_Address(array_opr, index_opr, LIR_Address::scale(type), offset_in_bytes, type); + } else { + addr = new LIR_Address(array_opr, (intx)disp, type); + } +#else + // A displacement overflow can also occur for x86 but that is not a problem due to the 32-bit address range! + // Let's assume an array 'a' and an access with displacement 'disp'. When disp overflows, then "a + disp" will + // always be negative (i.e. underflows the 32-bit address range): + // Let N = 2^32: a + signed_overflow(disp) = a + disp - N. + // "a + disp" is always smaller than N. If an index was chosen which would point to an address beyond N, then + // range checks would catch that and throw an exception. Thus, a + disp < 0 holds which means that it always + // underflows the 32-bit address range: + // unsigned_underflow(a + signed_overflow(disp)) = unsigned_underflow(a + disp - N) + // = (a + disp - N) + N = a + disp + // This shows that we still end up at the correct address with a displacement overflow due to the 32-bit address + // range limitation. This overflow only needs to be handled if addresses can be larger as on 64-bit platforms. + addr = new LIR_Address(array_opr, offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); +#endif // _LP64 } else { #ifdef _LP64 if (index_opr->type() == T_INT) {
diff --git a/src/hotspot/cpu/x86/c2_globals_x86.hpp b/src/hotspot/cpu/x86/c2_globals_x86.hpp index 73db10f..382d546 100644 --- a/src/hotspot/cpu/x86/c2_globals_x86.hpp +++ b/src/hotspot/cpu/x86/c2_globals_x86.hpp
@@ -46,7 +46,7 @@ define_pd_global(intx, ConditionalMoveLimit, 3); define_pd_global(intx, FreqInlineSize, 325); define_pd_global(intx, MinJumpTableSize, 10); -define_pd_global(intx, LoopPercentProfileLimit, 30); +define_pd_global(intx, LoopPercentProfileLimit, 10); #ifdef AMD64 define_pd_global(intx, INTPRESSURE, 13); define_pd_global(intx, FLOATPRESSURE, 14);
diff --git a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp index c39c4d8..7f5ee8b 100644 --- a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp +++ b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp
@@ -153,14 +153,15 @@ method = getMethodFromHotSpotMethod(hotspot_method()); } #endif + NativeCall* call = NULL; switch (_next_call_type) { case INLINE_INVOKE: - break; + return; case INVOKEVIRTUAL: case INVOKEINTERFACE: { assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), @@ -170,7 +171,7 @@ case INVOKESTATIC: { assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_static_call_stub()); _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); @@ -178,15 +179,18 @@ } case INVOKESPECIAL: { assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); break; } default: - JVMCI_ERROR("invalid _next_call_type value"); - break; + JVMCI_ERROR("invalid _next_call_type value: %d", _next_call_type); + return; + } + if (!call->is_displacement_aligned()) { + JVMCI_ERROR("unaligned displacement for call at offset %d", pc_offset); } }
diff --git a/src/hotspot/cpu/x86/nativeInst_x86.cpp b/src/hotspot/cpu/x86/nativeInst_x86.cpp index 989d870..76ce6ff 100644 --- a/src/hotspot/cpu/x86/nativeInst_x86.cpp +++ b/src/hotspot/cpu/x86/nativeInst_x86.cpp
@@ -241,6 +241,9 @@ } +bool NativeCall::is_displacement_aligned() { + return (uintptr_t) displacement_address() % 4 == 0; +} // Similar to replace_mt_safe, but just changes the destination. The // important thing is that free-running threads are able to execute this @@ -264,16 +267,15 @@ // Both C1 and C2 should now be generating code which aligns the patched address // to be within a single cache line except that C1 does not do the alignment on // uniprocessor systems. - bool is_aligned = ((uintptr_t)displacement_address() + 0) / cache_line_size == - ((uintptr_t)displacement_address() + 3) / cache_line_size; + bool is_aligned = is_displacement_aligned(); guarantee(!os::is_MP() || is_aligned, "destination must be aligned"); if (is_aligned) { // Simple case: The destination lies within a single cache line. set_destination(dest); - } else if ((uintptr_t)instruction_address() / cache_line_size == - ((uintptr_t)instruction_address()+1) / cache_line_size) { + } else if ((uintptr_t)instruction_address() / 4 == + ((uintptr_t)instruction_address()+1) / 4) { // Tricky case: The instruction prefix lies within a single cache line. intptr_t disp = dest - return_address(); #ifdef AMD64
diff --git a/src/hotspot/cpu/x86/nativeInst_x86.hpp b/src/hotspot/cpu/x86/nativeInst_x86.hpp index 69ce9a9..25f4a7e 100644 --- a/src/hotspot/cpu/x86/nativeInst_x86.hpp +++ b/src/hotspot/cpu/x86/nativeInst_x86.hpp
@@ -163,8 +163,6 @@ return_address_offset = 5 }; - enum { cache_line_size = BytesPerWord }; // conservative estimate! - address instruction_address() const { return addr_at(instruction_offset); } address next_instruction_address() const { return addr_at(return_address_offset); } int displacement() const { return (jint) int_at(displacement_offset); } @@ -178,9 +176,11 @@ #endif // AMD64 set_int_at(displacement_offset, dest - return_address()); } + // Returns whether the 4-byte displacement operand is 4-byte aligned. + bool is_displacement_aligned(); void set_destination_mt_safe(address dest); - void verify_alignment() { assert((intptr_t)addr_at(displacement_offset) % BytesPerInt == 0, "must be aligned"); } + void verify_alignment() { assert(is_displacement_aligned(), "displacement of call is not aligned"); } void verify(); void print();
diff --git a/src/hotspot/cpu/x86/register_x86.hpp b/src/hotspot/cpu/x86/register_x86.hpp index f5c4496..8cc85e0 100644 --- a/src/hotspot/cpu/x86/register_x86.hpp +++ b/src/hotspot/cpu/x86/register_x86.hpp
@@ -50,7 +50,7 @@ #else number_of_registers = 16, number_of_byte_registers = 16, - max_slots_per_register = 1 + max_slots_per_register = 2 #endif // AMD64 }; @@ -274,10 +274,7 @@ // There is no requirement that any ordering here matches any ordering c2 gives // it's optoregs. - number_of_registers = RegisterImpl::number_of_registers + -#ifdef AMD64 - RegisterImpl::number_of_registers + // "H" half of a 64bit register -#endif // AMD64 + number_of_registers = RegisterImpl::number_of_registers * RegisterImpl::max_slots_per_register + 2 * FloatRegisterImpl::number_of_registers + XMMRegisterImpl::max_slots_per_register * XMMRegisterImpl::number_of_registers + KRegisterImpl::number_of_registers + // mask registers
diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 5c595bd..baa7cc7 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad
@@ -1297,6 +1297,16 @@ #endif }; +inline uint vector_length(const Node* n) { + const TypeVect* vt = n->bottom_type()->is_vect(); + return vt->length(); +} + +inline uint vector_length_in_bytes(const Node* n) { + const TypeVect* vt = n->bottom_type()->is_vect(); + return vt->length_in_bytes(); +} + %} // end source_hpp source %{ @@ -1481,6 +1491,21 @@ if (UseSSE < 4) ret_value = false; break; + case Op_SqrtF: + if (UseSSE < 1) { + return false; + } + break; + case Op_SqrtD: +#ifdef _LP64 + if (UseSSE < 2) { + return false; + } +#else + // x86_32.ad has a special match rule for SqrtD. + // Together with common x86 rules, this handles all UseSSE cases. +#endif + break; } return ret_value; // Per default match rules are supported. @@ -6034,7 +6059,8 @@ instruct vadd4B_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 4); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AddVB src (LoadVector mem))); format %{ "vpaddb $dst,$src,$mem\t! add packed4B" %} ins_encode %{ @@ -6067,7 +6093,8 @@ instruct vadd8B_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 8); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 8) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AddVB src (LoadVector mem))); format %{ "vpaddb $dst,$src,$mem\t! add packed8B" %} ins_encode %{ @@ -6176,7 +6203,8 @@ %} instruct vadd2S_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AddVS src (LoadVector mem))); format %{ "vpaddw $dst,$src,$mem\t! add packed2S" %} ins_encode %{ @@ -6208,7 +6236,8 @@ %} instruct vadd4S_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 4); + predicate((UseAVX == 0) && (n->as_Vector()->length() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AddVS src (LoadVector mem))); format %{ "vpaddw $dst,$src,$mem\t! add packed4S" %} ins_encode %{ @@ -6317,7 +6346,8 @@ %} instruct vadd2I_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AddVI src (LoadVector mem))); format %{ "vpaddd $dst,$src,$mem\t! add packed2I" %} ins_encode %{ @@ -6503,7 +6533,8 @@ %} instruct vadd2F_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX == 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AddVF src (LoadVector mem))); format %{ "vaddps $dst,$src,$mem\t! add packed2F" %} ins_encode %{ @@ -6691,7 +6722,8 @@ %} instruct vsub4B_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 4); + predicate((UseAVX == 0) && (n->as_Vector()->length() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (SubVB src (LoadVector mem))); format %{ "vpsubb $dst,$src,$mem\t! sub packed4B" %} ins_encode %{ @@ -6723,7 +6755,8 @@ %} instruct vsub8B_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 8); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 8) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (SubVB src (LoadVector mem))); format %{ "vpsubb $dst,$src,$mem\t! sub packed8B" %} ins_encode %{ @@ -6832,7 +6865,8 @@ %} instruct vsub2S_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX == 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (SubVS src (LoadVector mem))); format %{ "vpsubw $dst,$src,$mem\t! sub packed2S" %} ins_encode %{ @@ -6864,7 +6898,8 @@ %} instruct vsub4S_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 4); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (SubVS src (LoadVector mem))); format %{ "vpsubw $dst,$src,$mem\t! sub packed4S" %} ins_encode %{ @@ -6973,7 +7008,8 @@ %} instruct vsub2I_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (SubVI src (LoadVector mem))); format %{ "vpsubd $dst,$src,$mem\t! sub packed2I" %} ins_encode %{ @@ -7159,7 +7195,8 @@ %} instruct vsub2F_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX == 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (SubVF src (LoadVector mem))); format %{ "vsubps $dst,$src,$mem\t! sub packed2F" %} ins_encode %{ @@ -7527,7 +7564,8 @@ %} instruct vmul2S_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (MulVS src (LoadVector mem))); format %{ "vpmullw $dst,$src,$mem\t! mul packed2S" %} ins_encode %{ @@ -7559,7 +7597,8 @@ %} instruct vmul4S_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 4); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (MulVS src (LoadVector mem))); format %{ "vpmullw $dst,$src,$mem\t! mul packed4S" %} ins_encode %{ @@ -7668,7 +7707,8 @@ %} instruct vmul2I_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (MulVI src (LoadVector mem))); format %{ "vpmulld $dst,$src,$mem\t! mul packed2I" %} ins_encode %{ @@ -7843,7 +7883,8 @@ %} instruct vmul2F_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (MulVF src (LoadVector mem))); format %{ "vmulps $dst,$src,$mem\t! mul packed2F" %} ins_encode %{ @@ -8063,7 +8104,8 @@ %} instruct vdiv2F_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (DivVF src (LoadVector mem))); format %{ "vdivps $dst,$src,$mem\t! div packed2F" %} ins_encode %{ @@ -8307,7 +8349,8 @@ %} instruct vsqrt2F_mem(vecD dst, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length() == 2); + predicate((UseAVX > 0) && (n->as_Vector()->length() == 2) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (SqrtVF (LoadVector mem))); format %{ "vsqrtps $dst,$mem\t! sqrt packed2F" %} ins_encode %{ @@ -8892,7 +8935,8 @@ %} instruct vand4B_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 4); + predicate((UseAVX > 0) && (n->as_Vector()->length_in_bytes() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AndV src (LoadVector mem))); format %{ "vpand $dst,$src,$mem\t! and vectors (4 bytes)" %} ins_encode %{ @@ -8924,7 +8968,8 @@ %} instruct vand8B_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 8); + predicate((UseAVX > 0) && (n->as_Vector()->length_in_bytes() == 8) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (AndV src (LoadVector mem))); format %{ "vpand $dst,$src,$mem\t! and vectors (8 bytes)" %} ins_encode %{ @@ -9034,7 +9079,8 @@ %} instruct vor4B_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 4); + predicate((UseAVX > 0) && (n->as_Vector()->length_in_bytes() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (OrV src (LoadVector mem))); format %{ "vpor $dst,$src,$mem\t! or vectors (4 bytes)" %} ins_encode %{ @@ -9066,7 +9112,8 @@ %} instruct vor8B_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 4); + predicate((UseAVX > 0) && (n->as_Vector()->length_in_bytes() == 8) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (OrV src (LoadVector mem))); format %{ "vpor $dst,$src,$mem\t! or vectors (8 bytes)" %} ins_encode %{ @@ -9176,7 +9223,8 @@ %} instruct vxor4B_mem(vecS dst, vecS src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 4); + predicate((UseAVX > 0) && (n->as_Vector()->length_in_bytes() == 4) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (XorV src (LoadVector mem))); format %{ "vpxor $dst,$src,$mem\t! xor vectors (4 bytes)" %} ins_encode %{ @@ -9208,7 +9256,8 @@ %} instruct vxor8B_mem(vecD dst, vecD src, memory mem) %{ - predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 8); + predicate((UseAVX > 0) && (n->as_Vector()->length_in_bytes() == 8) && + (vector_length_in_bytes(n->in(1)) > 8)); match(Set dst (XorV src (LoadVector mem))); format %{ "vpxor $dst,$src,$mem\t! xor vectors (8 bytes)" %} ins_encode %{
diff --git a/src/hotspot/cpu/zero/globals_zero.hpp b/src/hotspot/cpu/zero/globals_zero.hpp index 49b39ff..ecc0829 100644 --- a/src/hotspot/cpu/zero/globals_zero.hpp +++ b/src/hotspot/cpu/zero/globals_zero.hpp
@@ -77,8 +77,7 @@ define_pd_global(bool, PreserveFramePointer, false); -// No performance work done here yet. -define_pd_global(bool, CompactStrings, false); +define_pd_global(bool, CompactStrings, true); define_pd_global(bool, ThreadLocalHandshakes, false);
diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 44a05ae..296f34e 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp
@@ -64,9 +64,9 @@ #include "runtime/os.hpp" #include "runtime/osThread.hpp" #include "runtime/perfMemory.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/statSampler.hpp" -#include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" @@ -1188,7 +1188,7 @@ ::abort(); // dump core } - ::exit(1); + ::_exit(1); } // Die immediately, no exit hook, no abort hook, no cleanup.
diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 15b820f..9340dcf 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp
@@ -22,6 +22,16 @@ * */ +/* + * On macOS MAP_JIT cannot be used in conjunction with MAP_FIXED when mapping + * a page for codecache. Therefore our traditional technique of doing commit + * and uncommit - replacing a mapping with another one at the same address + * range but swapped MAP_NORESERVE - does not work. + * The "exec" flag basically means "its code cache" and it should be used + * consistently for the same mapping (reserve-commit-uncommit etc) + * This affects pd_reserve_memory, pd_commit_memory, pd_uncommit_memory functions + */ + // no precompiled headers #include "jvm.h" #include "classfile/classLoader.hpp" @@ -229,6 +239,8 @@ static char cpu_arch[] = "amd64"; #elif defined(ARM) static char cpu_arch[] = "arm"; +#elif defined(AARCH64) +static char cpu_arch[] = "aarch64"; #elif defined(PPC32) static char cpu_arch[] = "ppc"; #elif defined(SPARC) @@ -468,7 +480,9 @@ } } Arguments::set_java_home(buf); - set_boot_path('/', ':'); + if (!set_boot_path('/', ':')) { + vm_exit_during_initialization("Failed setting boot class path.", NULL); + } } // Where to look for native libraries. @@ -1092,7 +1106,7 @@ ::abort(); // dump core } - ::exit(1); + ::_exit(1); } // Die immediately, no exit hook, no abort hook, no cleanup. @@ -2005,12 +2019,25 @@ // problem. bool os::pd_commit_memory(char* addr, size_t size, bool exec) { int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; -#ifdef __OpenBSD__ +#if defined(__OpenBSD__) // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot); if (::mprotect(addr, size, prot) == 0) { return true; } +#elif defined(__APPLE__) + if (exec) { + // Do not replace MAP_JIT mappings, see JDK-8234930 + if (::mprotect(addr, size, prot) == 0) { + return true; + } + } else { + uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, + MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); + if (res != (uintptr_t) MAP_FAILED) { + return true; + } + } #else uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); @@ -2089,11 +2116,23 @@ } -bool os::pd_uncommit_memory(char* addr, size_t size) { -#ifdef __OpenBSD__ +MACOS_ONLY(bool os::pd_uncommit_memory(char* addr, size_t size, bool executable)) +NOT_MACOS(bool os::pd_uncommit_memory(char* addr, size_t size)) { +#if defined(__OpenBSD__) // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size)); return ::mprotect(addr, size, PROT_NONE) == 0; +#elif defined(__APPLE__) + if (executable) { + if (::madvise(addr, size, MADV_FREE) != 0) { + return false; + } + return ::mprotect(addr, size, PROT_NONE) == 0; + } else { + uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, + MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); + return res != (uintptr_t) MAP_FAILED; + } #else uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); @@ -2117,11 +2156,17 @@ // 'requested_addr' is only treated as a hint, the return value may or // may not start from the requested address. Unlike Bsd mmap(), this // function returns NULL to indicate failure. -static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) { +static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed, bool executable = false) { char * addr; int flags; flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS; +#ifdef __APPLE__ + if (executable) { + guarantee(!fixed, "MAP_JIT (for execute) is incompatible with MAP_FIXED"); + flags |= MAP_JIT; + } +#endif if (fixed) { assert((uintptr_t)requested_addr % os::Bsd::page_size() == 0, "unaligned address"); flags |= MAP_FIXED; @@ -2140,10 +2185,18 @@ return ::munmap(addr, size) == 0; } +#if defined(__APPLE__) +char* os::pd_reserve_memory(size_t bytes, char* requested_addr, + size_t alignment_hint, + bool executable) { + return anon_mmap(requested_addr, bytes, (requested_addr != NULL), executable); +} +#else char* os::pd_reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) { return anon_mmap(requested_addr, bytes, (requested_addr != NULL)); } +#endif bool os::pd_release_memory(char* addr, size_t size) { return anon_munmap(addr, size); @@ -3018,20 +3071,17 @@ set_signal_handler(SIGXFSZ, true); #if defined(__APPLE__) - // In Mac OS X 10.4, CrashReporter will write a crash log for all 'fatal' signals, including - // signals caught and handled by the JVM. To work around this, we reset the mach task - // signal handler that's placed on our process by CrashReporter. This disables - // CrashReporter-based reporting. - // - // This work-around is not necessary for 10.5+, as CrashReporter no longer intercedes - // on caught fatal signals. - // - // Additionally, gdb installs both standard BSD signal handlers, and mach exception - // handlers. By replacing the existing task exception handler, we disable gdb's mach + // lldb (gdb) installs both standard BSD signal handlers, and mach exception + // handlers. By replacing the existing task exception handler, we disable lldb's mach // exception handling, while leaving the standard BSD signal handlers functional. + // + // EXC_MASK_BAD_ACCESS needed by all architectures for NULL ptr checking + // EXC_MASK_ARITHMETIC needed by all architectures for div by 0 checking + // EXC_MASK_BAD_INSTRUCTION needed by aarch64 to initiate deoptimization kern_return_t kr; kr = task_set_exception_ports(mach_task_self(), - EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC, + EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC + AARCH64_ONLY(| EXC_MASK_BAD_INSTRUCTION), MACH_PORT_NULL, EXCEPTION_STATE_IDENTITY, MACHINE_THREAD_STATE);
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index f31a474..476b1c2 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp
@@ -158,6 +158,11 @@ const char * os::Linux::_glibc_version = NULL; const char * os::Linux::_libpthread_version = NULL; +#ifdef __GLIBC__ +os::Linux::mallinfo_func_t os::Linux::_mallinfo = NULL; +os::Linux::mallinfo2_func_t os::Linux::_mallinfo2 = NULL; +#endif // __GLIBC__ + static jlong initial_time_count=0; static int clock_tics_per_sec = 100; @@ -1512,7 +1517,7 @@ ::abort(); // dump core } - ::exit(1); + ::_exit(1); } // Die immediately, no exit hook, no abort hook, no cleanup. @@ -1835,6 +1840,12 @@ #ifndef EM_AARCH64 #define EM_AARCH64 183 /* ARM AARCH64 */ #endif +#ifndef EM_RISCV + #define EM_RISCV 243 /* RISC-V */ +#endif +#ifndef EM_LOONGARCH + #define EM_LOONGARCH 258 /* LoongArch */ +#endif static const arch_t arch_array[]={ {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, @@ -1860,6 +1871,8 @@ {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"}, {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}, {EM_AARCH64, EM_AARCH64, ELFCLASS64, ELFDATA2LSB, (char*)"AARCH64"}, + {EM_RISCV, EM_RISCV, ELFCLASS64, ELFDATA2LSB, (char*)"RISC-V"}, + {EM_LOONGARCH, EM_LOONGARCH, ELFCLASS64, ELFDATA2LSB, (char*)"LoongArch"}, }; #if (defined IA32) @@ -1894,9 +1907,13 @@ static Elf32_Half running_arch_code=EM_68K; #elif (defined SH) static Elf32_Half running_arch_code=EM_SH; +#elif (defined RISCV) + static Elf32_Half running_arch_code=EM_RISCV; +#elif (defined LOONGARCH) + static Elf32_Half running_arch_code=EM_LOONGARCH; #else #error Method os::dll_load requires that one of following is defined:\ - AARCH64, ALPHA, ARM, AMD64, IA32, IA64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, S390, SH, __sparc + AARCH64, ALPHA, ARM, AMD64, IA32, IA64, LOONGARCH, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, RISCV, S390, SH, __sparc #endif // Identify compatability class for VM's architecture and library's architecture @@ -2333,19 +2350,25 @@ // Print glibc outstanding allocations. // (note: there is no implementation of mallinfo for muslc) #ifdef __GLIBC__ - struct mallinfo mi = ::mallinfo(); - - // mallinfo is an old API. Member names mean next to nothing and, beyond that, are int. - // So values may have wrapped around. Still useful enough to see how much glibc thinks - // we allocated. - const size_t total_allocated = (size_t)(unsigned)mi.uordblks; - st->print("C-Heap outstanding allocations: " SIZE_FORMAT "K", total_allocated / K); - // Since mallinfo members are int, glibc values may have wrapped. Warn about this. - if ((vmrss * K) > UINT_MAX && (vmrss * K) > (total_allocated + UINT_MAX)) { - st->print(" (may have wrapped)"); + size_t total_allocated = 0; + bool might_have_wrapped = false; + if (_mallinfo2 != NULL) { + struct glibc_mallinfo2 mi = _mallinfo2(); + total_allocated = mi.uordblks; + } else if (_mallinfo != NULL) { + // mallinfo is an old API. Member names mean next to nothing and, beyond that, are int. + // So values may have wrapped around. Still useful enough to see how much glibc thinks + // we allocated. + struct glibc_mallinfo mi = _mallinfo(); + total_allocated = (size_t)(unsigned)mi.uordblks; + // Since mallinfo members are int, glibc values may have wrapped. Warn about this. + might_have_wrapped = (vmrss * K) > UINT_MAX && (vmrss * K) > (total_allocated + UINT_MAX); } - st->cr(); - + if (_mallinfo2 != NULL || _mallinfo != NULL) { + st->print_cr("C-Heap outstanding allocations: " SIZE_FORMAT "K%s", + total_allocated / K, + might_have_wrapped ? " (may have wrapped)" : ""); + } #endif // __GLIBC__ } @@ -3202,8 +3225,26 @@ return dlvsym(handle, name, "libnuma_1.2"); } +// Check numa dependent syscalls +static bool numa_syscall_check() { + // NUMA APIs depend on several syscalls. E.g., get_mempolicy is required for numa_get_membind and + // numa_get_interleave_mask. But these dependent syscalls can be unsupported for various reasons. + // Especially in dockers, get_mempolicy is not allowed with the default configuration. So it's necessary + // to check whether the syscalls are available. Currently, only get_mempolicy is checked since checking + // others like mbind would cause unexpected side effects. +#ifdef SYS_get_mempolicy + int dummy = 0; + if (syscall(SYS_get_mempolicy, &dummy, NULL, 0, (void*)&dummy, 3) == -1) { + return false; + } +#endif + + return true; +} + bool os::Linux::libnuma_init() { - if (sched_getcpu() != -1) { // Requires sched_getcpu() support + // Requires sched_getcpu() and numa dependent syscalls support + if ((sched_getcpu() != -1) && numa_syscall_check()) { void *handle = dlopen("libnuma.so.1", RTLD_LAZY); if (handle != NULL) { set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, @@ -3522,6 +3563,9 @@ if (mincore((address)stack_extent, os::vm_page_size(), vec) == -1) { // Fallback to slow path on all errors, including EAGAIN + assert((uintptr_t)addr >= stack_extent, + "Sanity: addr should be larger than extent, " PTR_FORMAT " >= " PTR_FORMAT, + p2i(addr), stack_extent); stack_extent = (uintptr_t) get_stack_commited_bottom( os::Linux::initial_thread_stack_bottom(), (size_t)addr - stack_extent); @@ -5229,6 +5273,11 @@ Linux::initialize_os_info(); +#ifdef __GLIBC__ + Linux::_mallinfo = CAST_TO_FN_PTR(Linux::mallinfo_func_t, dlsym(RTLD_DEFAULT, "mallinfo")); + Linux::_mallinfo2 = CAST_TO_FN_PTR(Linux::mallinfo2_func_t, dlsym(RTLD_DEFAULT, "mallinfo2")); +#endif // __GLIBC__ + os::Linux::CPUPerfTicks pticks; bool res = os::Linux::get_tick_information(&pticks, -1);
diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 546da29..e94a2e1 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp
@@ -278,6 +278,41 @@ static void set_numa_all_nodes_ptr(struct bitmask **ptr) { _numa_all_nodes_ptr = (ptr == NULL ? NULL : *ptr); } static void set_numa_nodes_ptr(struct bitmask **ptr) { _numa_nodes_ptr = (ptr == NULL ? NULL : *ptr); } static int sched_getcpu_syscall(void); + +#ifdef __GLIBC__ + struct glibc_mallinfo { + int arena; + int ordblks; + int smblks; + int hblks; + int hblkhd; + int usmblks; + int fsmblks; + int uordblks; + int fordblks; + int keepcost; + }; + + struct glibc_mallinfo2 { + size_t arena; + size_t ordblks; + size_t smblks; + size_t hblks; + size_t hblkhd; + size_t usmblks; + size_t fsmblks; + size_t uordblks; + size_t fordblks; + size_t keepcost; + }; + + typedef struct glibc_mallinfo (*mallinfo_func_t)(void); + typedef struct glibc_mallinfo2 (*mallinfo2_func_t)(void); + + static mallinfo_func_t _mallinfo; + static mallinfo2_func_t _mallinfo2; +#endif + public: static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index c0a0c96..c5bb956 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp
@@ -1362,7 +1362,11 @@ os->print(", si_addr: " PTR_FORMAT, p2i(si->si_addr)); #ifdef SIGPOLL } else if (sig == SIGPOLL) { - os->print(", si_band: %ld", si->si_band); + // siginfo_t.si_band is defined as "long", and it is so in most + // implementations. But SPARC64 glibc has a bug: si_band is "int". + // Cast si_band to "long" to prevent format specifier mismatch. + // See: https://sourceware.org/bugzilla/show_bug.cgi?id=23821 + os->print(", si_band: %ld", (long) si->si_band); #endif } @@ -2016,7 +2020,8 @@ while (_event < 0) { // OS-level "spurious wakeups" are ignored status = pthread_cond_wait(_cond, _mutex); - assert_status(status == 0, status, "cond_wait"); + assert_status(status == 0 MACOS_ONLY(|| status == ETIMEDOUT), + status, "cond_wait"); } --_nParked; @@ -2211,7 +2216,8 @@ if (time == 0) { _cur_index = REL_INDEX; // arbitrary choice when not timed status = pthread_cond_wait(&_cond[_cur_index], _mutex); - assert_status(status == 0, status, "cond_timedwait"); + assert_status(status == 0 MACOS_ONLY(|| status == ETIMEDOUT), + status, "cond_wait"); } else { _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
diff --git a/src/hotspot/os/solaris/os_solaris.cpp b/src/hotspot/os/solaris/os_solaris.cpp index d38a886..ae5a7cd 100644 --- a/src/hotspot/os/solaris/os_solaris.cpp +++ b/src/hotspot/os/solaris/os_solaris.cpp
@@ -1343,7 +1343,7 @@ ::abort(); // dump core (for debugging) } - ::exit(1); + ::_exit(1); } // Die immediately, no exit hook, no abort hook, no cleanup.
diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index b8a4224..d1dc252 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp
@@ -31,6 +31,7 @@ #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" +#include "code/nativeInst.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" @@ -56,9 +57,9 @@ #include "runtime/orderAccess.hpp" #include "runtime/osThread.hpp" #include "runtime/perfMemory.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/statSampler.hpp" -#include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" @@ -120,12 +121,19 @@ static FILETIME process_user_time; static FILETIME process_kernel_time; -#ifdef _M_AMD64 +#if defined(_M_ARM64) + #define __CPU__ aarch64 +#elif defined(_M_AMD64) #define __CPU__ amd64 #else #define __CPU__ i486 #endif +#if defined(USE_VECTORED_EXCEPTION_HANDLING) +PVOID topLevelVectoredExceptionHandler = NULL; +LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = NULL; +#endif + // save DLL module handle, used by GetModuleFileName HINSTANCE vm_lib_handle; @@ -144,6 +152,12 @@ if (ForceTimeHighResolution) { timeEndPeriod(1L); } +#if defined(USE_VECTORED_EXCEPTION_HANDLING) + if (topLevelVectoredExceptionHandler != NULL) { + RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler); + topLevelVectoredExceptionHandler = NULL; + } +#endif break; default: break; @@ -454,6 +468,12 @@ log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id()); +#ifdef USE_VECTORED_EXCEPTION_HANDLING + // Any exception is caught by the Vectored Exception Handler, so VM can + // generate error dump when an exception occurred in non-Java thread + // (e.g. VM thread). + thread->call_run(); +#else // Install a win32 structured exception handler around every thread created // by VM, so VM can generate error dump when an exception occurred in non- // Java thread (e.g. VM thread). @@ -463,6 +483,7 @@ (_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } +#endif // Note: at this point the thread object may already have deleted itself. // Do not dereference it from here on out. @@ -589,6 +610,9 @@ return false; } + // Initial state is ALLOCATED but not INITIALIZED + osthread->set_state(ALLOCATED); + // Initialize support for Java interrupts HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL); if (interrupt_event == NULL) { @@ -680,7 +704,7 @@ osthread->set_thread_handle(thread_handle); osthread->set_thread_id(thread_id); - // Initial thread state is INITIALIZED, not SUSPENDED + // Thread state now is INITIALIZED, not SUSPENDED osthread->set_state(INITIALIZED); // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain @@ -1426,15 +1450,18 @@ static const arch_t arch_array[] = { {IMAGE_FILE_MACHINE_I386, (char*)"IA 32"}, - {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"} + {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}, + {IMAGE_FILE_MACHINE_ARM64, (char*)"ARM 64"} }; -#if (defined _M_AMD64) +#if (defined _M_ARM64) + static const uint16_t running_arch = IMAGE_FILE_MACHINE_ARM64; +#elif (defined _M_AMD64) static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64; #elif (defined _M_IX86) static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386; #else #error Method os::dll_load requires that one of following \ - is defined :_M_AMD64 or _M_IX86 + is defined :_M_AMD64 or _M_IX86 or _M_ARM64 #endif @@ -1706,11 +1733,19 @@ case 10000: if (is_workstation) { - st->print("10"); + if (build_number >= 22000) { + st->print("11"); + } else { + st->print("10"); + } } else { - // distinguish Windows Server 2016 and 2019 by build number - // Windows server 2019 GA 10/2018 build number is 17763 - if (build_number > 17762) { + // distinguish Windows Server by build number + // - 2016 GA 10/2016 build: 14393 + // - 2019 GA 11/2018 build: 17763 + // - 2022 GA 08/2021 build: 20348 + if (build_number > 20347) { + st->print("Server 2022"); + } else if (build_number > 17762) { st->print("Server 2019"); } else { st->print("Server 2016"); @@ -1729,7 +1764,8 @@ SYSTEM_INFO si; ZeroMemory(&si, sizeof(SYSTEM_INFO)); GetNativeSystemInfo(&si); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) || + (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)) { st->print(" , 64 bit"); } @@ -2141,6 +2177,8 @@ #define PC_NAME Rip #elif defined(_M_IX86) #define PC_NAME Eip +#elif defined(_M_ARM64) + #define PC_NAME Pc #else #error unknown architecture #endif @@ -2235,7 +2273,17 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { // handle exception caused by idiv; should only happen for -MinInt/-1 // (division by zero is handled explicitly) -#ifdef _M_AMD64 +#if defined(_M_ARM64) + PCONTEXT ctx = exceptionInfo->ContextRecord; + address pc = (address)ctx->Sp; + assert(pc[0] == 0x83, "not an sdiv opcode"); //Fixme did i get the right opcode? + assert(ctx->X4 == min_jint, "unexpected idiv exception"); + // set correct result values and continue after idiv instruction + ctx->Pc = (uint64_t)pc + 4; // idiv reg, reg, reg is 4 bytes + ctx->X4 = (uint64_t)min_jint; // result + ctx->X5 = (uint64_t)0; // remainder + // Continue the execution +#elif defined(_M_AMD64) PCONTEXT ctx = exceptionInfo->ContextRecord; address pc = (address)ctx->Rip; assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode"); @@ -2266,6 +2314,7 @@ return EXCEPTION_CONTINUE_EXECUTION; } +#if defined(_M_AMD64) || defined(_M_IX86) //----------------------------------------------------------------------------- LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { PCONTEXT ctx = exceptionInfo->ContextRecord; @@ -2311,6 +2360,7 @@ return EXCEPTION_CONTINUE_SEARCH; } +#endif static inline void report_error(Thread* t, DWORD exception_code, address addr, void* siginfo, void* context) { @@ -2320,47 +2370,15 @@ // somewhere where we can find it in the minidump. } -bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, - struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) { - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - address addr = (address) exceptionRecord->ExceptionInformation[1]; - if (Interpreter::contains(pc)) { - *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); - if (!fr->is_first_java_frame()) { - // get_frame_at_stack_banging_point() is only called when we - // have well defined stacks so java_sender() calls do not need - // to assert safe_for_sender() first. - *fr = fr->java_sender(); - } - } else { - // more complex code with compiled code - assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); - CodeBlob* cb = CodeCache::find_blob(pc); - if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { - // Not sure where the pc points to, fallback to default - // stack overflow handling - return false; - } else { - *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); - // in compiled code, the stack banging is performed just after the return pc - // has been pushed on the stack - *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp())); - if (!fr->is_java_frame()) { - // See java_sender() comment above. - *fr = fr->java_sender(); - } - } - } - assert(fr->is_java_frame(), "Safety check"); - return true; -} - //----------------------------------------------------------------------------- JNIEXPORT LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH; - DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; -#ifdef _M_AMD64 + PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord; + DWORD exception_code = exception_record->ExceptionCode; +#if defined(_M_ARM64) + address pc = (address) exceptionInfo->ContextRecord->Pc; +#elif defined(_M_AMD64) address pc = (address) exceptionInfo->ContextRecord->Rip; #else address pc = (address) exceptionInfo->ContextRecord->Eip; @@ -2378,9 +2396,8 @@ // This is safe to do because we have a new/unique ExceptionInformation // code for this condition. if (exception_code == EXCEPTION_ACCESS_VIOLATION) { - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - int exception_subcode = (int) exceptionRecord->ExceptionInformation[0]; - address addr = (address) exceptionRecord->ExceptionInformation[1]; + int exception_subcode = (int) exception_record->ExceptionInformation[0]; + address addr = (address) exception_record->ExceptionInformation[1]; if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) { int page_size = os::vm_page_size(); @@ -2444,8 +2461,10 @@ // Last unguard failed or not unguarding tty->print_raw_cr("Execution protection violation"); - report_error(t, exception_code, addr, exceptionInfo->ExceptionRecord, +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) + report_error(t, exception_code, addr, exception_record, exceptionInfo->ContextRecord); +#endif return EXCEPTION_CONTINUE_SEARCH; } } @@ -2458,33 +2477,33 @@ if (exception_code == EXCEPTION_ACCESS_VIOLATION) { if (t != NULL && t->is_Java_thread()) { JavaThread* thread = (JavaThread*) t; - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - address addr = (address) exceptionRecord->ExceptionInformation[1]; + address addr = (address) exception_record->ExceptionInformation[1]; if (os::is_memory_serialize_page(thread, addr)) { // Block current thread until the memory serialize page permission restored. os::block_on_serialize_page_trap(); return EXCEPTION_CONTINUE_EXECUTION; } } - } - if ((exception_code == EXCEPTION_ACCESS_VIOLATION) && - VM_Version::is_cpuinfo_segv_addr(pc)) { - // Verify that OS save/restore AVX registers. - return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr()); +#if defined(_M_AMD64) || defined(_M_IX86) + if (VM_Version::is_cpuinfo_segv_addr(pc)) { + // Verify that OS save/restore AVX registers. + return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr()); + } +#endif } if (t != NULL && t->is_Java_thread()) { JavaThread* thread = (JavaThread*) t; bool in_java = thread->thread_state() == _thread_in_Java; + bool in_native = thread->thread_state() == _thread_in_native; + bool in_vm = thread->thread_state() == _thread_in_vm; // Handle potential stack overflows up front. if (exception_code == EXCEPTION_STACK_OVERFLOW) { if (thread->stack_guards_enabled()) { if (in_java) { frame fr; - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - address addr = (address) exceptionRecord->ExceptionInformation[1]; if (os::win32::get_frame_at_stack_banging_point(thread, exceptionInfo, pc, &fr)) { assert(fr.is_java_frame(), "Must be a Java frame"); SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr); @@ -2493,7 +2512,7 @@ // Yellow zone violation. The o/s has unprotected the first yellow // zone page for us. Note: must call disable_stack_yellow_zone to // update the enabled status, even if the zone contains only one page. - assert(thread->thread_state() != _thread_in_vm, "Undersized StackShadowPages"); + assert(!in_vm, "Undersized StackShadowPages"); thread->disable_stack_yellow_reserved_zone(); // If not in java code, return and hope for the best. return in_java @@ -2503,15 +2522,16 @@ // Fatal red zone violation. thread->disable_stack_red_zone(); tty->print_raw_cr("An unrecoverable stack overflow has occurred."); - report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, - exceptionInfo->ContextRecord); +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) + report_error(t, exception_code, pc, exception_record, + exceptionInfo->ContextRecord); +#endif return EXCEPTION_CONTINUE_SEARCH; } } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) { - // Either stack overflow or null pointer exception. if (in_java) { - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - address addr = (address) exceptionRecord->ExceptionInformation[1]; + // Either stack overflow or null pointer exception. + address addr = (address) exception_record->ExceptionInformation[1]; address stack_end = thread->stack_end(); if (addr < stack_end && addr >= stack_end - os::vm_page_size()) { // Stack overflow. @@ -2530,48 +2550,41 @@ return Handle_Exception(exceptionInfo, stub); } } - { #ifdef _WIN64 - // If it's a legal stack address map the entire region in - // - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - address addr = (address) exceptionRecord->ExceptionInformation[1]; - if (addr > thread->stack_reserved_zone_base() && addr < thread->stack_base()) { - addr = (address)((uintptr_t)addr & - (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); - os::commit_memory((char *)addr, thread->stack_base() - addr, - !ExecMem); - return EXCEPTION_CONTINUE_EXECUTION; - } else -#endif - { - // Null pointer exception. - if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr)) { - address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); - if (stub != NULL) return Handle_Exception(exceptionInfo, stub); - } - report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, - exceptionInfo->ContextRecord); - return EXCEPTION_CONTINUE_SEARCH; - } + // If it's a legal stack address, map the entire region in + if (addr > thread->stack_reserved_zone_base() && addr < thread->stack_base()) { + addr = (address)((uintptr_t)addr & + (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); + os::commit_memory((char *)addr, thread->stack_base() - addr, + !ExecMem); + return EXCEPTION_CONTINUE_EXECUTION; } +#endif + // Null pointer exception. + if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr)) { + address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); + if (stub != NULL) return Handle_Exception(exceptionInfo, stub); + } + report_error(t, exception_code, pc, exception_record, + exceptionInfo->ContextRecord); + return EXCEPTION_CONTINUE_SEARCH; } #ifdef _WIN64 // Special care for fast JNI field accessors. // 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 (exception_code == EXCEPTION_ACCESS_VIOLATION) { - address addr = JNI_FastGetField::find_slowcase_pc(pc); - if (addr != (address)-1) { - return Handle_Exception(exceptionInfo, addr); - } + address slowcase_pc = JNI_FastGetField::find_slowcase_pc(pc); + if (slowcase_pc != (address)-1) { + return Handle_Exception(exceptionInfo, slowcase_pc); } #endif // Stack overflow or null pointer exception in native code. - report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) + report_error(t, exception_code, pc, exception_record, exceptionInfo->ContextRecord); +#endif return EXCEPTION_CONTINUE_SEARCH; } // /EXCEPTION_ACCESS_VIOLATION // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2583,13 +2596,25 @@ CodeBlob* cb = CodeCache::find_blob_unsafe(pc); nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; } - if ((thread->thread_state() == _thread_in_vm && - thread->doing_unsafe_access()) || + if ((in_vm && thread->doing_unsafe_access()) || (nm != NULL && nm->has_unsafe_access())) { return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, (address)Assembler::locate_next_instruction(pc))); } } +#ifdef _M_ARM64 + if (in_java && + (exception_code == EXCEPTION_ILLEGAL_INSTRUCTION || + exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) { + if (nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) { + if (TraceTraps) { + tty->print_cr("trap: zombie_not_entrant"); + } + return Handle_Exception(exceptionInfo, SharedRuntime::get_handle_wrong_method_stub()); + } + } +#endif + if (in_java) { switch (exception_code) { case EXCEPTION_INT_DIVIDE_BY_ZERO: @@ -2600,20 +2625,74 @@ } // switch } - if (((thread->thread_state() == _thread_in_Java) || - (thread->thread_state() == _thread_in_native)) && - exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) { + +#if defined(_M_AMD64) || defined(_M_IX86) + if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) { LONG result=Handle_FLT_Exception(exceptionInfo); if (result==EXCEPTION_CONTINUE_EXECUTION) return result; } +#endif } +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) + if (exception_code != EXCEPTION_BREAKPOINT) { + report_error(t, exception_code, pc, exception_record, + exceptionInfo->ContextRecord); + } +#endif + return EXCEPTION_CONTINUE_SEARCH; +} + +#if defined(USE_VECTORED_EXCEPTION_HANDLING) +LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { + PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; +#if defined(_M_ARM64) + address pc = (address) exceptionInfo->ContextRecord->Pc; +#elif defined(_M_AMD64) + address pc = (address) exceptionInfo->ContextRecord->Rip; +#else + address pc = (address) exceptionInfo->ContextRecord->Eip; +#endif + + // Fast path for code part of the code cache + if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) { + return topLevelExceptionFilter(exceptionInfo); + } + + // Handle the case where we get an implicit exception in AOT generated + // code. AOT DLL's loaded are not registered for structured exceptions. + // If the exception occurred in the codeCache or AOT code, pass control + // to our normal exception handler. + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb != NULL) { + return topLevelExceptionFilter(exceptionInfo); + } + + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + +#if defined(USE_VECTORED_EXCEPTION_HANDLING) +LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { + if (InterceptOSException) goto exit; + DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; +#if defined(_M_ARM64) + address pc = (address) exceptionInfo->ContextRecord->Pc; +#elif defined(_M_AMD64) + address pc = (address) exceptionInfo->ContextRecord->Rip; +#else + address pc = (address) exceptionInfo->ContextRecord->Eip; +#endif + Thread* t = Thread::current_or_null_safe(); + if (exception_code != EXCEPTION_BREAKPOINT) { report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, exceptionInfo->ContextRecord); } - return EXCEPTION_CONTINUE_SEARCH; +exit: + return previousUnhandledExceptionFilter ? previousUnhandledExceptionFilter(exceptionInfo) : EXCEPTION_CONTINUE_SEARCH; } +#endif #ifndef _WIN64 // Special care for fast JNI accessors. @@ -3463,7 +3542,12 @@ // Must never look like an address returned by reserve_memory, // even in its subfields (as defined by the CPU immediate fields, // if the CPU splits constants across multiple instructions). +#ifdef _M_ARM64 + // AArch64 has a maximum addressable space of 48-bits + return (char*)((1ull << 48) - 1); +#else return (char*)-1; +#endif } #define MAX_ERROR_COUNT 100 @@ -4137,6 +4221,11 @@ jint os::init_2(void) { // Setup Windows Exceptions +#if defined(USE_VECTORED_EXCEPTION_HANDLING) + topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter); + previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter); +#endif + // for debugging float code generation bugs if (ForceFloatExceptions) { #ifndef _WIN64 @@ -5509,7 +5598,7 @@ // WINDOWS CONTEXT Flags for THREAD_SAMPLING #if defined(IA32) #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS) -#elif defined (AMD64) +#elif defined(AMD64) || defined(_M_ARM64) #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT) #endif
diff --git a/src/hotspot/os_cpu/aix_ppc/orderAccess_aix_ppc.hpp b/src/hotspot/os_cpu/aix_ppc/orderAccess_aix_ppc.hpp index 81427eb..d126d42 100644 --- a/src/hotspot/os_cpu/aix_ppc/orderAccess_aix_ppc.hpp +++ b/src/hotspot/os_cpu/aix_ppc/orderAccess_aix_ppc.hpp
@@ -82,7 +82,7 @@ struct OrderAccess::PlatformOrderedLoad<byte_size, X_ACQUIRE> { template <typename T> - T operator()(const volatile T* p) const { register T t = Atomic::load(p); inlasm_acquire_reg(t); return t; } + T operator()(const volatile T* p) const { T t = Atomic::load(p); inlasm_acquire_reg(t); return t; } }; #undef inlasm_sync
diff --git a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp index f00e6d9..5769025 100644 --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp
@@ -152,7 +152,9 @@ // method returns the Java sender of the current frame. *fr = os::fetch_frame_from_context(uc); if (!fr->is_first_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. *fr = fr->java_sender(); } } else { @@ -169,7 +171,7 @@ address lr = ucontext_get_lr(uc); *fr = frame(sp, lr); if (!fr->is_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // See java_sender() comment above. assert(!fr->is_first_frame(), "Safety check"); *fr = fr->java_sender(); }
diff --git a/src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp new file mode 100644 index 0000000..757da22 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp
@@ -0,0 +1,82 @@ +/* + * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_ATOMIC_BSD_AARCH64_HPP +#define OS_CPU_BSD_AARCH64_VM_ATOMIC_BSD_AARCH64_HPP + +// Implementation of class atomic +// Note that memory_order_conservative requires a full barrier after atomic stores. +// See https://patchwork.kernel.org/patch/3575821/ + +#define FULL_MEM_BARRIER __sync_synchronize() +#define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); +#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); + +template<size_t byte_size> +struct Atomic::PlatformAdd + : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> > +{ + template<typename I, typename D> + D add_and_fetch(I add_value, D volatile* dest, atomic_memory_order order) const { + D res = __atomic_add_fetch(dest, add_value, __ATOMIC_RELEASE); + FULL_MEM_BARRIER; + return res; + } +}; + +template<size_t byte_size> +template<typename T> +inline T Atomic::PlatformXchg<byte_size>::operator()(T exchange_value, + T volatile* dest, + atomic_memory_order order) const { + STATIC_ASSERT(byte_size == sizeof(T)); + T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE); + FULL_MEM_BARRIER; + return res; +} + +template<size_t byte_size> +template<typename T> +inline T Atomic::PlatformCmpxchg<byte_size>::operator()(T exchange_value, + T volatile* dest, + T compare_value, + atomic_memory_order order) const { + STATIC_ASSERT(byte_size == sizeof(T)); + if (order == memory_order_relaxed) { + T value = compare_value; + __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, + __ATOMIC_RELAXED, __ATOMIC_RELAXED); + return value; + } else { + T value = compare_value; + FULL_MEM_BARRIER; + __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, + __ATOMIC_RELAXED, __ATOMIC_RELAXED); + FULL_MEM_BARRIER; + return value; + } +} + +#endif // OS_CPU_BSD_AARCH64_VM_ATOMIC_BSD_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/bytes_bsd_aarch64.inline.hpp b/src/hotspot/os_cpu/bsd_aarch64/bytes_bsd_aarch64.inline.hpp new file mode 100644 index 0000000..b8d6a38 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/bytes_bsd_aarch64.inline.hpp
@@ -0,0 +1,55 @@ +/* + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP +#define OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP + +#ifdef __APPLE__ +#include <libkern/OSByteOrder.h> +#endif + +#if defined(__APPLE__) +# define bswap_16(x) OSSwapInt16(x) +# define bswap_32(x) OSSwapInt32(x) +# define bswap_64(x) OSSwapInt64(x) +#else +# error "Unimplemented" +#endif + +// Efficient swapping of data bytes from Java byte +// ordering to native byte ordering and vice versa. +inline u2 Bytes::swap_u2(u2 x) { + return bswap_16(x); +} + +inline u4 Bytes::swap_u4(u4 x) { + return bswap_32(x); +} + +inline u8 Bytes::swap_u8(u8 x) { + return bswap_64(x); +} + +#endif // OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.inline.hpp b/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.inline.hpp new file mode 100644 index 0000000..114b684 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.inline.hpp
@@ -0,0 +1,188 @@ +/* + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_COPY_BSD_AARCH64_INLINE_HPP +#define OS_CPU_BSD_AARCH64_VM_COPY_BSD_AARCH64_INLINE_HPP + +#define COPY_SMALL(from, to, count) \ +{ \ + long tmp0, tmp1, tmp2, tmp3; \ + long tmp4, tmp5, tmp6, tmp7; \ + __asm volatile( \ +" adr %[t0], 0f;\n" \ +" add %[t0], %[t0], %[cnt], lsl #5;\n" \ +" br %[t0];\n" \ +" .align 5;\n" \ +"0:" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldr %[t0], [%[s], #0];\n" \ +" str %[t0], [%[d], #0];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldr %[t2], [%[s], #16];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" str %[t2], [%[d], #16];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" ldr %[t4], [%[s], #32];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" str %[t4], [%[d], #32];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" ldp %[t4], %[t5], [%[s], #32];\n" \ +"2:" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" stp %[t4], %[t5], [%[d], #32];\n" \ +" b 1f;\n" \ +" .align 5;\n" \ +" ldr %[t6], [%[s], #0];\n" \ +" ldp %[t0], %[t1], [%[s], #8];\n" \ +" ldp %[t2], %[t3], [%[s], #24];\n" \ +" ldp %[t4], %[t5], [%[s], #40];\n" \ +" str %[t6], [%[d]], #8;\n" \ +" b 2b;\n" \ +" .align 5;\n" \ +" ldp %[t0], %[t1], [%[s], #0];\n" \ +" ldp %[t2], %[t3], [%[s], #16];\n" \ +" ldp %[t4], %[t5], [%[s], #32];\n" \ +" ldp %[t6], %[t7], [%[s], #48];\n" \ +" stp %[t0], %[t1], [%[d], #0];\n" \ +" stp %[t2], %[t3], [%[d], #16];\n" \ +" stp %[t4], %[t5], [%[d], #32];\n" \ +" stp %[t6], %[t7], [%[d], #48];\n" \ +"1:" \ + \ + : [s]"+r"(from), [d]"+r"(to), [cnt]"+r"(count), \ + [t0]"=&r"(tmp0), [t1]"=&r"(tmp1), [t2]"=&r"(tmp2), [t3]"=&r"(tmp3), \ + [t4]"=&r"(tmp4), [t5]"=&r"(tmp5), [t6]"=&r"(tmp6), [t7]"=&r"(tmp7) \ + : \ + : "memory", "cc"); \ +} + +static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); + if (__builtin_expect(count <= 8, 1)) { + COPY_SMALL(from, to, count); + return; + } + _Copy_conjoint_words(from, to, count); +} + +static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + if (__builtin_constant_p(count)) { + memcpy(to, from, count * sizeof(HeapWord)); + return; + } + __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); + if (__builtin_expect(count <= 8, 1)) { + COPY_SMALL(from, to, count); + return; + } + _Copy_disjoint_words(from, to, count); +} + +static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { + __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory"); + if (__builtin_expect(count <= 8, 1)) { + COPY_SMALL(from, to, count); + return; + } + _Copy_disjoint_words(from, to, count); +} + +static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_words(from, to, count); +} + +static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(const void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { + pd_conjoint_bytes(from, to, count); +} + +static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { + _Copy_conjoint_jshorts_atomic(from, to, count); +} + +static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { + _Copy_conjoint_jints_atomic(from, to, count); +} + +static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { + _Copy_conjoint_jlongs_atomic(from, to, count); +} + +static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); +} + +static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_bytes(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jshorts(from, to, count); +} + +static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jints(from, to, count); +} + +static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jlongs(from, to, count); +} + +static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { + assert(!UseCompressedOops, "foo!"); + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_arrayof_conjoint_jlongs(from, to, count); +} + +#endif // OS_CPU_BSD_AARCH64_VM_COPY_BSD_AARCH64_INLINE_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.s b/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.s new file mode 100644 index 0000000..70b0c24 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/copy_bsd_aarch64.s
@@ -0,0 +1,239 @@ +/* + * Copyright (c) 2016, Linaro Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#define CFUNC(x) _##x + + .global CFUNC(_Copy_conjoint_words) + .global CFUNC(_Copy_disjoint_words) + +s .req x0 +d .req x1 +count .req x2 +t0 .req x3 +t1 .req x4 +t2 .req x5 +t3 .req x6 +t4 .req x7 +t5 .req x8 +t6 .req x9 +t7 .req x10 + + .align 6 +CFUNC(_Copy_disjoint_words): + // Ensure 2 word aligned + tbz s, #3, fwd_copy_aligned + ldr t0, [s], #8 + str t0, [d], #8 + sub count, count, #1 + +fwd_copy_aligned: + // Bias s & d so we only pre index on the last copy + sub s, s, #16 + sub d, d, #16 + + ldp t0, t1, [s, #16] + ldp t2, t3, [s, #32] + ldp t4, t5, [s, #48] + ldp t6, t7, [s, #64]! + + subs count, count, #16 + blo fwd_copy_drain + +fwd_copy_again: + prfm pldl1keep, [s, #256] + stp t0, t1, [d, #16] + ldp t0, t1, [s, #16] + stp t2, t3, [d, #32] + ldp t2, t3, [s, #32] + stp t4, t5, [d, #48] + ldp t4, t5, [s, #48] + stp t6, t7, [d, #64]! + ldp t6, t7, [s, #64]! + subs count, count, #8 + bhs fwd_copy_again + +fwd_copy_drain: + stp t0, t1, [d, #16] + stp t2, t3, [d, #32] + stp t4, t5, [d, #48] + stp t6, t7, [d, #64]! + + // count is now -8..-1 for 0..7 words to copy + adr t0, 0f + add t0, t0, count, lsl #5 + br t0 + + .align 5 + ret // -8 == 0 words + .align 5 + ldr t0, [s, #16] // -7 == 1 word + str t0, [d, #16] + ret + .align 5 + ldp t0, t1, [s, #16] // -6 = 2 words + stp t0, t1, [d, #16] + ret + .align 5 + ldp t0, t1, [s, #16] // -5 = 3 words + ldr t2, [s, #32] + stp t0, t1, [d, #16] + str t2, [d, #32] + ret + .align 5 + ldp t0, t1, [s, #16] // -4 = 4 words + ldp t2, t3, [s, #32] + stp t0, t1, [d, #16] + stp t2, t3, [d, #32] + ret + .align 5 + ldp t0, t1, [s, #16] // -3 = 5 words + ldp t2, t3, [s, #32] + ldr t4, [s, #48] + stp t0, t1, [d, #16] + stp t2, t3, [d, #32] + str t4, [d, #48] + ret + .align 5 + ldp t0, t1, [s, #16] // -2 = 6 words + ldp t2, t3, [s, #32] + ldp t4, t5, [s, #48] + stp t0, t1, [d, #16] + stp t2, t3, [d, #32] + stp t4, t5, [d, #48] + ret + .align 5 + ldp t0, t1, [s, #16] // -1 = 7 words + ldp t2, t3, [s, #32] + ldp t4, t5, [s, #48] + ldr t6, [s, #64] + stp t0, t1, [d, #16] + stp t2, t3, [d, #32] + stp t4, t5, [d, #48] + str t6, [d, #64] + // Is always aligned here, code for 7 words is one instruction + // too large so it just falls through. + .align 5 +0: + ret + + .align 6 +CFUNC(_Copy_conjoint_words): + sub t0, d, s + cmp t0, count, lsl #3 + bhs CFUNC(_Copy_disjoint_words) + + add s, s, count, lsl #3 + add d, d, count, lsl #3 + + // Ensure 2 word aligned + tbz s, #3, bwd_copy_aligned + ldr t0, [s, #-8]! + str t0, [d, #-8]! + sub count, count, #1 + +bwd_copy_aligned: + ldp t0, t1, [s, #-16] + ldp t2, t3, [s, #-32] + ldp t4, t5, [s, #-48] + ldp t6, t7, [s, #-64]! + + subs count, count, #16 + blo bwd_copy_drain + +bwd_copy_again: + prfum pldl1keep, [s, #-256] + stp t0, t1, [d, #-16] + ldp t0, t1, [s, #-16] + stp t2, t3, [d, #-32] + ldp t2, t3, [s, #-32] + stp t4, t5, [d, #-48] + ldp t4, t5, [s, #-48] + stp t6, t7, [d, #-64]! + ldp t6, t7, [s, #-64]! + subs count, count, #8 + bhs bwd_copy_again + +bwd_copy_drain: + stp t0, t1, [d, #-16] + stp t2, t3, [d, #-32] + stp t4, t5, [d, #-48] + stp t6, t7, [d, #-64]! + + // count is now -8..-1 for 0..7 words to copy + adr t0, 0f + add t0, t0, count, lsl #5 + br t0 + + .align 5 + ret // -8 == 0 words + .align 5 + ldr t0, [s, #-8] // -7 == 1 word + str t0, [d, #-8] + ret + .align 5 + ldp t0, t1, [s, #-16] // -6 = 2 words + stp t0, t1, [d, #-16] + ret + .align 5 + ldp t0, t1, [s, #-16] // -5 = 3 words + ldr t2, [s, #-24] + stp t0, t1, [d, #-16] + str t2, [d, #-24] + ret + .align 5 + ldp t0, t1, [s, #-16] // -4 = 4 words + ldp t2, t3, [s, #-32] + stp t0, t1, [d, #-16] + stp t2, t3, [d, #-32] + ret + .align 5 + ldp t0, t1, [s, #-16] // -3 = 5 words + ldp t2, t3, [s, #-32] + ldr t4, [s, #-40] + stp t0, t1, [d, #-16] + stp t2, t3, [d, #-32] + str t4, [d, #-40] + ret + .align 5 + ldp t0, t1, [s, #-16] // -2 = 6 words + ldp t2, t3, [s, #-32] + ldp t4, t5, [s, #-48] + stp t0, t1, [d, #-16] + stp t2, t3, [d, #-32] + stp t4, t5, [d, #-48] + ret + .align 5 + ldp t0, t1, [s, #-16] // -1 = 7 words + ldp t2, t3, [s, #-32] + ldp t4, t5, [s, #-48] + ldr t6, [s, #-56] + stp t0, t1, [d, #-16] + stp t2, t3, [d, #-32] + stp t4, t5, [d, #-48] + str t6, [d, #-56] + // Is always aligned here, code for 7 words is one instruction + // too large so it just falls through. + .align 5 +0: + ret
diff --git a/src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp new file mode 100644 index 0000000..77f99a8 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp
@@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_GLOBALS_BSD_AARCH64_HPP +#define OS_CPU_BSD_AARCH64_VM_GLOBALS_BSD_AARCH64_HPP + +// Sets the default values for platform dependent flags used by the runtime system. +// (see globals.hpp) + +define_pd_global(bool, DontYieldALot, false); +define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default +define_pd_global(intx, VMThreadStackSize, 2048); + +define_pd_global(intx, CompilerThreadStackSize, 2048); + +define_pd_global(uintx,JVMInvokeMethodSlack, 8192); + +// Used on 64 bit platforms for UseCompressedOops base address +define_pd_global(uintx,HeapBaseMinAddress, 2*G); + +#endif // OS_CPU_BSD_AARCH64_VM_GLOBALS_BSD_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/icache_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/icache_bsd_aarch64.hpp new file mode 100644 index 0000000..a9efb90 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/icache_bsd_aarch64.hpp
@@ -0,0 +1,45 @@ +/* + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_ICACHE_AARCH64_HPP +#define OS_CPU_BSD_AARCH64_ICACHE_AARCH64_HPP + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. + +class ICache : public AbstractICache { + public: + static void initialize(); + static void invalidate_word(address addr) { + __clear_cache((char *)addr, (char *)(addr + 4)); + } + static void invalidate_range(address start, int nbytes) { + __clear_cache((char *)start, (char *)(start + nbytes)); + } +}; + +#endif // OS_CPU_BSD_AARCH64_ICACHE_AARCH64_HPP \ No newline at end of file
diff --git a/src/hotspot/os_cpu/bsd_aarch64/orderAccess_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/orderAccess_bsd_aarch64.hpp new file mode 100644 index 0000000..9b15466 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/orderAccess_bsd_aarch64.hpp
@@ -0,0 +1,54 @@ +/* + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_ORDERACCESS_BSD_AARCH64_HPP +#define OS_CPU_BSD_AARCH64_VM_ORDERACCESS_BSD_AARCH64_HPP + +// Included in orderAccess.hpp header file. + +// Implementation of class OrderAccess. + +inline void OrderAccess::loadload() { acquire(); } +inline void OrderAccess::storestore() { release(); } +inline void OrderAccess::loadstore() { acquire(); } +inline void OrderAccess::storeload() { fence(); } + +#define FULL_MEM_BARRIER __sync_synchronize() +#define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); +#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); + +inline void OrderAccess::acquire() { + READ_MEM_BARRIER; +} + +inline void OrderAccess::release() { + WRITE_MEM_BARRIER; +} + +inline void OrderAccess::fence() { + FULL_MEM_BARRIER; +} + +#endif // OS_CPU_BSD_AARCH64_VM_ORDERACCESS_BSD_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp new file mode 100644 index 0000000..231eb9e --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp
@@ -0,0 +1,753 @@ +/* + * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// no precompiled headers +#include "jvm.h" +#include "asm/macroAssembler.hpp" +#include "classfile/classLoader.hpp" +#include "classfile/systemDictionary.hpp" +#include "classfile/vmSymbols.hpp" +#include "code/codeCache.hpp" +#include "code/icBuffer.hpp" +#include "code/vtableStubs.hpp" +#include "interpreter/interpreter.hpp" +#include "logging/log.hpp" +#include "memory/allocation.inline.hpp" +#include "os_share_bsd.hpp" +#include "prims/jniFastGetField.hpp" +#include "prims/jvm_misc.hpp" +#include "runtime/arguments.hpp" +#include "runtime/extendedPC.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "runtime/java.hpp" +#include "runtime/javaCalls.hpp" +#include "runtime/mutexLocker.hpp" +#include "runtime/osThread.hpp" +#include "runtime/sharedRuntime.hpp" +#include "runtime/stubRoutines.hpp" +#include "runtime/thread.inline.hpp" +#include "runtime/timer.hpp" +#include "utilities/align.hpp" +#include "utilities/events.hpp" +#include "utilities/vmError.hpp" + +// put OS-includes here +# include <sys/types.h> +# include <sys/mman.h> +# include <pthread.h> +# include <signal.h> +# include <errno.h> +# include <dlfcn.h> +# include <stdlib.h> +# include <stdio.h> +# include <unistd.h> +# include <sys/resource.h> +# include <sys/stat.h> +# include <sys/time.h> +# include <sys/utsname.h> +# include <sys/socket.h> +# include <sys/wait.h> +# include <pwd.h> +# include <poll.h> +#ifndef __OpenBSD__ + # include <ucontext.h> +#endif + +#if !defined(__APPLE__) && !defined(__NetBSD__) +# include <pthread_np.h> +#endif + +#define SPELL_REG_SP "sp" +#define SPELL_REG_FP "fp" + +#ifdef __APPLE__ +// see darwin-xnu/osfmk/mach/arm/_structs.h + +// 10.5 UNIX03 member name prefixes +#define DU3_PREFIX(s, m) __ ## s.__ ## m +#endif + +#define context_x uc_mcontext->DU3_PREFIX(ss,x) +#define context_fp uc_mcontext->DU3_PREFIX(ss,fp) +#define context_lr uc_mcontext->DU3_PREFIX(ss,lr) +#define context_sp uc_mcontext->DU3_PREFIX(ss,sp) +#define context_pc uc_mcontext->DU3_PREFIX(ss,pc) +#define context_cpsr uc_mcontext->DU3_PREFIX(ss,cpsr) +#define context_esr uc_mcontext->DU3_PREFIX(es,esr) + +address os::current_stack_pointer() { +#if defined(__clang__) || defined(__llvm__) + void *sp; + __asm__("mov %0, " SPELL_REG_SP : "=r"(sp)); + return (address) sp; +#else + register void *sp __asm__ (SPELL_REG_SP); + return (address) sp; +#endif +} + +char* os::non_memory_address_word() { + // Must never look like an address returned by reserve_memory, + // even in its subfields (as defined by the CPU immediate fields, + // if the CPU splits constants across multiple instructions). + + // the return value used in computation of Universe::non_oop_word(), which + // is loaded by cpu/aarch64 by MacroAssembler::movptr(Register, uintptr_t) + return (char*) 0xffffffffffff; +} + +address os::Bsd::ucontext_get_pc(const ucontext_t * uc) { + return (address)uc->context_pc; +} + +void os::Bsd::ucontext_set_pc(ucontext_t * uc, address pc) { + uc->context_pc = (intptr_t)pc; +} + +intptr_t* os::Bsd::ucontext_get_sp(const ucontext_t * uc) { + return (intptr_t*)uc->context_sp; +} + +intptr_t* os::Bsd::ucontext_get_fp(const ucontext_t * uc) { + return (intptr_t*)uc->context_fp; +} + +// For Forte Analyzer AsyncGetCallTrace profiling support - thread +// is currently interrupted by SIGPROF. +// os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal +// frames. Currently we don't do that on Linux, so it's the same as +// os::fetch_frame_from_context(). +ExtendedPC os::Bsd::fetch_frame_from_ucontext(Thread* thread, + const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { + + assert(thread != NULL, "just checking"); + assert(ret_sp != NULL, "just checking"); + assert(ret_fp != NULL, "just checking"); + + return os::fetch_frame_from_context(uc, ret_sp, ret_fp); +} + +ExtendedPC os::fetch_frame_from_context(const void* ucVoid, + intptr_t** ret_sp, intptr_t** ret_fp) { + + ExtendedPC epc; + const ucontext_t* uc = (const ucontext_t*)ucVoid; + + if (uc != NULL) { + epc = ExtendedPC(os::Bsd::ucontext_get_pc(uc)); + if (ret_sp) *ret_sp = os::Bsd::ucontext_get_sp(uc); + if (ret_fp) *ret_fp = os::Bsd::ucontext_get_fp(uc); + } else { + // construct empty ExtendedPC for return value checking + epc = ExtendedPC(NULL); + if (ret_sp) *ret_sp = (intptr_t *)NULL; + if (ret_fp) *ret_fp = (intptr_t *)NULL; + } + + return epc; +} + +frame os::fetch_frame_from_context(const void* ucVoid) { + intptr_t* sp; + intptr_t* fp; + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); + return frame(sp, fp, epc.pc()); +} + +bool os::Bsd::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) { + address pc = (address) os::Bsd::ucontext_get_pc(uc); + if (Interpreter::contains(pc)) { + // interpreter performs stack banging after the fixed frame header has + // been generated while the compilers perform it before. To maintain + // semantic consistency between interpreted and compiled frames, the + // method returns the Java sender of the current frame. + *fr = os::fetch_frame_from_context(uc); + if (!fr->is_first_java_frame()) { + assert(fr->safe_for_sender(thread), "Safety check"); + *fr = fr->java_sender(); + } + } else { + // more complex code with compiled code + assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { + // Not sure where the pc points to, fallback to default + // stack overflow handling + return false; + } else { + // In compiled code, the stack banging is performed before LR + // has been saved in the frame. LR is live, and SP and FP + // belong to the caller. + intptr_t* fp = os::Bsd::ucontext_get_fp(uc); + intptr_t* sp = os::Bsd::ucontext_get_sp(uc); + address pc = (address)(uc->context_lr + - NativeInstruction::instruction_size); + *fr = frame(sp, fp, pc); + if (!fr->is_java_frame()) { + assert(fr->safe_for_sender(thread), "Safety check"); + assert(!fr->is_first_frame(), "Safety check"); + *fr = fr->java_sender(); + } + } + } + assert(fr->is_java_frame(), "Safety check"); + return true; +} + +// JVM compiled with -fno-omit-frame-pointer, so RFP is saved on the stack. +frame os::get_sender_for_C_frame(frame* fr) { + return frame(fr->link(), fr->link(), fr->sender_pc()); +} + +NOINLINE frame os::current_frame() { + intptr_t *fp = *(intptr_t **)__builtin_frame_address(0); + frame myframe((intptr_t*)os::current_stack_pointer(), + (intptr_t*)fp, + CAST_FROM_FN_PTR(address, os::current_frame)); + if (os::is_first_C_frame(&myframe)) { + // stack is not walkable + return frame(); + } else { + return os::get_sender_for_C_frame(&myframe); + } +} + +// Utility functions +extern "C" JNIEXPORT int +JVM_handle_bsd_signal(int sig, + siginfo_t* info, + void* ucVoid, + int abort_if_unrecognized) { + ucontext_t* uc = (ucontext_t*) ucVoid; + + Thread* t = Thread::current_or_null_safe(); + + // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away + // (no destructors can be run) + os::ThreadCrashProtection::check_crash_protection(sig, t); + + SignalHandlerMark shm(t); + + // Note: it's not uncommon that JNI code uses signal/sigset to install + // then restore certain signal handler (e.g. to temporarily block SIGPIPE, + // or have a SIGILL handler when detecting CPU type). When that happens, + // JVM_handle_bsd_signal() might be invoked with junk info/ucVoid. To + // avoid unnecessary crash when libjsig is not preloaded, try handle signals + // that do not require siginfo/ucontext first. + + if (sig == SIGPIPE || sig == SIGXFSZ) { + // allow chained handler to go first + if (os::Bsd::chained_handler(sig, info, ucVoid)) { + return true; + } else { + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 + return true; + } + } + +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return 1; + } + } +#endif + + JavaThread* thread = NULL; + VMThread* vmthread = NULL; + if (os::Bsd::signal_handlers_are_installed) { + if (t != NULL ){ + if(t->is_Java_thread()) { + thread = (JavaThread*)t; + } + else if(t->is_VM_thread()){ + vmthread = (VMThread *)t; + } + } + } + + // Handle SafeFetch faults: + if (uc != NULL) { + address const pc = (address) os::Bsd::ucontext_get_pc(uc); + if (pc && StubRoutines::is_safefetch_fault(pc)) { + os::Bsd::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); + return 1; + } + } + + // decide if this trap can be handled by a stub + address stub = NULL; + + address pc = NULL; + + //%note os_trap_1 + if (info != NULL && uc != NULL && thread != NULL) { + pc = (address) os::Bsd::ucontext_get_pc(uc); + + // Handle ALL stack overflow variations here + if (sig == SIGSEGV || sig == SIGBUS) { + address addr = (address) info->si_addr; + + // check if fault address is within thread stack + if (thread->on_local_stack(addr)) { + ThreadWXEnable wx(WXWrite, thread); + // stack overflow + if (thread->in_stack_yellow_reserved_zone(addr)) { + if (thread->thread_state() == _thread_in_Java) { + if (thread->in_stack_reserved_zone(addr)) { + frame fr; + if (os::Bsd::get_frame_at_stack_banging_point(thread, uc, &fr)) { + assert(fr.is_java_frame(), "Must be a Java frame"); + frame activation = + SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr); + if (activation.sp() != NULL) { + thread->disable_stack_reserved_zone(); + if (activation.is_interpreted_frame()) { + thread->set_reserved_stack_activation((address)( + activation.fp() + frame::interpreter_frame_initial_sp_offset)); + } else { + thread->set_reserved_stack_activation((address)activation.unextended_sp()); + } + return 1; + } + } + } + // Throw a stack overflow exception. Guard pages will be reenabled + // while unwinding the stack. + thread->disable_stack_yellow_reserved_zone(); + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); + } else { + // Thread was in the vm or native code. Return and try to finish. + thread->disable_stack_yellow_reserved_zone(); + return 1; + } + } else if (thread->in_stack_red_zone(addr)) { + // Fatal red zone violation. Disable the guard pages and fall through + // to handle_unexpected_exception way down below. + thread->disable_stack_red_zone(); + tty->print_raw_cr("An irrecoverable stack overflow has occurred."); + } + } + } + + // We test if stub is already set (by the stack overflow code + // above) so it is not overwritten by the code that follows. This + // check is not required on other platforms, because on other + // platforms we check for SIGSEGV only or SIGBUS only, where here + // we have to check for both SIGSEGV and SIGBUS. + if (thread->thread_state() == _thread_in_Java && stub == NULL) { + // Java thread running in Java code => find exception handler if any + // a fault inside compiled code, the interpreter, or a stub + ThreadWXEnable wx(WXWrite, thread); + // Handle signal from NativeJump::patch_verified_entry(). + if ((sig == SIGILL) + && nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) { + if (TraceTraps) { + tty->print_cr("trap: zombie_not_entrant"); + } + stub = SharedRuntime::get_handle_wrong_method_stub(); + } else if ((sig == SIGSEGV || sig == SIGBUS) && os::is_poll_address((address)info->si_addr)) { + stub = SharedRuntime::get_poll_stub(pc); +#if defined(__APPLE__) + // 32-bit Darwin reports a SIGBUS for nearly all memory access exceptions. + // 64-bit Darwin may also use a SIGBUS (seen with compressed oops). + // Catching SIGBUS here prevents the implicit SIGBUS NULL check below from + // being called, so only do so if the implicit NULL check is not necessary. + } else if (sig == SIGBUS && MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { +#else + } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) { +#endif + // BugId 4454115: A read from a MappedByteBuffer can fault + // here if the underlying file has been truncated. + // Do not crash the VM in such a case. + CodeBlob* cb = CodeCache::find_blob_unsafe(pc); + CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; + if ((nm != NULL && nm->has_unsafe_access())) { + address next_pc = pc + NativeCall::instruction_size; + stub = SharedRuntime::handle_unsafe_access(thread, next_pc); + } + } + else + + if (sig == SIGFPE && + (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) { + stub = + SharedRuntime:: + continuation_for_implicit_exception(thread, + pc, + SharedRuntime:: + IMPLICIT_DIVIDE_BY_ZERO); +#ifdef __APPLE__ + } else if (sig == SIGFPE && info->si_code == FPE_NOOP) { + Unimplemented(); +#endif /* __APPLE__ */ + + } else if ((sig == SIGSEGV || sig == SIGBUS) && + !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { + // Determination of interpreter/vtable stub/compiled code null exception + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); + } + } else if ((thread->thread_state() == _thread_in_vm || + thread->thread_state() == _thread_in_native) && + sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ + thread->doing_unsafe_access()) { + address next_pc = pc + NativeCall::instruction_size; + stub = SharedRuntime::handle_unsafe_access(thread, next_pc); + } + + // 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 just return to retry the write. + if ((sig == SIGSEGV) && + os::is_memory_serialize_page(thread, (address) info->si_addr)) { + // Block current thread until the memory serialize page permission restored. + os::block_on_serialize_page_trap(); + return true; + } + } + + if (stub != NULL) { + // save all thread context in case we need to restore it + if (thread != NULL) thread->set_saved_exception_pc(pc); + + os::Bsd::ucontext_set_pc(uc, stub); + return true; + } + + // signal-chaining + if (os::Bsd::chained_handler(sig, info, ucVoid)) { + return true; + } + + if (!abort_if_unrecognized) { + // caller wants another chance, so give it to him + return false; + } + + if (pc == NULL && uc != NULL) { + pc = os::Bsd::ucontext_get_pc(uc); + } + + // unmask current signal + sigset_t newset; + sigemptyset(&newset); + sigaddset(&newset, sig); + sigprocmask(SIG_UNBLOCK, &newset, NULL); + + VMError::report_and_die(t, sig, pc, info, ucVoid); + + ShouldNotReachHere(); + return true; // Mute compiler +} + +void os::Bsd::init_thread_fpu_state(void) { +} + +bool os::is_allocatable(size_t bytes) { + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// thread stack + +// Minimum usable stack sizes required to get to user code. Space for +// HotSpot guard pages is added later. +size_t os::Posix::_compiler_thread_min_stack_allowed = 72 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 72 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 72 * K; + +// return default stack size for thr_type +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { + // default stack size (compiler thread needs larger stack) + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); + return s; +} + +static void current_stack_region(address * bottom, size_t * size) { +#ifdef __APPLE__ + pthread_t self = pthread_self(); + void *stacktop = pthread_get_stackaddr_np(self); + *size = pthread_get_stacksize_np(self); + *bottom = (address) stacktop - *size; +#elif defined(__OpenBSD__) + stack_t ss; + int rslt = pthread_stackseg_np(pthread_self(), &ss); + + if (rslt != 0) + fatal("pthread_stackseg_np failed with error = %d", rslt); + + *bottom = (address)((char *)ss.ss_sp - ss.ss_size); + *size = ss.ss_size; +#else + pthread_attr_t attr; + + int rslt = pthread_attr_init(&attr); + + // JVM needs to know exact stack location, abort if it fails + if (rslt != 0) + fatal("pthread_attr_init failed with error = %d", rslt); + + rslt = pthread_attr_get_np(pthread_self(), &attr); + + if (rslt != 0) + fatal("pthread_attr_get_np failed with error = %d", rslt); + + if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 || + pthread_attr_getstacksize(&attr, size) != 0) { + fatal("Can not locate current stack attributes!"); + } + + pthread_attr_destroy(&attr); +#endif + assert(os::current_stack_pointer() >= *bottom && + os::current_stack_pointer() < *bottom + *size, "just checking"); +} + +address os::current_stack_base() { + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return (bottom + size); +} + +size_t os::current_stack_size() { + // stack size includes normal stack and HotSpot guard pages + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return size; +} + +///////////////////////////////////////////////////////////////////////////// +// helper functions for fatal error handler + +void os::print_context(outputStream *st, const void *context) { + if (context == NULL) return; + + const ucontext_t *uc = (const ucontext_t*)context; + st->print_cr("Registers:"); + st->print( " x0=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 0]); + st->print(" x1=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 1]); + st->print(" x2=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 2]); + st->print(" x3=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 3]); + st->cr(); + st->print( " x4=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 4]); + st->print(" x5=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 5]); + st->print(" x6=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 6]); + st->print(" x7=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 7]); + st->cr(); + st->print( " x8=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 8]); + st->print(" x9=" INTPTR_FORMAT, (intptr_t)uc->context_x[ 9]); + st->print(" x10=" INTPTR_FORMAT, (intptr_t)uc->context_x[10]); + st->print(" x11=" INTPTR_FORMAT, (intptr_t)uc->context_x[11]); + st->cr(); + st->print( "x12=" INTPTR_FORMAT, (intptr_t)uc->context_x[12]); + st->print(" x13=" INTPTR_FORMAT, (intptr_t)uc->context_x[13]); + st->print(" x14=" INTPTR_FORMAT, (intptr_t)uc->context_x[14]); + st->print(" x15=" INTPTR_FORMAT, (intptr_t)uc->context_x[15]); + st->cr(); + st->print( "x16=" INTPTR_FORMAT, (intptr_t)uc->context_x[16]); + st->print(" x17=" INTPTR_FORMAT, (intptr_t)uc->context_x[17]); + st->print(" x18=" INTPTR_FORMAT, (intptr_t)uc->context_x[18]); + st->print(" x19=" INTPTR_FORMAT, (intptr_t)uc->context_x[19]); + st->cr(); + st->print( "x20=" INTPTR_FORMAT, (intptr_t)uc->context_x[20]); + st->print(" x21=" INTPTR_FORMAT, (intptr_t)uc->context_x[21]); + st->print(" x22=" INTPTR_FORMAT, (intptr_t)uc->context_x[22]); + st->print(" x23=" INTPTR_FORMAT, (intptr_t)uc->context_x[23]); + st->cr(); + st->print( "x24=" INTPTR_FORMAT, (intptr_t)uc->context_x[24]); + st->print(" x25=" INTPTR_FORMAT, (intptr_t)uc->context_x[25]); + st->print(" x26=" INTPTR_FORMAT, (intptr_t)uc->context_x[26]); + st->print(" x27=" INTPTR_FORMAT, (intptr_t)uc->context_x[27]); + st->cr(); + st->print( "x28=" INTPTR_FORMAT, (intptr_t)uc->context_x[28]); + st->print(" fp=" INTPTR_FORMAT, (intptr_t)uc->context_fp); + st->print(" lr=" INTPTR_FORMAT, (intptr_t)uc->context_lr); + st->print(" sp=" INTPTR_FORMAT, (intptr_t)uc->context_sp); + st->cr(); + st->print( "pc=" INTPTR_FORMAT, (intptr_t)uc->context_pc); + st->print(" cpsr=" INTPTR_FORMAT, (intptr_t)uc->context_cpsr); + st->cr(); + + intptr_t *sp = (intptr_t *)os::Bsd::ucontext_get_sp(uc); + st->print_cr("Top of Stack: (sp=" INTPTR_FORMAT ")", (intptr_t)sp); + print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t)); + st->cr(); + + // Note: it may be unsafe to inspect memory near pc. For example, pc may + // point to garbage if entry point in an nmethod is corrupted. Leave + // this at the end, and hope for the best. + address pc = os::Bsd::ucontext_get_pc(uc); + print_instructions(st, pc, sizeof(char)); + st->cr(); +} + +void os::print_register_info(outputStream *st, const void *context) { + if (context == NULL) return; + + const ucontext_t *uc = (const ucontext_t*)context; + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is horrendously verbose but the layout of the registers in the + // context does not match how we defined our abstract Register set, so + // we can't just iterate through the gregs area + + // this is only for the "general purpose" registers + + st->print(" x0="); print_location(st, uc->context_x[ 0]); + st->print(" x1="); print_location(st, uc->context_x[ 1]); + st->print(" x2="); print_location(st, uc->context_x[ 2]); + st->print(" x3="); print_location(st, uc->context_x[ 3]); + st->print(" x4="); print_location(st, uc->context_x[ 4]); + st->print(" x5="); print_location(st, uc->context_x[ 5]); + st->print(" x6="); print_location(st, uc->context_x[ 6]); + st->print(" x7="); print_location(st, uc->context_x[ 7]); + st->print(" x8="); print_location(st, uc->context_x[ 8]); + st->print(" x9="); print_location(st, uc->context_x[ 9]); + st->print("x10="); print_location(st, uc->context_x[10]); + st->print("x11="); print_location(st, uc->context_x[11]); + st->print("x12="); print_location(st, uc->context_x[12]); + st->print("x13="); print_location(st, uc->context_x[13]); + st->print("x14="); print_location(st, uc->context_x[14]); + st->print("x15="); print_location(st, uc->context_x[15]); + st->print("x16="); print_location(st, uc->context_x[16]); + st->print("x17="); print_location(st, uc->context_x[17]); + st->print("x18="); print_location(st, uc->context_x[18]); + st->print("x19="); print_location(st, uc->context_x[19]); + st->print("x20="); print_location(st, uc->context_x[20]); + st->print("x21="); print_location(st, uc->context_x[21]); + st->print("x22="); print_location(st, uc->context_x[22]); + st->print("x23="); print_location(st, uc->context_x[23]); + st->print("x24="); print_location(st, uc->context_x[24]); + st->print("x25="); print_location(st, uc->context_x[25]); + st->print("x26="); print_location(st, uc->context_x[26]); + st->print("x27="); print_location(st, uc->context_x[27]); + st->print("x28="); print_location(st, uc->context_x[28]); + + st->cr(); +} + +void os::setup_fpu() { +} + +#ifndef PRODUCT +void os::verify_stack_alignment() { + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +} +#endif + +int os::extra_bang_size_in_bytes() { + // AArch64 does not require the additional stack bang. + return 0; +} + +void os::current_thread_enable_wx(WXMode mode) { + pthread_jit_write_protect_np(mode == WXExec); +} + +extern "C" { + int SpinPause() { + return 0; + } + + void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { + if (from > to) { + const jshort *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + const jshort *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { + if (from > to) { + const jint *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + const jint *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { + if (from > to) { + const jlong *end = from + count; + while (from < end) + os::atomic_copy64(from++, to++); + } + else if (from < to) { + const jlong *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + os::atomic_copy64(from--, to--); + } + } + + void _Copy_arrayof_conjoint_bytes(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count); + } + void _Copy_arrayof_conjoint_jshorts(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count * 2); + } + void _Copy_arrayof_conjoint_jints(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count * 4); + } + void _Copy_arrayof_conjoint_jlongs(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count * 8); + } +};
diff --git a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.hpp new file mode 100644 index 0000000..6e03c89 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.hpp
@@ -0,0 +1,42 @@ +/* + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_HPP +#define OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_HPP + + static void setup_fpu(); + + static bool is_allocatable(size_t bytes); + + // Used to register dynamic code cache area with the OS + // 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(const volatile void *src, volatile void *dst) { + *(jlong *) dst = *(const jlong *) src; + } + +#endif // OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/pauth_bsd_aarch64.inline.hpp b/src/hotspot/os_cpu/bsd_aarch64/pauth_bsd_aarch64.inline.hpp new file mode 100644 index 0000000..f4be578 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/pauth_bsd_aarch64.inline.hpp
@@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_PAUTH_BSD_AARCH64_INLINE_HPP +#define OS_CPU_BSD_AARCH64_VM_PAUTH_BSD_AARCH64_INLINE_HPP + +#ifdef __APPLE__ +#include <ptrauth.h> +#endif + +// Only the PAC instructions in the NOP space can be used. This ensures the +// binaries work on systems without PAC. Write these instructions using their +// alternate "hint" instructions to ensure older compilers can still be used. +// For Apple, use the provided interface as this may provide additional +// optimization. + +#define XPACLRI "hint #0x7;" + +inline address pauth_strip_pointer(address ptr) { +#ifdef __APPLE__ + return ptrauth_strip(ptr, ptrauth_key_asib); +#else + register address result __asm__("x30") = ptr; + asm (XPACLRI : "+r"(result)); + return result; +#endif +} + +#undef XPACLRI + +#endif // OS_CPU_BSD_AARCH64_VM_PAUTH_BSD_AARCH64_INLINE_HPP +
diff --git a/src/hotspot/os_cpu/bsd_aarch64/prefetch_bsd_aarch64.inline.hpp b/src/hotspot/os_cpu/bsd_aarch64/prefetch_bsd_aarch64.inline.hpp new file mode 100644 index 0000000..525b6b5 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/prefetch_bsd_aarch64.inline.hpp
@@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_PREFETCH_BSD_AARCH64_INLINE_HPP +#define OS_CPU_BSD_AARCH64_VM_PREFETCH_BSD_AARCH64_INLINE_HPP + +#include "runtime/prefetch.hpp" + + +inline void Prefetch::read (void *loc, intx interval) { + if (interval >= 0) + asm("prfm PLDL1KEEP, [%0, %1]" : : "r"(loc), "r"(interval)); +} + +inline void Prefetch::write(void *loc, intx interval) { + if (interval >= 0) + asm("prfm PSTL1KEEP, [%0, %1]" : : "r"(loc), "r"(interval)); +} + +#endif // OS_CPU_BSD_AARCH64_VM_PREFETCH_BSD_AARCH64_INLINE_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp new file mode 100644 index 0000000..84dcfa7 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp
@@ -0,0 +1,104 @@ +/* + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/thread.inline.hpp" + +frame JavaThread::pd_last_frame() { + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); + vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); + return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); +} + +// For Forte Analyzer AsyncGetCallTrace profiling support - thread is +// currently interrupted by SIGPROF +bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, bool isInJava) { + + assert(Thread::current() == this, "caller must be current thread"); + return pd_get_top_frame(fr_addr, ucontext, isInJava); +} + +bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { + return pd_get_top_frame(fr_addr, ucontext, isInJava); +} + +bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) { + assert(this->is_Java_thread(), "must be JavaThread"); + JavaThread* jt = (JavaThread *)this; + + // If we have a last_Java_frame, then we should use it even if + // isInJava == true. It should be more reliable than ucontext info. + if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { + *fr_addr = jt->pd_last_frame(); + return true; + } + + // At this point, we don't have a last_Java_frame, so + // we try to glean some information out of the ucontext + // if we were running Java code when SIGPROF came in. + if (isInJava) { + ucontext_t* uc = (ucontext_t*) ucontext; + + intptr_t* ret_fp; + intptr_t* ret_sp; + ExtendedPC addr = os::fetch_frame_from_context(uc, &ret_sp, &ret_fp); + if (addr.pc() == NULL || ret_sp == NULL ) { + // ucontext wasn't useful + return false; + } + + if (MetaspaceShared::is_in_trampoline_frame(addr.pc())) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } + + frame ret_frame(ret_sp, ret_fp, addr.pc()); + if (!ret_frame.safe_for_sender(jt)) { +#ifdef COMPILER2 + frame ret_frame2(ret_sp, NULL, addr.pc()); + if (!ret_frame2.safe_for_sender(jt)) { + // nothing else to try if the frame isn't good + return false; + } + ret_frame = ret_frame2; +#else + // nothing else to try if the frame isn't good + return false; +#endif /* COMPILER2 */ + } + *fr_addr = ret_frame; + return true; + } + + // nothing else to try + return false; +} + +void JavaThread::cache_global_variables() { } +
diff --git a/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.hpp new file mode 100644 index 0000000..48daab4 --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.hpp
@@ -0,0 +1,74 @@ +/* + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_THREAD_BSD_AARCH64_HPP +#define OS_CPU_BSD_AARCH64_VM_THREAD_BSD_AARCH64_HPP + + private: + + void pd_initialize() { + _anchor.clear(); + } + + frame pd_last_frame(); + + public: + // Mutators are highly dangerous.... + intptr_t* last_Java_fp() { return _anchor.last_Java_fp(); } + void set_last_Java_fp(intptr_t* fp) { _anchor.set_last_Java_fp(fp); } + + void set_base_of_stack_pointer(intptr_t* base_sp) { + } + + static ByteSize last_Java_fp_offset() { + return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset(); + } + + intptr_t* base_of_stack_pointer() { + return NULL; + } + void record_base_of_stack_pointer() { + } + + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, + bool isInJava); + + bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava); +private: + bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava); +public: + + static Thread *aarch64_get_thread_helper() { + return Thread::current(); + } + + // These routines are only used on cpu architectures that + // have separate register stacks (Itanium). + static bool register_stack_overflow() { return false; } + static void enable_register_stack_guard() {} + static void disable_register_stack_guard() {} + +#endif // OS_CPU_BSD_AARCH64_VM_THREAD_BSD_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/vmStructs_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/vmStructs_bsd_aarch64.hpp new file mode 100644 index 0000000..9d7651e --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/vmStructs_bsd_aarch64.hpp
@@ -0,0 +1,54 @@ +/* + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_AARCH64_VM_VMSTRUCTS_BSD_AARCH64_HPP +#define OS_CPU_BSD_AARCH64_VM_VMSTRUCTS_BSD_AARCH64_HPP + +// These are the OS and CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ + \ + /******************************/ \ + /* Threads (NOTE: incomplete) */ \ + /******************************/ \ + nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ + nonstatic_field(OSThread, _unique_thread_id, uint64_t) + + +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ + \ + /**********************/ \ + /* Thread IDs */ \ + /**********************/ \ + \ + declare_unsigned_integer_type(OSThread::thread_id_t) + +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#endif // OS_CPU_BSD_AARCH64_VM_VMSTRUCTS_BSD_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp new file mode 100644 index 0000000..19df1ea --- /dev/null +++ b/src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
@@ -0,0 +1,89 @@ +/* + * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/java.hpp" +#include "runtime/os.hpp" +#include "runtime/vm_version.hpp" +#include <sys/sysctl.h> + +static bool cpu_has(const char* optional) { + uint32_t val; + size_t len = sizeof(val); + if (sysctlbyname(optional, &val, &len, NULL, 0)) { + return false; + } + return val; +} + +void VM_Version::get_os_cpu_info() { + size_t sysctllen; + + // hw.optional.floatingpoint always returns 1, see + // https://github.com/apple/darwin-xnu/blob/master/bsd/kern/kern_mib.c#L416. + // ID_AA64PFR0_EL1 describes AdvSIMD always equals to FP field. + assert(cpu_has("hw.optional.floatingpoint"), "should be"); + assert(cpu_has("hw.optional.neon"), "should be"); + _features = CPU_FP | CPU_ASIMD; + + // Only few features are available via sysctl, see line 614 + // https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/kern/kern_mib.c.auto.html + if (cpu_has("hw.optional.armv8_crc32")) _features |= CPU_CRC32; + if (cpu_has("hw.optional.armv8_1_atomics")) _features |= CPU_LSE; + + int cache_line_size; + int hw_conf_cache_line[] = { CTL_HW, HW_CACHELINE }; + sysctllen = sizeof(cache_line_size); + if (sysctl(hw_conf_cache_line, 2, &cache_line_size, &sysctllen, NULL, 0)) { + cache_line_size = 16; + } + _icache_line_size = 16; // minimal line lenght CCSIDR_EL1 can hold + _dcache_line_size = cache_line_size; + + uint64_t dczid_el0; + __asm__ ( + "mrs %0, DCZID_EL0\n" + : "=r"(dczid_el0) + ); + if (!(dczid_el0 & 0x10)) { + _zva_length = 4 << (dczid_el0 & 0xf); + } + int family; + sysctllen = sizeof(family); + if (sysctlbyname("hw.cpufamily", &family, &sysctllen, NULL, 0)) { + family = 0; + } + _model = family; + _cpu = CPU_APPLE; +} + +#ifdef __APPLE__ + +bool VM_Version::is_cpu_emulated() { + return false; +} + +#endif \ No newline at end of file
diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp index f116a44..65c8f5b 100644 --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp
@@ -278,11 +278,11 @@ address os::current_stack_pointer() { #if defined(__clang__) || defined(__llvm__) - register void *esp; + void *esp; __asm__("mov %%" SPELL_REG_SP ", %0":"=r"(esp)); return (address) esp; #elif defined(SPARC_WORKS) - register void *esp; + void *esp; __asm__("mov %%" SPELL_REG_SP ", %0":"=r"(esp)); return (address) ((char*)esp + sizeof(long)*2); #else @@ -410,7 +410,7 @@ intptr_t* _get_previous_fp() { #if defined(SPARC_WORKS) || defined(__clang__) || defined(__llvm__) - register intptr_t **ebp; + intptr_t **ebp; __asm__("mov %%" SPELL_REG_FP ", %0":"=r"(ebp)); #else register intptr_t **ebp __asm__ (SPELL_REG_FP); @@ -633,7 +633,7 @@ int op = pc[0]; if (op == 0xDB) { // FIST - // TODO: The encoding of D2I in i486.ad can cause an exception + // TODO: The encoding of D2I in x86_32.ad can cause an exception // prior to the fist instruction if there was an invalid operation // pending. We want to dismiss that exception. From the win_32 // side it also seems that if it really was the fist causing
diff --git a/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp new file mode 100644 index 0000000..3722195 --- /dev/null +++ b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp
@@ -0,0 +1,44 @@ +/* + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP +#define OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. + +class ICache : public AbstractICache { + public: + static void initialize(); + static void invalidate_word(address addr) { + __builtin___clear_cache((char *)addr, (char *)(addr + 4)); + } + static void invalidate_range(address start, int nbytes) { + __builtin___clear_cache((char *)start, (char *)(start + nbytes)); + } +}; + +#endif // OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP \ No newline at end of file
diff --git a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.hpp index a2261b1..985b664 100644 --- a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.hpp +++ b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.hpp
@@ -27,15 +27,6 @@ #define OS_CPU_LINUX_AARCH64_VM_THREAD_LINUX_AARCH64_HPP private: -#ifdef ASSERT - // spill stack holds N callee-save registers at each Java call and - // grows downwards towards limit - // we need limit to check we have space for a spill and base so we - // can identify all live spill frames at GC (eventually) - address _spill_stack; - address _spill_stack_base; - address _spill_stack_limit; -#endif // ASSERT void pd_initialize() { _anchor.clear();
diff --git a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp index e4ae30c..5d943ff 100644 --- a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp
@@ -27,3 +27,91 @@ #include "runtime/os.hpp" #include "runtime/vm_version.hpp" +#include <asm/hwcap.h> +#include <sys/auxv.h> +#include <sys/prctl.h> + +#ifndef HWCAP_AES +#define HWCAP_AES (1<<3) +#endif + +#ifndef HWCAP_PMULL +#define HWCAP_PMULL (1<<4) +#endif + +#ifndef HWCAP_SHA1 +#define HWCAP_SHA1 (1<<5) +#endif + +#ifndef HWCAP_SHA2 +#define HWCAP_SHA2 (1<<6) +#endif + +#ifndef HWCAP_CRC32 +#define HWCAP_CRC32 (1<<7) +#endif + +#ifndef HWCAP_ATOMICS +#define HWCAP_ATOMICS (1<<8) +#endif + +void VM_Version::get_os_cpu_info() { + + uint64_t auxv = getauxval(AT_HWCAP); + + STATIC_ASSERT(CPU_FP == HWCAP_FP); + STATIC_ASSERT(CPU_ASIMD == HWCAP_ASIMD); + STATIC_ASSERT(CPU_EVTSTRM == HWCAP_EVTSTRM); + STATIC_ASSERT(CPU_AES == HWCAP_AES); + STATIC_ASSERT(CPU_PMULL == HWCAP_PMULL); + STATIC_ASSERT(CPU_SHA1 == HWCAP_SHA1); + STATIC_ASSERT(CPU_SHA2 == HWCAP_SHA2); + STATIC_ASSERT(CPU_CRC32 == HWCAP_CRC32); + STATIC_ASSERT(CPU_LSE == HWCAP_ATOMICS); + _features = auxv & ( + HWCAP_FP | + HWCAP_ASIMD | + HWCAP_EVTSTRM | + HWCAP_AES | + HWCAP_PMULL | + HWCAP_SHA1 | + HWCAP_SHA2 | + HWCAP_CRC32 | + HWCAP_ATOMICS); + + uint64_t ctr_el0; + uint64_t dczid_el0; + __asm__ ( + "mrs %0, CTR_EL0\n" + "mrs %1, DCZID_EL0\n" + : "=r"(ctr_el0), "=r"(dczid_el0) + ); + + _icache_line_size = (1 << (ctr_el0 & 0x0f)) * 4; + _dcache_line_size = (1 << ((ctr_el0 >> 16) & 0x0f)) * 4; + + if (!(dczid_el0 & 0x10)) { + _zva_length = 4 << (dczid_el0 & 0xf); + } + + if (FILE *f = fopen("/proc/cpuinfo", "r")) { + // need a large buffer as the flags line may include lots of text + char buf[1024], *p; + while (fgets(buf, sizeof (buf), f) != NULL) { + if ((p = strchr(buf, ':')) != NULL) { + long v = strtol(p+1, NULL, 0); + if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) { + _cpu = v; + } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) { + _variant = v; + } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) { + if (_model != v) _model2 = _model; + _model = v; + } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) { + _revision = v; + } + } + } + fclose(f); + } +}
diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp index c8c1cae..72df928 100644 --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
@@ -259,9 +259,11 @@ #ifndef AARCH64 extern "C" address check_vfp_fault_instr; extern "C" address check_vfp3_32_fault_instr; +extern "C" address check_mp_ext_fault_instr; address check_vfp_fault_instr = NULL; address check_vfp3_32_fault_instr = NULL; +address check_mp_ext_fault_instr = NULL; #endif // !AARCH64 extern "C" address check_simd_fault_instr; address check_simd_fault_instr = NULL; @@ -283,7 +285,8 @@ if (sig == SIGILL && ((info->si_addr == (caddr_t)check_simd_fault_instr) NOT_AARCH64(|| info->si_addr == (caddr_t)check_vfp_fault_instr) - NOT_AARCH64(|| info->si_addr == (caddr_t)check_vfp3_32_fault_instr))) { + NOT_AARCH64(|| info->si_addr == (caddr_t)check_vfp3_32_fault_instr) + NOT_AARCH64(|| info->si_addr == (caddr_t)check_mp_ext_fault_instr))) { // skip faulty instruction + instruction that sets return value to // success and set return value to failure. os::Linux::ucontext_set_pc(uc, (address)info->si_addr + 8);
diff --git a/src/hotspot/os_cpu/linux_ppc/orderAccess_linux_ppc.hpp b/src/hotspot/os_cpu/linux_ppc/orderAccess_linux_ppc.hpp index 92ce826..a57a115 100644 --- a/src/hotspot/os_cpu/linux_ppc/orderAccess_linux_ppc.hpp +++ b/src/hotspot/os_cpu/linux_ppc/orderAccess_linux_ppc.hpp
@@ -85,7 +85,7 @@ struct OrderAccess::PlatformOrderedLoad<byte_size, X_ACQUIRE> { template <typename T> - T operator()(const volatile T* p) const { register T t = Atomic::load(p); inlasm_acquire_reg(t); return t; } + T operator()(const volatile T* p) const { T t = Atomic::load(p); inlasm_acquire_reg(t); return t; } }; #undef inlasm_sync
diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp index a23f55e..3630d10 100644 --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp
@@ -172,7 +172,9 @@ // method returns the Java sender of the current frame. *fr = os::fetch_frame_from_context(uc); if (!fr->is_first_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. *fr = fr->java_sender(); } } else { @@ -189,7 +191,7 @@ address lr = ucontext_get_lr(uc); *fr = frame(sp, lr); if (!fr->is_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // See java_sender() comment above. assert(!fr->is_first_frame(), "Safety check"); *fr = fr->java_sender(); } @@ -229,6 +231,10 @@ Thread* t = Thread::current_or_null_safe(); + // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away + // (no destructors can be run) + os::ThreadCrashProtection::check_crash_protection(sig, t); + SignalHandlerMark shm(t); // Note: it's not uncommon that JNI code uses signal/sigset to install
diff --git a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp index 3f49fed..86fd382 100644 --- a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp
@@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2019 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 SAP SE. 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 @@ -34,6 +34,8 @@ address pc = _anchor.last_Java_pc(); // Last_Java_pc ist not set, if we come here from compiled code. + // Assume spill slot for link register contains a suitable pc. + // Should have been filled by method entry code. if (pc == NULL) { pc = (address) *(sp + 2); } @@ -56,14 +58,26 @@ // if we were running Java code when SIGPROF came in. if (isInJava) { ucontext_t* uc = (ucontext_t*) ucontext; - frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], - (address)uc->uc_mcontext.regs->nip); + address pc = (address)uc->uc_mcontext.regs->nip; - if (ret_frame.pc() == NULL) { + if (pc == NULL) { // ucontext wasn't useful return false; } + frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], pc); + + if (ret_frame.fp() == NULL) { + // The found frame does not have a valid frame pointer. + // Bail out because this will create big trouble later on, either + // - when using istate, calculated as (NULL - ijava_state_size) or + // - when using fp() directly in safe_for_sender() + // + // There is no conclusive description (yet) how this could happen, but it does. + // For more details on what was observed, see thread_linux_s390.cpp + return false; + } + if (ret_frame.is_interpreted_frame()) { frame::ijava_state *istate = ret_frame.get_ijava_state(); const Method *m = (const Method*)(istate->method);
diff --git a/src/hotspot/os_cpu/linux_s390/orderAccess_linux_s390.hpp b/src/hotspot/os_cpu/linux_s390/orderAccess_linux_s390.hpp index 3a528f6..50f2a02 100644 --- a/src/hotspot/os_cpu/linux_s390/orderAccess_linux_s390.hpp +++ b/src/hotspot/os_cpu/linux_s390/orderAccess_linux_s390.hpp
@@ -79,7 +79,7 @@ struct OrderAccess::PlatformOrderedLoad<byte_size, X_ACQUIRE> { template <typename T> - T operator()(const volatile T* p) const { register T t = *p; inlasm_zarch_acquire(); return t; } + T operator()(const volatile T* p) const { T t = *p; inlasm_zarch_acquire(); return t; } }; #undef inlasm_compiler_barrier
diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp index 5de0c21..01a49fa 100644 --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp
@@ -154,7 +154,9 @@ // method returns the Java sender of the current frame. *fr = os::fetch_frame_from_context(uc); if (!fr->is_first_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. *fr = fr->java_sender(); } } else { @@ -171,7 +173,7 @@ address lr = ucontext_get_lr(uc); *fr = frame(sp, lr); if (!fr->is_java_frame()) { - assert(fr->safe_for_sender(thread), "Safety check"); + // See java_sender() comment above. assert(!fr->is_first_frame(), "Safety check"); *fr = fr->java_sender(); }
diff --git a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp index c6b183f..1d7fdaf 100644 --- a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp
@@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019 SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 SAP SE. 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 @@ -34,6 +34,8 @@ address pc = _anchor.last_Java_pc(); // Last_Java_pc ist not set if we come here from compiled code. + // Assume spill slot for Z_R14 (return register) contains a suitable pc. + // Should have been filled by method entry code. if (pc == NULL) { pc = (address) *(sp + 14); } @@ -51,19 +53,55 @@ return true; } + // At this point, we don't have a last_Java_frame, so + // we try to glean some information out of the ucontext + // if we were running Java code when SIGPROF came in. if (isInJava) { ucontext_t* uc = (ucontext_t*) ucontext; - frame ret_frame((intptr_t*)uc->uc_mcontext.gregs[15/*Z_SP*/], - (address)uc->uc_mcontext.psw.addr); + address pc = (address)uc->uc_mcontext.psw.addr; - if (ret_frame.pc() == NULL) { + if (pc == NULL) { // ucontext wasn't useful return false; } + frame ret_frame((intptr_t*)uc->uc_mcontext.gregs[15/*Z_SP*/], pc); + + if (ret_frame.fp() == NULL) { + // The found frame does not have a valid frame pointer. + // Bail out because this will create big trouble later on, either + // - when using istate, calculated as (NULL - z_ijava_state_size (= 0x70 (dbg) or 0x68 (rel)) or + // - when using fp() directly in safe_for_sender() + // + // There is no conclusive description (yet) how this could happen, but it does: + // + // We observed a SIGSEGV with the following stack trace (openjdk.jdk11u-dev, 2021-07-07, linuxs390x fastdebug) + // V [libjvm.so+0x12c8f12] JavaThread::pd_get_top_frame_for_profiling(frame*, void*, bool)+0x142 + // V [libjvm.so+0xb1020c] JfrGetCallTrace::get_topframe(void*, frame&)+0x3c + // V [libjvm.so+0xba0b08] OSThreadSampler::protected_task(os::SuspendedThreadTaskContext const&)+0x98 + // V [libjvm.so+0xff33c4] os::SuspendedThreadTask::internal_do_task()+0x14c + // V [libjvm.so+0xfe3c9c] os::SuspendedThreadTask::run()+0x24 + // V [libjvm.so+0xba0c66] JfrThreadSampleClosure::sample_thread_in_java(JavaThread*, JfrStackFrame*, unsigned int)+0x66 + // V [libjvm.so+0xba1718] JfrThreadSampleClosure::do_sample_thread(JavaThread*, JfrStackFrame*, unsigned int, JfrSampleType)+0x278 + // V [libjvm.so+0xba4f54] JfrThreadSampler::task_stacktrace(JfrSampleType, JavaThread**) [clone .constprop.62]+0x284 + // V [libjvm.so+0xba5e54] JfrThreadSampler::run()+0x2ec + // V [libjvm.so+0x12adc9c] Thread::call_run()+0x9c + // V [libjvm.so+0xff5ab0] thread_native_entry(Thread*)+0x128 + // siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0xfffffffffffff000 + // failing instruction: e320 6008 0004 LG r2,8(r0,r6) + // contents of r6: 0xffffffffffffff90 + // + // Here is the sequence of what happens: + // - ret_frame is constructed with _fp == NULL (for whatever reason) + // - ijava_state_unchecked() calculates it's result as + // istate = fp() - z_ijava_state_size() = NULL - 0x68 DEBUG_ONLY(-8) + // - istate->method dereferences memory at offset 8 from istate + return false; + } + if (ret_frame.is_interpreted_frame()) { frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked(); - if (stack_base() >= (address)istate && (address)istate > stack_end()) { + if (!(stack_base() >= (address)istate && (address)istate > stack_end())) { return false; } const Method *m = (const Method*)(istate->method);
diff --git a/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp b/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp index 4d5069e..8e47c7e 100644 --- a/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp +++ b/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp
@@ -34,7 +34,13 @@ define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 1024); #else -define_pd_global(intx, CompilerThreadStackSize, 512); +// Some tests in debug VM mode run out of compile thread stack. +// Observed on some x86_32 VarHandles tests during escape analysis. +#ifdef ASSERT +define_pd_global(intx, CompilerThreadStackSize, 768); +#else +define_pd_global(intx, CompilerThreadStackSize, 512); +#endif // ThreadStackSize 320 allows a couple of test cases to run while // keeping the number of threads that can be created high. System // default ThreadStackSize appears to be 512 which is too big.
diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp index c97d918..d475f85 100644 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
@@ -95,16 +95,11 @@ address os::current_stack_pointer() { #ifdef SPARC_WORKS - register void *esp; + void *esp; __asm__("mov %%" SPELL_REG_SP ", %0":"=r"(esp)); return (address) ((char*)esp + sizeof(long)*2); -#elif defined(__clang__) - intptr_t* esp; - __asm__ __volatile__ ("mov %%" SPELL_REG_SP ", %0":"=r"(esp):); - return (address) esp; #else - register void *esp __asm__ (SPELL_REG_SP); - return (address) esp; + return (address)__builtin_frame_address(0); #endif } @@ -229,7 +224,7 @@ intptr_t* _get_previous_fp() { #ifdef SPARC_WORKS - register intptr_t **ebp; + intptr_t **ebp; __asm__("mov %%" SPELL_REG_FP ", %0":"=r"(ebp)); #elif defined(__clang__) intptr_t **ebp; @@ -463,7 +458,7 @@ int op = pc[0]; if (op == 0xDB) { // FIST - // TODO: The encoding of D2I in i486.ad can cause an exception + // TODO: The encoding of D2I in x86_32.ad can cause an exception // prior to the fist instruction if there was an invalid operation // pending. We want to dismiss that exception. From the win_32 // side it also seems that if it really was the fist causing
diff --git a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp index 9fa5a40..e0539e1 100644 --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp
@@ -317,6 +317,20 @@ } static void current_stack_region(address *bottom, size_t *size) { + if (os::is_primordial_thread()) { + // primordial thread needs special handling because pthread_getattr_np() + // may return bogus value. + address stack_bottom = os::Linux::initial_thread_stack_bottom(); + size_t stack_bytes = os::Linux::initial_thread_stack_size(); + + assert(os::current_stack_pointer() >= stack_bottom, "should do"); + assert(os::current_stack_pointer() < stack_bottom + stack_bytes, "should do"); + + *bottom = stack_bottom; + *size = stack_bytes; + return; + } + pthread_attr_t attr; int res = pthread_getattr_np(pthread_self(), &attr); if (res != 0) { @@ -365,18 +379,6 @@ pthread_attr_destroy(&attr); - // The initial thread has a growable stack, and the size reported - // by pthread_attr_getstack is the maximum size it could possibly - // be given what currently mapped. This can be huge, so we cap it. - if (os::is_primordial_thread()) { - stack_bytes = stack_top - stack_bottom; - - if (stack_bytes > JavaThread::stack_size_at_create()) - stack_bytes = JavaThread::stack_size_at_create(); - - stack_bottom = stack_top - stack_bytes; - } - assert(os::current_stack_pointer() >= stack_bottom, "should do"); assert(os::current_stack_pointer() < stack_top, "should do");
diff --git a/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp new file mode 100644 index 0000000..965613f --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp
@@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// nothing required here +#include "precompiled.hpp"
diff --git a/src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp new file mode 100644 index 0000000..04ca9a9 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp
@@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP + +#include <intrin.h> +#include "runtime/os.hpp" +#include "runtime/vm_version.hpp" + + +// As per atomic.hpp all read-modify-write operations have to provide two-way +// barriers semantics. The memory_order parameter is ignored - we always provide +// the strongest/most-conservative ordering +// +// For AARCH64 we add explicit barriers in the stubs. + +template<size_t byte_size> +struct Atomic::PlatformAdd + : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> > +{ + template<typename I, typename D> + D add_and_fetch(I add_value, D volatile* dest, atomic_memory_order order) const; +}; + +// The Interlocked* APIs only take long and will not accept __int32. That is +// acceptable on Windows, since long is a 32-bits integer type. + +#define DEFINE_INTRINSIC_ADD(IntrinsicName, IntrinsicType) \ + template<> \ + template<typename I, typename D> \ + inline D Atomic::PlatformAdd<sizeof(IntrinsicType)>::add_and_fetch(I add_value, \ + D volatile* dest, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(D)); \ + return PrimitiveConversions::cast<D>( \ + IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \ + PrimitiveConversions::cast<IntrinsicType>(add_value))); \ + } + +DEFINE_INTRINSIC_ADD(InterlockedAdd, long) +DEFINE_INTRINSIC_ADD(InterlockedAdd64, __int64) + +#undef DEFINE_INTRINSIC_ADD + +#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \ + template<> \ + template<typename T> \ + inline T Atomic::PlatformXchg<sizeof(IntrinsicType)>::operator()(T exchange_value, \ + T volatile* dest, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \ + return PrimitiveConversions::cast<T>( \ + IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \ + PrimitiveConversions::cast<IntrinsicType>(exchange_value))); \ + } + +DEFINE_INTRINSIC_XCHG(InterlockedExchange, long) +DEFINE_INTRINSIC_XCHG(InterlockedExchange64, __int64) + +#undef DEFINE_INTRINSIC_XCHG + +// Note: the order of the parameters is different between +// Atomic::PlatformCmpxchg<*>::operator() and the +// InterlockedCompareExchange* API. + +#define DEFINE_INTRINSIC_CMPXCHG(IntrinsicName, IntrinsicType) \ + template<> \ + template<typename T> \ + inline T Atomic::PlatformCmpxchg<sizeof(IntrinsicType)>::operator()(T exchange_value, \ + T volatile* dest, \ + T compare_value, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \ + return PrimitiveConversions::cast<T>( \ + IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \ + PrimitiveConversions::cast<IntrinsicType>(exchange_value), \ + PrimitiveConversions::cast<IntrinsicType>(compare_value))); \ + } + +DEFINE_INTRINSIC_CMPXCHG(_InterlockedCompareExchange8, char) // Use the intrinsic as InterlockedCompareExchange8 does not exist +DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange, long) +DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange64, __int64) + +#undef DEFINE_INTRINSIC_CMPXCHG + +#endif // OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp new file mode 100644 index 0000000..35389c9 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp
@@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP + +#include <stdlib.h> + +// Efficient swapping of data bytes from Java byte +// ordering to native byte ordering and vice versa. +inline u2 Bytes::swap_u2(u2 x) { + return _byteswap_ushort(x); +} + +inline u4 Bytes::swap_u4(u4 x) { + return _byteswap_ulong(x); +} + +inline u8 Bytes::swap_u8(u8 x) { + return _byteswap_uint64(x); +} + +#endif // OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.inline.hpp new file mode 100644 index 0000000..76cb66f --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.inline.hpp
@@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP + +#include <string.h> + +static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + (void)memcpy(to, from, count * HeapWordSize); + break; + } +} + +static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: while (count-- > 0) { + *to++ = *from++; + } + break; + } +} + +static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + // pd_conjoint_words(from, to, count); + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(const void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { + pd_conjoint_bytes(from, to, count); +} + +static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { + if (from > to) { + while (count-- > 0) { + // Copy forwards + *to++ = *from++; + } + } else { + from += count - 1; + to += count - 1; + while (count-- > 0) { + // Copy backwards + *to-- = *from--; + } + } +} + +static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { + if (from > to) { + while (count-- > 0) { + // Copy forwards + *to++ = *from++; + } + } else { + from += count - 1; + to += count - 1; + while (count-- > 0) { + // Copy backwards + *to-- = *from--; + } + } +} + +static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { + pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); +} + +static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { + if (from > to) { + while (count-- > 0) { + // Copy forwards + *to++ = *from++; + } + } else { + from += count - 1; + to += count - 1; + while (count-- > 0) { + // Copy backwards + *to-- = *from--; + } + } +} + +static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_bytes_atomic(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count); +} + +static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count); +} + +static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); +} + +static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); +} + +#endif // OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp new file mode 100644 index 0000000..836fb46 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp
@@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP + +// Sets the default values for platform dependent flags used by the runtime system. +// (see globals.hpp) + +define_pd_global(bool, DontYieldALot, false); + +// Default stack size on Windows is determined by the executable (java.exe +// has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing +// ThreadStackSize to non-zero may have significant impact on memory usage. +// See comments in os_windows.cpp. +define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default +define_pd_global(intx, VMThreadStackSize, 0); + +#ifdef ASSERT +define_pd_global(intx, CompilerThreadStackSize, 1024); +#else +define_pd_global(intx, CompilerThreadStackSize, 0); +#endif + +define_pd_global(uintx,JVMInvokeMethodSlack, 8192); + +// Used on 64 bit platforms for UseCompressedOops base address +define_pd_global(uintx,HeapBaseMinAddress, 2*G); +#endif // OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/icache_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/icache_windows_aarch64.hpp new file mode 100644 index 0000000..bf36b77 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/icache_windows_aarch64.hpp
@@ -0,0 +1,44 @@ +/* + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. + +class ICache : public AbstractICache { + public: + static void initialize(); + static void invalidate_word(address addr) { + invalidate_range(addr, 4); + } + static void invalidate_range(address start, int nbytes) { + FlushInstructionCache((HANDLE)GetCurrentProcess(), start, (SIZE_T)(nbytes)); + } +}; + +#endif // OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp new file mode 100644 index 0000000..1018860 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp
@@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP + +// Included in orderAccess.hpp header file. +#include <atomic> +using std::atomic_thread_fence; +#include <intrin.h> +#include "vm_version_aarch64.hpp" +#include "runtime/vm_version.hpp" + +// Implementation of class OrderAccess. + +inline void OrderAccess::loadload() { acquire(); } +inline void OrderAccess::storestore() { release(); } +inline void OrderAccess::loadstore() { acquire(); } +inline void OrderAccess::storeload() { fence(); } + +#define READ_MEM_BARRIER atomic_thread_fence(std::memory_order_acquire); +#define WRITE_MEM_BARRIER atomic_thread_fence(std::memory_order_release); +#define FULL_MEM_BARRIER atomic_thread_fence(std::memory_order_seq_cst); + +inline void OrderAccess::acquire() { + READ_MEM_BARRIER; +} + +inline void OrderAccess::release() { + WRITE_MEM_BARRIER; +} + +inline void OrderAccess::fence() { + FULL_MEM_BARRIER; +} + +#endif // OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp new file mode 100644 index 0000000..6f50e42 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp
@@ -0,0 +1,312 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "jvm.h" +#include "asm/macroAssembler.hpp" +#include "classfile/classLoader.hpp" +#include "classfile/systemDictionary.hpp" +#include "classfile/vmSymbols.hpp" +#include "code/codeCache.hpp" +#include "code/icBuffer.hpp" +#include "code/vtableStubs.hpp" +#include "code/nativeInst.hpp" +#include "interpreter/interpreter.hpp" +#include "memory/allocation.inline.hpp" +#include "prims/jniFastGetField.hpp" +#include "prims/jvm_misc.hpp" +#include "runtime/arguments.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "runtime/java.hpp" +#include "runtime/javaCalls.hpp" +#include "runtime/mutexLocker.hpp" +#include "runtime/osThread.hpp" +#include "runtime/sharedRuntime.hpp" +#include "runtime/stubRoutines.hpp" +#include "runtime/thread.inline.hpp" +#include "runtime/timer.hpp" +#include "unwind_windows_aarch64.hpp" +#include "utilities/debug.hpp" +#include "utilities/events.hpp" +#include "utilities/vmError.hpp" + + +// put OS-includes here +# include <sys/types.h> +# include <signal.h> +# include <errno.h> +# include <stdlib.h> +# include <stdio.h> +# include <intrin.h> + +void os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread) { + f(value, method, args, thread); +} + +#pragma warning(disable: 4172) + +// Returns an estimate of the current stack pointer. Result must be guaranteed +// to point into the calling threads stack, and be no lower than the current +// stack pointer. +address os::current_stack_pointer() { + int dummy; + address sp = (address)&dummy; + return sp; +} + +#pragma warning(default: 4172) + +ExtendedPC os::fetch_frame_from_context(const void* ucVoid, + intptr_t** ret_sp, intptr_t** ret_fp) { + ExtendedPC epc; + CONTEXT* uc = (CONTEXT*)ucVoid; + + if (uc != NULL) { + epc = ExtendedPC((address)uc->Pc); + if (ret_sp) *ret_sp = (intptr_t*)uc->Sp; + if (ret_fp) *ret_fp = (intptr_t*)uc->Fp; + } else { + // construct empty ExtendedPC for return value checking + epc = NULL; + if (ret_sp) *ret_sp = (intptr_t *)NULL; + if (ret_fp) *ret_fp = (intptr_t *)NULL; + } + return epc; +} + +frame os::fetch_frame_from_context(const void* ucVoid) { + intptr_t* sp; + intptr_t* fp; + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); + return frame(sp, fp, epc.pc()); +} + +bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, + struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) { + PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; + address addr = (address) exceptionRecord->ExceptionInformation[1]; + if (Interpreter::contains(pc)) { + *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); + if (!fr->is_first_java_frame()) { + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. + *fr = fr->java_sender(); + } + } else { + // more complex code with compiled code + assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { + // Not sure where the pc points to, fallback to default + // stack overflow handling + return false; + } else { + // In compiled code, the stack banging is performed before LR + // has been saved in the frame. LR is live, and SP and FP + // belong to the caller. + intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->Fp; + intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->Sp; + address pc = (address)(exceptionInfo->ContextRecord->Lr + - NativeInstruction::instruction_size); + *fr = frame(sp, fp, pc); + if (!fr->is_java_frame()) { + assert(fr->safe_for_sender(thread), "Safety check"); + assert(!fr->is_first_frame(), "Safety check"); + *fr = fr->java_sender(); + } + } + } + assert(fr->is_java_frame(), "Safety check"); + return true; +} + +// By default, gcc always saves frame pointer rfp on this stack. This +// may get turned off by -fomit-frame-pointer. +frame os::get_sender_for_C_frame(frame* fr) { + return frame(fr->link(), fr->link(), fr->sender_pc()); +} + +frame os::current_frame() { + typedef intptr_t* get_fp_func (); + get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*, + StubRoutines::aarch64::get_previous_fp_entry()); + if (func == NULL) return frame(); + intptr_t* fp = (*func)(); + if (fp == NULL) { + return frame(); + } + + frame myframe((intptr_t*)os::current_stack_pointer(), + (intptr_t*)fp, + CAST_FROM_FN_PTR(address, os::current_frame)); + if (os::is_first_C_frame(&myframe)) { + + // stack is not walkable + return frame(); + } else { + return os::get_sender_for_C_frame(&myframe); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// thread stack + +// Minimum usable stack sizes required to get to user code. Space for +// HotSpot guard pages is added later. + +///////////////////////////////////////////////////////////////////////////// +// helper functions for fatal error handler + +void os::print_context(outputStream *st, const void *context) { + if (context == NULL) return; + + const CONTEXT* uc = (const CONTEXT*)context; + + st->print_cr("Registers:"); + + st->print( "X0 =" INTPTR_FORMAT, uc->X0); + st->print(", X1 =" INTPTR_FORMAT, uc->X1); + st->print(", X2 =" INTPTR_FORMAT, uc->X2); + st->print(", X3 =" INTPTR_FORMAT, uc->X3); + st->cr(); + st->print( "X4 =" INTPTR_FORMAT, uc->X4); + st->print(", X5 =" INTPTR_FORMAT, uc->X5); + st->print(", X6 =" INTPTR_FORMAT, uc->X6); + st->print(", X7 =" INTPTR_FORMAT, uc->X7); + st->cr(); + st->print( "X8 =" INTPTR_FORMAT, uc->X8); + st->print(", X9 =" INTPTR_FORMAT, uc->X9); + st->print(", X10=" INTPTR_FORMAT, uc->X10); + st->print(", X11=" INTPTR_FORMAT, uc->X11); + st->cr(); + st->print( "X12=" INTPTR_FORMAT, uc->X12); + st->print(", X13=" INTPTR_FORMAT, uc->X13); + st->print(", X14=" INTPTR_FORMAT, uc->X14); + st->print(", X15=" INTPTR_FORMAT, uc->X15); + st->cr(); + st->print( "X16=" INTPTR_FORMAT, uc->X16); + st->print(", X17=" INTPTR_FORMAT, uc->X17); + st->print(", X18=" INTPTR_FORMAT, uc->X18); + st->print(", X19=" INTPTR_FORMAT, uc->X19); + st->cr(); + st->print(", X20=" INTPTR_FORMAT, uc->X20); + st->print(", X21=" INTPTR_FORMAT, uc->X21); + st->print(", X22=" INTPTR_FORMAT, uc->X22); + st->print(", X23=" INTPTR_FORMAT, uc->X23); + st->cr(); + st->print(", X24=" INTPTR_FORMAT, uc->X24); + st->print(", X25=" INTPTR_FORMAT, uc->X25); + st->print(", X26=" INTPTR_FORMAT, uc->X26); + st->print(", X27=" INTPTR_FORMAT, uc->X27); + st->print(", X28=" INTPTR_FORMAT, uc->X28); + st->cr(); + st->cr(); + + intptr_t *sp = (intptr_t *)uc->Sp; + st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); + print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t)); + st->cr(); + + // Note: it may be unsafe to inspect memory near pc. For example, pc may + // point to garbage if entry point in an nmethod is corrupted. Leave + // this at the end, and hope for the best. + address pc = (address)uc->Pc; + st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); + print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); + st->cr(); + +} + +void os::print_register_info(outputStream *st, const void *context) { + if (context == NULL) return; + + const CONTEXT* uc = (const CONTEXT*)context; + + st->print_cr("Register to memory mapping:"); + st->cr(); + // this is only for the "general purpose" registers + st->print(" X0="); print_location(st, uc->X0); + st->print(" X1="); print_location(st, uc->X1); + st->print(" X2="); print_location(st, uc->X2); + st->print(" X3="); print_location(st, uc->X3); + st->cr(); + st->print(" X4="); print_location(st, uc->X4); + st->print(" X5="); print_location(st, uc->X5); + st->print(" X6="); print_location(st, uc->X6); + st->print(" X7="); print_location(st, uc->X7); + st->cr(); + st->print(" X8="); print_location(st, uc->X8); + st->print(" X9="); print_location(st, uc->X9); + st->print("X10="); print_location(st, uc->X10); + st->print("X11="); print_location(st, uc->X11); + st->cr(); + st->print("X12="); print_location(st, uc->X12); + st->print("X13="); print_location(st, uc->X13); + st->print("X14="); print_location(st, uc->X14); + st->print("X15="); print_location(st, uc->X15); + st->cr(); + st->print("X16="); print_location(st, uc->X16); + st->print("X17="); print_location(st, uc->X17); + st->print("X18="); print_location(st, uc->X18); + st->print("X19="); print_location(st, uc->X19); + st->cr(); + st->print("X20="); print_location(st, uc->X20); + st->print("X21="); print_location(st, uc->X21); + st->print("X22="); print_location(st, uc->X22); + st->print("X23="); print_location(st, uc->X23); + st->cr(); + st->print("X24="); print_location(st, uc->X24); + st->print("X25="); print_location(st, uc->X25); + st->print("X26="); print_location(st, uc->X26); + st->print("X27="); print_location(st, uc->X27); + st->print("X28="); print_location(st, uc->X28); + + st->cr(); +} + +void os::setup_fpu() { +} + +bool os::supports_sse() { + return true; +} + +#ifndef PRODUCT +void os::verify_stack_alignment() { + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +} +#endif + +int os::extra_bang_size_in_bytes() { + // AArch64 does not require the additional stack bang. + return 0; +} + +extern "C" { + int SpinPause() { + return 0; + } +};
diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp new file mode 100644 index 0000000..fedf584 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp
@@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP + + static void setup_fpu(); + static bool supports_sse(); + + static bool register_code_area(char *low, char *high) { + // Using Vectored Exception Handling + return true; + } + +#endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp new file mode 100644 index 0000000..673cd3f --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp
@@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP + +#include "runtime/os.hpp" + +#endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/pauth_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/pauth_windows_aarch64.inline.hpp new file mode 100644 index 0000000..844291e --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/pauth_windows_aarch64.inline.hpp
@@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP + +inline address pauth_strip_pointer(address ptr) { + // No PAC support in windows as of yet. + return ptr; +} + +#endif // OS_CPU_WINDOWS_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP +
diff --git a/src/hotspot/os_cpu/windows_aarch64/prefetch_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/prefetch_windows_aarch64.inline.hpp new file mode 100644 index 0000000..d2bd8f1 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/prefetch_windows_aarch64.inline.hpp
@@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP + +#include "runtime/prefetch.hpp" + + +inline void Prefetch::read (void *loc, intx interval) { +} + +inline void Prefetch::write(void *loc, intx interval) { +} + +#endif // OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp new file mode 100644 index 0000000..d235b48 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp
@@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/thread.inline.hpp" + +frame JavaThread::pd_last_frame() { + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); + vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); + return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); +} + +// For Forte Analyzer AsyncGetCallTrace profiling support - thread is +// currently interrupted by SIGPROF +bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, bool isInJava) { + + assert(Thread::current() == this, "caller must be current thread"); + return pd_get_top_frame(fr_addr, ucontext, isInJava); +} + +bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { + return pd_get_top_frame(fr_addr, ucontext, isInJava); +} + +bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) { + + assert(this->is_Java_thread(), "must be JavaThread"); + + JavaThread* jt = (JavaThread *)this; + + // If we have a last_Java_frame, then we should use it even if + // isInJava == true. It should be more reliable than CONTEXT info. + if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { + *fr_addr = jt->pd_last_frame(); + return true; + } + + // At this point, we don't have a last_Java_frame, so + // we try to glean some information out of the CONTEXT + // if we were running Java code when SIGPROF came in. + if (isInJava) { + frame ret_frame = os::fetch_frame_from_context(ucontext); + if (ret_frame.pc() == NULL || ret_frame.sp() == NULL ) { + // CONTEXT wasn't useful + return false; + } + + if (MetaspaceShared::is_in_trampoline_frame(ret_frame.pc())) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } + + if (!ret_frame.safe_for_sender(jt)) { +#if COMPILER2_OR_JVMCI + // C2 and JVMCI use ebp as a general register see if NULL fp helps + frame ret_frame2(ret_frame.sp(), NULL, ret_frame.pc()); + if (!ret_frame2.safe_for_sender(jt)) { + // nothing else to try if the frame isn't good + return false; + } + ret_frame = ret_frame2; +#else + // nothing else to try if the frame isn't good + return false; +#endif // COMPILER2_OR_JVMCI + } + *fr_addr = ret_frame; + return true; + } + + // nothing else to try + return false; +} + +void JavaThread::cache_global_variables() { }
diff --git a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp new file mode 100644 index 0000000..e4caef1 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp
@@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP + + private: + + void pd_initialize() { + _anchor.clear(); + } + + frame pd_last_frame(); + + public: + // Mutators are highly dangerous.... + intptr_t* last_Java_fp() { return _anchor.last_Java_fp(); } + void set_last_Java_fp(intptr_t* fp) { _anchor.set_last_Java_fp(fp); } + + void set_base_of_stack_pointer(intptr_t* base_sp) {} + + static ByteSize last_Java_fp_offset() { + return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset(); + } + + intptr_t* base_of_stack_pointer() { return NULL; } + void record_base_of_stack_pointer() {} + + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, + bool isInJava); + + bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava); +private: + bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava); +public: + + static Thread *aarch64_get_thread_helper() { + return Thread::current(); + } + + public: + // These routines are only used on cpu architectures that + // have separate register stacks (Itanium). + static bool register_stack_overflow() { return false; } + static void enable_register_stack_guard() {} + static void disable_register_stack_guard() {} + +#endif // OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/unwind_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/unwind_windows_aarch64.hpp new file mode 100644 index 0000000..477e0b0 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/unwind_windows_aarch64.hpp
@@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP + + +typedef unsigned char UBYTE; + +#if _MSC_VER < 1700 + +/* Not needed for VS2012 compiler, comes from winnt.h. */ +#define UNW_FLAG_EHANDLER 0x01 +#define UNW_FLAG_UHANDLER 0x02 +#define UNW_FLAG_CHAININFO 0x04 + +#endif + +// See https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling#xdata-records +typedef struct _UNWIND_INFO_EH_ONLY { + DWORD FunctionLength : 18; + DWORD Version : 2; + DWORD X : 1; // = 1 + DWORD E : 1; // = 1 + DWORD EpilogCount : 5; // = 0 + DWORD CodeWords : 5; // = 1 + DWORD UnwindCode0 : 8; + DWORD UnwindCode1 : 8; + DWORD UnwindCode2 : 8; + DWORD UnwindCode3 : 8; + DWORD ExceptionHandler; +} UNWIND_INFO_EH_ONLY, *PUNWIND_INFO_EH_ONLY; + +/* +typedef struct _RUNTIME_FUNCTION { + DWORD BeginAddress; + union { + DWORD UnwindData; + struct { + DWORD Flag : 2; + DWORD FunctionLength : 11; + DWORD RegF : 3; + DWORD RegI : 4; + DWORD H : 1; + DWORD CR : 2; + DWORD FrameSize : 9; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; +} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; +*/ + +#if _MSC_VER < 1700 + +/* Not needed for VS2012 compiler, comes from winnt.h. */ +typedef struct _DISPATCHER_CONTEXT { + ULONG64 ControlPc; + ULONG64 ImageBase; + PRUNTIME_FUNCTION FunctionEntry; + ULONG64 EstablisherFrame; + ULONG64 TargetIp; + PCONTEXT ContextRecord; +// PEXCEPTION_ROUTINE LanguageHandler; + char * LanguageHandler; // double dependency problem + PVOID HandlerData; +} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; + +#endif + +#if _MSC_VER < 1500 + +/* Not needed for VS2008 compiler, comes from winnt.h. */ +typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) ( + IN PEXCEPTION_RECORD ExceptionRecord, + IN ULONG64 EstablisherFrame, + IN OUT PCONTEXT ContextRecord, + IN OUT PDISPATCHER_CONTEXT DispatcherContext +); + +#endif + +#endif // OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/vmStructs_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/vmStructs_windows_aarch64.hpp new file mode 100644 index 0000000..2207878 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/vmStructs_windows_aarch64.hpp
@@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP + +// These are the OS and CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ + \ + /******************************/ \ + /* Threads (NOTE: incomplete) */ \ + /******************************/ \ + \ + nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ + unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ + +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ + \ + declare_unsigned_integer_type(OSThread::thread_id_t) + +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#endif // OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP
diff --git a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp new file mode 100644 index 0000000..5548a31 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp
@@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/os.hpp" +#include "runtime/vm_version.hpp" + +void VM_Version::get_os_cpu_info() { + + if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) _features |= CPU_CRC32; + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) _features |= CPU_AES | CPU_SHA1 | CPU_SHA2; + if (IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE)) _features |= CPU_ASIMD; + // No check for CPU_PMULL + + __int64 dczid_el0 = _ReadStatusReg(0x5807 /* ARM64_DCZID_EL0 */); + + if (!(dczid_el0 & 0x10)) { + _zva_length = 4 << (dczid_el0 & 0xf); + } + + { + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; + DWORD returnLength = 0; + + // See https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation + GetLogicalProcessorInformation(NULL, &returnLength); + assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return from GetLogicalProcessorInformation"); + + buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)os::malloc(returnLength, mtInternal); + BOOL rc = GetLogicalProcessorInformation(buffer, &returnLength); + assert(rc, "Unexpected return from GetLogicalProcessorInformation"); + + _icache_line_size = _dcache_line_size = -1; + for (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer; ptr < buffer + returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ptr++) { + switch (ptr->Relationship) { + case RelationCache: + // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache. + PCACHE_DESCRIPTOR Cache = &ptr->Cache; + if (Cache->Level == 1) { + _icache_line_size = _dcache_line_size = Cache->LineSize; + } + break; + } + } + os::free(buffer); + } + + { + char* buf = ::getenv("PROCESSOR_IDENTIFIER"); + if (buf && strstr(buf, "Ampere(TM)") != NULL) { + _cpu = CPU_AMCC; + } else if (buf && strstr(buf, "Cavium Inc.") != NULL) { + _cpu = CPU_CAVIUM; + } else { + log_info(os)("VM_Version: unknown CPU model"); + } + + if (_cpu) { + SYSTEM_INFO si; + GetSystemInfo(&si); + _model = si.wProcessorLevel; + _variant = si.wProcessorRevision / 0xFF; + _revision = si.wProcessorRevision & 0xFF; + } + } +}
diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp index 7bd2a8b..9504f35 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp
@@ -488,6 +488,41 @@ } #endif +bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, + struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) { + PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; + address addr = (address) exceptionRecord->ExceptionInformation[1]; + if (Interpreter::contains(pc)) { + *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); + if (!fr->is_first_java_frame()) { + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. + *fr = fr->java_sender(); + } + } else { + // more complex code with compiled code + assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { + // Not sure where the pc points to, fallback to default + // stack overflow handling + return false; + } else { + // in compiled code, the stack banging is performed just after the return pc + // has been pushed on the stack + intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->REG_FP; + intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->REG_SP; + *fr = frame(sp + 1, fp, (address)*sp); + if (!fr->is_java_frame()) { + // See java_sender() comment above. + *fr = fr->java_sender(); + } + } + } + assert(fr->is_java_frame(), "Safety check"); + return true; +} #ifndef AMD64 intptr_t* _get_previous_fp() {
diff --git a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp index 69fff03..b2eb108 100644 --- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp
@@ -63,33 +63,22 @@ // we try to glean some information out of the CONTEXT // if we were running Java code when SIGPROF came in. if (isInJava) { - CONTEXT* uc = (CONTEXT*)ucontext; - -#ifdef AMD64 - intptr_t* ret_fp = (intptr_t*) uc->Rbp; - intptr_t* ret_sp = (intptr_t*) uc->Rsp; - ExtendedPC addr = ExtendedPC((address)uc->Rip); -#else - intptr_t* ret_fp = (intptr_t*) uc->Ebp; - intptr_t* ret_sp = (intptr_t*) uc->Esp; - ExtendedPC addr = ExtendedPC((address)uc->Eip); -#endif // AMD64 - if (addr.pc() == NULL || ret_sp == NULL ) { + frame ret_frame = os::fetch_frame_from_context(ucontext); + if (ret_frame.pc() == NULL || ret_frame.sp() == NULL ) { // CONTEXT wasn't useful return false; } - if (MetaspaceShared::is_in_trampoline_frame(addr.pc())) { + if (MetaspaceShared::is_in_trampoline_frame(ret_frame.pc())) { // In the middle of a trampoline call. Bail out for safety. // This happens rarely so shouldn't affect profiling. return false; } - frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { #if COMPILER2_OR_JVMCI // C2 and JVMCI use ebp as a general register see if NULL fp helps - frame ret_frame2(ret_sp, NULL, addr.pc()); + frame ret_frame2(ret_frame.sp(), NULL, ret_frame.pc()); if (!ret_frame2.safe_for_sender(jt)) { // nothing else to try if the frame isn't good return false;
diff --git a/src/hotspot/share/adlc/Test/i486.ad b/src/hotspot/share/adlc/Test/i486.ad deleted file mode 100644 index e69de29..0000000 --- a/src/hotspot/share/adlc/Test/i486.ad +++ /dev/null
diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp index b028b8d..7aceb0e 100644 --- a/src/hotspot/share/adlc/adlparse.cpp +++ b/src/hotspot/share/adlc/adlparse.cpp
@@ -4566,7 +4566,7 @@ // string(still inside the file buffer). Returns a pointer to the string or // NULL if some other token is found instead. char *ADLParser::get_ident_common(bool do_preproc) { - register char c; + char c; char *start; // Pointer to start of token char *end; // Pointer to end of token @@ -4764,7 +4764,7 @@ // invokes a parse_err if the next token is not an integer. // This routine does not leave the integer null-terminated. int ADLParser::get_int(void) { - register char c; + char c; char *start; // Pointer to start of token char *end; // Pointer to end of token int result; // Storage for integer result
diff --git a/src/hotspot/share/adlc/arena.cpp b/src/hotspot/share/adlc/arena.cpp index 140f511..9c8429b 100644 --- a/src/hotspot/share/adlc/arena.cpp +++ b/src/hotspot/share/adlc/arena.cpp
@@ -79,7 +79,7 @@ // Total of all Chunks in arena size_t Arena::used() const { size_t sum = _chunk->_len - (_max-_hwm); // Size leftover in this Chunk - register Chunk *k = _first; + Chunk *k = _first; while( k != _chunk) { // Whilst have Chunks in a row sum += k->_len; // Total size of this Chunk k = k->_next; // Bump along to next Chunk @@ -93,7 +93,7 @@ // Get minimal required size. Either real big, or even bigger for giant objs size_t len = max(x, Chunk::size); - register Chunk *k = _chunk; // Get filled-up chunk address + Chunk *k = _chunk; // Get filled-up chunk address _chunk = new (len) Chunk(len); if( k ) k->_next = _chunk; // Append new chunk to end of linked list
diff --git a/src/hotspot/share/adlc/dict2.cpp b/src/hotspot/share/adlc/dict2.cpp index f341a2b..2dc60b2 100644 --- a/src/hotspot/share/adlc/dict2.cpp +++ b/src/hotspot/share/adlc/dict2.cpp
@@ -283,9 +283,9 @@ // limited to MAXID characters in length. Experimental evidence on 150K of // C text shows excellent spreading of values for any size hash table. int hashstr(const void *t) { - register char c, k = 0; - register int sum = 0; - register const char *s = (const char *)t; + char c, k = 0; + int sum = 0; + const char *s = (const char *)t; while (((c = s[k]) != '\0') && (k < MAXID-1)) { // Get characters till nul c = (char) ((c << 1) + 1); // Characters are always odd!
diff --git a/src/hotspot/share/adlc/main.cpp b/src/hotspot/share/adlc/main.cpp index 7476db8..f7cef4f 100644 --- a/src/hotspot/share/adlc/main.cpp +++ b/src/hotspot/share/adlc/main.cpp
@@ -58,7 +58,7 @@ // Read command line arguments and file names for( int i = 1; i < argc; i++ ) { // For all arguments - register char *s = argv[i]; // Get option/filename + char *s = argv[i]; // Get option/filename if( *s++ == '-' ) { // It's a flag? (not a filename) if( !*s ) { // Stand-alone `-' means stdin
diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp index 38089d9..9d9154e 100644 --- a/src/hotspot/share/adlc/output_c.cpp +++ b/src/hotspot/share/adlc/output_c.cpp
@@ -3005,7 +3005,7 @@ // Provide a non-NULL return for disp_as_type() that will allow adr_type() // to correctly compute the access type for alias analysis. // - // See BugId 4796752, operand indOffset32X in i486.ad + // See BugId 4796752, operand indOffset32X in x86_32.ad int idx = rep_var_to_constant_index(disp, oper, globals); fprintf(fp," virtual const TypePtr *disp_as_type() const { return _c%d; }\n", idx); }
diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index 2a2ad78..6888d10 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp
@@ -1988,10 +1988,8 @@ if (singleton) { cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton); if (cha_monomorphic_target != NULL) { - // If CHA is able to bind this invoke then update the class - // to match that class, otherwise klass will refer to the - // interface. - klass = cha_monomorphic_target->holder(); + ciInstanceKlass* holder = cha_monomorphic_target->holder(); + klass = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts actual_recv = target->holder(); // insert a check it's really the expected class. @@ -2001,6 +1999,8 @@ // pass the result of the checkcast so that the compiler has // more accurate type info in the inlinee better_receiver = append_split(c); + + dependency_recorder()->assert_unique_implementor(target->holder(), singleton); } } }
diff --git a/src/hotspot/share/c1/c1_IR.cpp b/src/hotspot/share/c1/c1_IR.cpp index b08d15d..fa2c7e7 100644 --- a/src/hotspot/share/c1/c1_IR.cpp +++ b/src/hotspot/share/c1/c1_IR.cpp
@@ -190,7 +190,8 @@ , _stack(stack) , _exception_handlers(exception_handlers) , _is_method_handle_invoke(false) - , _deoptimize_on_exception(deoptimize_on_exception) { + , _deoptimize_on_exception(deoptimize_on_exception) + , _force_reexecute(false) { assert(_stack != NULL, "must be non null"); } @@ -202,7 +203,8 @@ , _oop_map(NULL) , _stack(stack == NULL ? info->_stack : stack) , _is_method_handle_invoke(info->_is_method_handle_invoke) - , _deoptimize_on_exception(info->_deoptimize_on_exception) { + , _deoptimize_on_exception(info->_deoptimize_on_exception) + , _force_reexecute(info->_force_reexecute) { // deep copy of exception handlers if (info->_exception_handlers != NULL) { @@ -214,7 +216,8 @@ void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) { // record the safepoint before recording the debug info for enclosing scopes recorder->add_safepoint(pc_offset, _oop_map->deep_copy()); - _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, _is_method_handle_invoke); + bool reexecute = _force_reexecute || _scope_debug_info->should_reexecute(); + _scope_debug_info->record_debug_info(recorder, pc_offset, reexecute, _is_method_handle_invoke); recorder->end_safepoint(pc_offset); }
diff --git a/src/hotspot/share/c1/c1_IR.hpp b/src/hotspot/share/c1/c1_IR.hpp index c40cf26..86304e0 100644 --- a/src/hotspot/share/c1/c1_IR.hpp +++ b/src/hotspot/share/c1/c1_IR.hpp
@@ -232,16 +232,15 @@ //Whether we should reexecute this bytecode for deopt bool should_reexecute(); - void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) { + void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool reexecute, bool is_method_handle_invoke = false) { if (caller() != NULL) { // Order is significant: Must record caller first. - caller()->record_debug_info(recorder, pc_offset, false/*topmost*/); + caller()->record_debug_info(recorder, pc_offset, false/*reexecute*/); } DebugToken* locvals = recorder->create_scope_values(locals()); DebugToken* expvals = recorder->create_scope_values(expressions()); DebugToken* monvals = recorder->create_monitor_values(monitors()); // reexecute allowed only for the topmost frame - bool reexecute = topmost ? should_reexecute() : false; bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis. bool rethrow_exception = false; recorder->describe_scope(pc_offset, methodHandle(), scope()->method(), bci(), reexecute, rethrow_exception, is_method_handle_invoke, return_oop, locvals, expvals, monvals); @@ -259,6 +258,7 @@ ValueStack* _stack; // used by deoptimization (contains also monitors bool _is_method_handle_invoke; // true if the associated call site is a MethodHandle call site. bool _deoptimize_on_exception; + bool _force_reexecute; // force the reexecute flag on, used for patching stub FrameMap* frame_map() const { return scope()->compilation()->frame_map(); } Compilation* compilation() const { return scope()->compilation(); } @@ -285,7 +285,11 @@ bool is_method_handle_invoke() const { return _is_method_handle_invoke; } void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; } + bool force_reexecute() const { return _force_reexecute; } + void set_force_reexecute() { _force_reexecute = true; } + int interpreter_frame_size() const; + };
diff --git a/src/hotspot/share/c1/c1_Instruction.cpp b/src/hotspot/share/c1/c1_Instruction.cpp index ee3be89..c4135f6 100644 --- a/src/hotspot/share/c1/c1_Instruction.cpp +++ b/src/hotspot/share/c1/c1_Instruction.cpp
@@ -838,6 +838,11 @@ existing_state->invalidate_local(index); TRACE_PHI(tty->print_cr("invalidating local %d because of type mismatch", index)); } + + if (existing_value != new_state->local_at(index) && existing_value->as_Phi() == NULL) { + TRACE_PHI(tty->print_cr("required phi for local %d is missing, irreducible loop?", index)); + return false; // BAILOUT in caller + } } #ifdef ASSERT
diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index aa8510f..160483d 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp
@@ -41,6 +41,7 @@ while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeGeneralJump::instruction_size) { _masm->nop(); } + info->set_force_reexecute(); patch->install(_masm, patch_code, obj, info); append_code_stub(patch);
diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 8847b22..f4b156d 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp
@@ -993,6 +993,14 @@ Phi* phi = sux_val->as_Phi(); // cur_val can be null without phi being null in conjunction with inlining if (phi != NULL && cur_val != NULL && cur_val != phi && !phi->is_illegal()) { + if (phi->is_local()) { + for (int i = 0; i < phi->operand_count(); i++) { + Value op = phi->operand_at(i); + if (op != NULL && op->type()->is_illegal()) { + bailout("illegal phi operand"); + } + } + } Phi* cur_phi = cur_val->as_Phi(); if (cur_phi != NULL && cur_phi->is_illegal()) { // Phi and local would need to get invalidated
diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index 2138299..807cc40 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp
@@ -834,6 +834,10 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_id )) NOT_PRODUCT(_patch_code_slowcase_cnt++;) + // Enable WXWrite: the function is called by c1 stub as a runtime function + // (see another implementation above). + MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); + ResourceMark rm(thread); RegisterMap reg_map(thread, false); frame runtime_frame = thread->last_frame();
diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index 274b1b1..a57043c 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp
@@ -95,7 +95,7 @@ // ------------------------------------------------------------------ // ciEnv::ciEnv -ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) +ciEnv::ciEnv(CompileTask* task) : _ciEnv_arena(mtCompiler) { VM_ENTRY_MARK; @@ -115,7 +115,6 @@ assert(!firstEnv, "not initialized properly"); #endif /* !PRODUCT */ - _system_dictionary_modification_counter = system_dictionary_modification_counter; _num_inlined_bytecodes = 0; assert(task == NULL || thread->task() == task, "sanity"); if (task != NULL) { @@ -180,7 +179,6 @@ firstEnv = false; #endif /* !PRODUCT */ - _system_dictionary_modification_counter = 0; _num_inlined_bytecodes = 0; _task = NULL; _log = NULL; @@ -923,10 +921,6 @@ return JavaThread::current()->thread_state() == _thread_in_vm; } -bool ciEnv::system_dictionary_modification_counter_changed() { - return _system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); -} - // ------------------------------------------------------------------ // ciEnv::validate_compile_task_dependencies // @@ -935,8 +929,7 @@ void ciEnv::validate_compile_task_dependencies(ciMethod* target) { if (failing()) return; // no need for further checks - bool counter_changed = system_dictionary_modification_counter_changed(); - Dependencies::DepType result = dependencies()->validate_dependencies(_task, counter_changed); + Dependencies::DepType result = dependencies()->validate_dependencies(_task); if (result != Dependencies::end_marker) { if (result == Dependencies::call_site_target_value) { _inc_decompile_count_on_failure = false;
diff --git a/src/hotspot/share/ci/ciEnv.hpp b/src/hotspot/share/ci/ciEnv.hpp index 07b2a96..9245b2e 100644 --- a/src/hotspot/share/ci/ciEnv.hpp +++ b/src/hotspot/share/ci/ciEnv.hpp
@@ -46,11 +46,11 @@ friend class CompileBroker; friend class Dependencies; // for get_object, during logging + friend class PrepareExtraDataClosure; private: Arena* _arena; // Alias for _ciEnv_arena except in init_shared_objects() Arena _ciEnv_arena; - int _system_dictionary_modification_counter; ciObjectFactory* _factory; OopRecorder* _oop_recorder; DebugInformationRecorder* _debug_info; @@ -189,6 +189,10 @@ } } + ciMetadata* cached_metadata(Metadata* o) { + return _factory->cached_metadata(o); + } + ciInstance* get_instance(oop o) { if (o == NULL) return NULL; return get_object(o)->as_instance(); @@ -295,7 +299,7 @@ MethodCompilable_never }; - ciEnv(CompileTask* task, int system_dictionary_modification_counter); + ciEnv(CompileTask* task); // Used only during initialization of the ci ciEnv(Arena* arena); ~ciEnv(); @@ -451,9 +455,6 @@ CompileLog* log() { return _log; } void set_log(CompileLog* log) { _log = log; } - // Check for changes to the system dictionary during compilation - bool system_dictionary_modification_counter_changed(); - void record_failure(const char* reason); // Record failure and report later void report_failure(const char* reason); // Report failure immediately void record_method_not_compilable(const char* reason, bool all_tiers = true);
diff --git a/src/hotspot/share/ci/ciMethodData.cpp b/src/hotspot/share/ci/ciMethodData.cpp index bd2d52d..a6b38db 100644 --- a/src/hotspot/share/ci/ciMethodData.cpp +++ b/src/hotspot/share/ci/ciMethodData.cpp
@@ -37,51 +37,105 @@ // ------------------------------------------------------------------ // ciMethodData::ciMethodData // -ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) { - assert(md != NULL, "no null method data"); - Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord)); - _data = NULL; - _data_size = 0; - _extra_data_size = 0; - _current_mileage = 0; - _invocation_counter = 0; - _backedge_counter = 0; - _state = empty_state; - _saw_free_extra_data = false; +ciMethodData::ciMethodData(MethodData* md) +: ciMetadata(md), + _data_size(0), _extra_data_size(0), _data(NULL), // Set an initial hint. Don't use set_hint_di() because // first_di() may be out of bounds if data_size is 0. - _hint_di = first_di(); + _hint_di(first_di()), + _state(empty_state), + _saw_free_extra_data(false), // Initialize the escape information (to "don't know."); - _eflags = _arg_local = _arg_stack = _arg_returned = 0; - _parameters = NULL; -} + _eflags(0), _arg_local(0), _arg_stack(0), _arg_returned(0), + _current_mileage(0), + _invocation_counter(0), + _backedge_counter(0), + _orig(), + _parameters(NULL) {} -// ------------------------------------------------------------------ -// ciMethodData::ciMethodData -// -// No MethodData*. -ciMethodData::ciMethodData() : ciMetadata(NULL) { - Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord)); - _data = NULL; - _data_size = 0; - _extra_data_size = 0; - _current_mileage = 0; - _invocation_counter = 0; - _backedge_counter = 0; - _state = empty_state; - _saw_free_extra_data = false; - // Set an initial hint. Don't use set_hint_di() because - // first_di() may be out of bounds if data_size is 0. - _hint_di = first_di(); - // Initialize the escape information (to "don't know."); - _eflags = _arg_local = _arg_stack = _arg_returned = 0; - _parameters = NULL; -} +// Check for entries that reference an unloaded method +class PrepareExtraDataClosure : public CleanExtraDataClosure { + MethodData* _mdo; + int _safepoint_counter; // Needs to be uint64_t after JDK-8212108! + GrowableArray<Method*> _uncached_methods; -void ciMethodData::load_extra_data() { +public: + PrepareExtraDataClosure(MethodData* mdo) + : _mdo(mdo), + _safepoint_counter(SafepointSynchronize::safepoint_counter()), + _uncached_methods() + { } + + bool is_live(Method* m) { + if (!m->method_holder()->is_loader_alive()) { + return false; + } + if (CURRENT_ENV->cached_metadata(m) == NULL) { + // Uncached entries need to be pre-populated. + _uncached_methods.append(m); + } + return true; + } + + bool has_safepointed() { + return SafepointSynchronize::safepoint_counter() != _safepoint_counter; + } + + bool finish() { + if (_uncached_methods.length() == 0) { + // Preparation finished iff all Methods* were already cached. + return true; + } + // Holding locks through safepoints is bad practice. + MutexUnlocker mu(_mdo->extra_data_lock()); + for (int i = 0; i < _uncached_methods.length(); ++i) { + if (has_safepointed()) { + // The metadata in the growable array might contain stale + // entries after a safepoint. + return false; + } + Method* method = _uncached_methods.at(i); + // Populating ciEnv caches may cause safepoints due + // to taking the Compile_lock with safepoint checks. + (void)CURRENT_ENV->get_method(method); + } + return false; + } +}; + +void ciMethodData::prepare_metadata() { MethodData* mdo = get_MethodData(); + for (;;) { + ResourceMark rm; + PrepareExtraDataClosure cl(mdo); + mdo->clean_extra_data(&cl); + if (cl.finish()) { + // When encountering uncached metadata, the Compile_lock might be + // acquired when creating ciMetadata handles, causing safepoints + // which requires a new round of preparation to clean out potentially + // new unloading metadata. + return; + } + } +} + +void ciMethodData::load_remaining_extra_data() { + MethodData* mdo = get_MethodData(); MutexLocker ml(mdo->extra_data_lock()); + // Deferred metadata cleaning due to concurrent class unloading. + prepare_metadata(); + // After metadata preparation, there is no stale metadata, + // and no safepoints can introduce more stale metadata. + NoSafepointVerifier no_safepoint; + + assert((mdo->data_size() == _data_size) && (mdo->extra_data_size() == _extra_data_size), "sanity, unchanged"); + assert(extra_data_base() == (DataLayout*)((address) _data + _data_size), "sanity"); + + // Copy the extra data once it is prepared (i.e. cache populated, no release of extra data lock anymore) + Copy::disjoint_words_atomic((HeapWord*) mdo->extra_data_base(), + (HeapWord*)((address) _data + _data_size), + (_extra_data_size - mdo->parameters_size_in_bytes()) / HeapWordSize); // speculative trap entries also hold a pointer to a Method so need to be translated DataLayout* dp_src = mdo->extra_data_base(); @@ -91,28 +145,12 @@ assert(dp_src < end_src, "moved past end of extra data"); assert(((intptr_t)dp_dst) - ((intptr_t)extra_data_base()) == ((intptr_t)dp_src) - ((intptr_t)mdo->extra_data_base()), "source and destination don't match"); - // New traps in the MDO may have been added since we copied the - // data (concurrent deoptimizations before we acquired - // extra_data_lock above) or can be removed (a safepoint may occur - // in the translate_from call below) as we translate the copy: - // update the copy as we go. int tag = dp_src->tag(); - size_t entry_size = DataLayout::header_size_in_bytes(); - if (tag != DataLayout::no_tag) { - ProfileData* src_data = dp_src->data_in(); - entry_size = src_data->size_in_bytes(); - } - memcpy(dp_dst, dp_src, entry_size); - switch(tag) { case DataLayout::speculative_trap_data_tag: { ciSpeculativeTrapData data_dst(dp_dst); SpeculativeTrapData data_src(dp_src); - - { // During translation a safepoint can happen or VM lock can be taken (e.g., Compile_lock). - MutexUnlocker ml(mdo->extra_data_lock()); - data_dst.translate_from(&data_src); - } + data_dst.translate_from(&data_src); break; } case DataLayout::bit_data_tag: @@ -138,10 +176,33 @@ // To do: don't copy the data if it is not "ripe" -- require a minimum # // of invocations. - // Snapshot the data -- actually, take an approximate snapshot of - // the data. Any concurrently executing threads may be changing the - // data as we copy it. - Copy::disjoint_words_atomic((HeapWord*) mdo, + // Snapshot the data and extra parameter data first without the extra trap and arg info data. + // Those are copied in a second step. Actually, an approximate snapshot of the data is taken. + // Any concurrently executing threads may be changing the data as we copy it. + // + // The first snapshot step requires two copies (data entries and parameter data entries) since + // the MDO is laid out as follows: + // + // data_base: --------------------------- + // | data entries | + // | ... | + // extra_data_base: --------------------------- + // | trap data entries | + // | ... | + // | one arg info data entry | + // | data for each arg | + // | ... | + // args_data_limit: --------------------------- + // | parameter data entries | + // | ... | + // extra_data_limit: --------------------------- + // + // _data_size = extra_data_base - data_base + // _extra_data_size = extra_data_limit - extra_data_base + // total_size = _data_size + _extra_data_size + // args_data_limit = data_base + total_size - parameter_data_size + STATIC_ASSERT(sizeof(_orig) % HeapWordSize == 0); // "align" + Copy::disjoint_words_atomic((HeapWord*) &mdo->_compiler_counters, (HeapWord*) &_orig, sizeof(_orig) / HeapWordSize); Arena* arena = CURRENT_ENV->arena(); @@ -151,8 +212,15 @@ _data = (intptr_t *) arena->Amalloc(total_size); Copy::disjoint_words_atomic((HeapWord*) mdo->data_base(), (HeapWord*) _data, - total_size / HeapWordSize); + _data_size / HeapWordSize); + int parameters_data_size = mdo->parameters_size_in_bytes(); + if (parameters_data_size > 0) { + // Snapshot the parameter data + Copy::disjoint_words_atomic((HeapWord*) mdo->args_data_limit(), + (HeapWord*) ((address)_data + total_size - parameters_data_size), + parameters_data_size / HeapWordSize); + } // Traverse the profile data, translating any oops into their // ci equivalents. ResourceMark rm; @@ -169,7 +237,9 @@ parameters->translate_from(mdo->parameters_type_data()); } - load_extra_data(); + assert((DataLayout*) ((address)_data + total_size - parameters_data_size) == args_data_limit(), + "sanity - parameter data starts after the argument data of the single ArgInfoData entry"); + load_remaining_extra_data(); // Note: Extra data are all BitData, and do not need translation. _current_mileage = MethodData::mileage_of(mdo->method()); @@ -196,8 +266,15 @@ for (uint row = 0; row < row_limit(); row++) { Klass* k = data->as_ReceiverTypeData()->receiver(row); if (k != NULL) { - ciKlass* klass = CURRENT_ENV->get_klass(k); - set_receiver(row, klass); + if (k->is_loader_alive()) { + ciKlass* klass = CURRENT_ENV->get_klass(k); + set_receiver(row, klass); + } else { + // With concurrent class unloading, the MDO could have stale metadata; override it + clear_row(row); + } + } else { + set_receiver(row, NULL); } } } @@ -279,7 +356,7 @@ two_free_slots = (MethodData::next_extra(dp)->tag() == DataLayout::no_tag); return NULL; case DataLayout::arg_info_data_tag: - return NULL; // ArgInfoData is at the end of extra data section. + return NULL; // ArgInfoData is after the trap data right before the parameter data. case DataLayout::bit_data_tag: if (m == NULL && dp->bci() == bci) { return new ciBitData(dp); @@ -690,7 +767,7 @@ break; case DataLayout::arg_info_data_tag: data = new ciArgInfoData(dp); - dp = end; // ArgInfoData is at the end of extra data section. + dp = end; // ArgInfoData is after the trap data right before the parameter data. break; case DataLayout::speculative_trap_data_tag: data = new ciSpeculativeTrapData(dp);
diff --git a/src/hotspot/share/ci/ciMethodData.hpp b/src/hotspot/share/ci/ciMethodData.hpp index e1bf77f..6a95456 100644 --- a/src/hotspot/share/ci/ciMethodData.hpp +++ b/src/hotspot/share/ci/ciMethodData.hpp
@@ -400,10 +400,10 @@ u_char _saw_free_extra_data; // Support for interprocedural escape analysis - intx _eflags; // flags on escape information - intx _arg_local; // bit set of non-escaping arguments - intx _arg_stack; // bit set of stack-allocatable arguments - intx _arg_returned; // bit set of returned arguments + intx _eflags; // flags on escape information + intx _arg_local; // bit set of non-escaping arguments + intx _arg_stack; // bit set of stack-allocatable arguments + intx _arg_returned; // bit set of returned arguments // Maturity of the oop when the snapshot is taken. int _current_mileage; @@ -415,17 +415,15 @@ int _backedge_counter; // Coherent snapshot of original header. - MethodData _orig; + MethodData::CompilerCounters _orig; - // Area dedicated to parameters. NULL if no parameter profiling for - // this method. + // Area dedicated to parameters. NULL if no parameter profiling for this method. DataLayout* _parameters; int parameters_size() const { return _parameters == NULL ? 0 : parameters_type_data()->size_in_bytes(); } - ciMethodData(MethodData* md); - ciMethodData(); + ciMethodData(MethodData* md = NULL); // Accessors int data_size() const { return _data_size; } @@ -475,7 +473,8 @@ return (address) _data; } - void load_extra_data(); + void prepare_metadata(); + void load_remaining_extra_data(); ciProfileData* bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots); void dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k); @@ -554,8 +553,8 @@ uint trap_count(int reason) const { return _orig.trap_count(reason); } - uint trap_reason_limit() const { return _orig.trap_reason_limit(); } - uint trap_count_limit() const { return _orig.trap_count_limit(); } + uint trap_reason_limit() const { return MethodData::trap_reason_limit(); } + uint trap_count_limit() const { return MethodData::trap_count_limit(); } // Helpful query functions that decode trap_state. int has_trap_at(ciProfileData* data, int reason);
diff --git a/src/hotspot/share/ci/ciObjectFactory.cpp b/src/hotspot/share/ci/ciObjectFactory.cpp index e6391b5..3ed142d 100644 --- a/src/hotspot/share/ci/ciObjectFactory.cpp +++ b/src/hotspot/share/ci/ciObjectFactory.cpp
@@ -266,6 +266,24 @@ } // ------------------------------------------------------------------ +// ciObjectFactory::cached_metadata +// +// Get the ciMetadata corresponding to some Metadata. If the ciMetadata has +// already been created, it is returned. Otherwise, null is returned. +ciMetadata* ciObjectFactory::cached_metadata(Metadata* key) { + ASSERT_IN_VM; + + bool found = false; + int index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found); + + if (!found) { + return NULL; + } + return _ci_metadata->at(index)->as_metadata(); +} + + +// ------------------------------------------------------------------ // ciObjectFactory::get_metadata // // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
diff --git a/src/hotspot/share/ci/ciObjectFactory.hpp b/src/hotspot/share/ci/ciObjectFactory.hpp index 1063c98..1e8033f 100644 --- a/src/hotspot/share/ci/ciObjectFactory.hpp +++ b/src/hotspot/share/ci/ciObjectFactory.hpp
@@ -100,6 +100,7 @@ // Get the ciObject corresponding to some oop. ciObject* get(oop key); ciMetadata* get_metadata(Metadata* key); + ciMetadata* cached_metadata(Metadata* key); ciSymbol* get_symbol(Symbol* key); // Get the ciSymbol corresponding to one of the vmSymbols.
diff --git a/src/hotspot/share/classfile/altHashing.cpp b/src/hotspot/share/classfile/altHashing.cpp index 7143e72..25d2728 100644 --- a/src/hotspot/share/classfile/altHashing.cpp +++ b/src/hotspot/share/classfile/altHashing.cpp
@@ -26,18 +26,23 @@ * halfsiphash code adapted from reference implementation * (https://github.com/veorq/SipHash/blob/master/halfsiphash.c) * which is distributed with the following copyright: - * - * SipHash reference C implementation - * - * Copyright (c) 2016 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com> - * - * To the extent possible under law, the author(s) have dedicated all copyright - * and related and neighboring rights to this software to the public domain - * worldwide. This software is distributed without any warranty. - * - * You should have received a copy of the CC0 Public Domain Dedication along - * with this software. If not, see - * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +/* + SipHash reference C implementation + + Copyright (c) 2012-2021 Jean-Philippe Aumasson + <jeanphilippe.aumasson@gmail.com> + Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to> + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + <http://creativecommons.org/publicdomain/zero/1.0/>. */ #include "precompiled.hpp" @@ -134,7 +139,9 @@ } // HalfSipHash-2-4 (32-bit output) for Symbols -uint32_t AltHashing::halfsiphash_32(uint64_t seed, const uint8_t* data, int len) { +uint32_t AltHashing::halfsiphash_32(uint64_t seed, const void* in, int len) { + + const unsigned char* data = (const unsigned char*)in; uint32_t v[4]; uint32_t newdata; int off = 0;
diff --git a/src/hotspot/share/classfile/altHashing.hpp b/src/hotspot/share/classfile/altHashing.hpp index 346592c..5f58ca8 100644 --- a/src/hotspot/share/classfile/altHashing.hpp +++ b/src/hotspot/share/classfile/altHashing.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ static uint64_t compute_seed(); // For Symbols - static uint32_t halfsiphash_32(uint64_t seed, const uint8_t* data, int len); + static uint32_t halfsiphash_32(uint64_t seed, const void* in, int len); // For Strings static uint32_t halfsiphash_32(uint64_t seed, const uint16_t* data, int len); };
diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 2ea6b7e..c4607a5 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp
@@ -3149,6 +3149,7 @@ static bool inner_classes_check_loop_through_outer(const Array<u2>* inner_classes, int idx, const ConstantPool* cp, int length) { int slow = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset); int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset); + while (fast != -1 && fast != 0) { if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) { return true; // found a circularity @@ -3178,14 +3179,15 @@ for (int y = idx + InstanceKlass::inner_class_next_offset; y < length; y += InstanceKlass::inner_class_next_offset) { - // To maintain compatibility, throw an exception if duplicate inner classes - // entries are found. - guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) || - _inner_classes->at(idx+1) != _inner_classes->at(y+1) || - _inner_classes->at(idx+2) != _inner_classes->at(y+2) || - _inner_classes->at(idx+3) != _inner_classes->at(y+3)), - "Duplicate entry in InnerClasses attribute in class file %s", - CHECK_(true)); + // 4347400: make sure there's no duplicate entry in the classes array + if (_major_version >= JAVA_1_5_VERSION) { + guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) || + _inner_classes->at(idx+1) != _inner_classes->at(y+1) || + _inner_classes->at(idx+2) != _inner_classes->at(y+2) || + _inner_classes->at(idx+3) != _inner_classes->at(y+3)), + "Duplicate entry in InnerClasses attribute in class file %s", + CHECK_(true)); + } // Return true if there are two entries with the same inner_class_info_index. if (_inner_classes->at(y) == _inner_classes->at(idx)) { return true; @@ -3278,10 +3280,9 @@ inner_classes->at_put(index++, inner_access_flags.as_short()); } - // 4347400: make sure there's no duplicate entry in the classes array - // Also, check for circular entries. + // Check for circular and duplicate entries. bool has_circularity = false; - if (_need_verify && _major_version >= JAVA_1_5_VERSION) { + if (_need_verify) { has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0); if (has_circularity) { // If circularity check failed then ignore InnerClasses attribute.
diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 03954f5..e38afea 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp
@@ -326,13 +326,19 @@ } // read contents into resource array - int size = (*filesize) + ((nul_terminate) ? 1 : 0); + size_t size = (uint32_t)(*filesize); + if (nul_terminate) { + if (sizeof(size) == sizeof(uint32_t) && size == UINT_MAX) { + return NULL; // 32-bit integer overflow will occur. + } + size++; + } buffer = NEW_RESOURCE_ARRAY(u1, size); if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL; // return result if (nul_terminate) { - buffer[*filesize] = 0; + buffer[size - 1] = 0; } return buffer; }
diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index 1ed4963..9a0872c 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp
@@ -613,9 +613,9 @@ ClassLoaderData* cld = loader_data(); // class loader must be present; a null class loader is the // boostrap loader - guarantee(cld != NULL || DumpSharedSpaces || - cld->class_loader() == NULL || - cld->class_loader()->is_instance(), + guarantee(DumpSharedSpaces || + (cld != NULL && + (cld->the_null_class_loader_data() || cld->class_loader()->is_instance())), "checking type of class_loader"); ResourceMark rm;
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index f21fbaf..0360de2 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -97,7 +97,6 @@ SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL; ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL; -int SystemDictionary::_number_of_modifications = 0; oop SystemDictionary::_system_loader_lock_obj = NULL; InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT] @@ -1010,11 +1009,7 @@ // Add to class hierarchy, initialize vtables, and do possible // deoptimizations. add_to_hierarchy(k, CHECK_NULL); // No exception, but can block - // But, do not add to dictionary. - - // compiled code dependencies need to be validated anyway - notice_modification(); } // Rewrite and patch constant pool here. @@ -1907,7 +1902,6 @@ void SystemDictionary::initialize(TRAPS) { // Allocate arrays _placeholders = new PlaceholderTable(_placeholder_table_size); - _number_of_modifications = 0; _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); _resolution_errors = new ResolutionErrorTable(_resolution_error_size); _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); @@ -2196,8 +2190,6 @@ InstanceKlass* sd_check = find_class(d_hash, name, dictionary); if (sd_check == NULL) { dictionary->add_klass(d_hash, name, k); - - notice_modification(); } #ifdef ASSERT sd_check = find_class(d_hash, name, dictionary);
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index a14728d..77adcd4 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -398,13 +398,6 @@ static void print_shared(outputStream* st); static void dump(outputStream* st, bool verbose); - // Monotonically increasing counter which grows as classes are - // loaded or modifications such as hot-swapping or setting/removing - // of breakpoints are performed - static inline int number_of_modifications() { assert_locked_or_safepoint(Compile_lock); return _number_of_modifications; } - // Needed by evolution and breakpoint code - static inline void notice_modification() { assert_locked_or_safepoint(Compile_lock); ++_number_of_modifications; } - // Verification static void verify(); @@ -613,11 +606,6 @@ // Hashtable holding classes from the shared archive. static Dictionary* _shared_dictionary; - // Monotonically increasing counter which grows with - // loading classes as well as hot-swapping and breakpoint setting - // and removal. - static int _number_of_modifications; - // Lock object for system class loader static oop _system_loader_lock_obj;
diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index d823c23..96a6407 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp
@@ -1734,7 +1734,7 @@ no_control_flow = true; break; default: // We only need to check the valid bytecodes in class file. - // And jsr and ret are not in the new class file format in JDK1.5. + // And jsr and ret are not in the new class file format in JDK1.6. verify_error(ErrorContext::bad_code(bci), "Bad instruction: %02x", opcode); no_control_flow = false; @@ -2356,7 +2356,8 @@ verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx(), TypeOrigin::implicit(current_type())), - "Bad access to protected data in getfield"); + "Bad access to protected data in %s", + is_getfield ? "getfield" : "putfield"); return; } }
diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp index 377b1c3..ec72ed2 100644 --- a/src/hotspot/share/code/dependencies.cpp +++ b/src/hotspot/share/code/dependencies.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,6 +121,12 @@ assert_common_3(exclusive_concrete_methods_2, ctxk, m1, m2); } +void Dependencies::assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) { + check_ctxk(ctxk); + check_unique_implementor(ctxk, uniqk); + assert_common_2(unique_implementor, ctxk, uniqk); +} + void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) { check_ctxk(ctxk); assert_common_1(no_finalizable_subclasses, ctxk); @@ -178,6 +184,13 @@ assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, conck_dv); } +void Dependencies::assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk) { + check_ctxk(ctxk); + assert(ctxk->is_interface(), "not an interface"); + assert(ctxk->implementor() == uniqk, "not a unique implementor"); + assert_common_2(unique_implementor, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqk)); +} + void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) { check_ctxk(ctxk); assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm)); @@ -593,6 +606,7 @@ "unique_concrete_method", "abstract_with_exclusive_concrete_subtypes_2", "exclusive_concrete_methods_2", + "unique_implementor", "no_finalizable_subclasses", "call_site_target_value" }; @@ -607,6 +621,7 @@ 2, // unique_concrete_method ctxk, m 3, // unique_concrete_subtypes_2 ctxk, k1, k2 3, // unique_concrete_methods_2 ctxk, m1, m2 + 2, // unique_implementor ctxk, implementor 1, // no_finalizable_subclasses ctxk 2 // call_site_target_value call_site, method_handle }; @@ -625,32 +640,10 @@ guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, "invalid dependency type: %d", (int) dept); } -Dependencies::DepType Dependencies::validate_dependencies(CompileTask* task, bool counter_changed, char** failure_detail) { - // First, check non-klass dependencies as we might return early and - // not check klass dependencies if the system dictionary - // modification counter hasn't changed (see below). - for (Dependencies::DepStream deps(this); deps.next(); ) { - if (deps.is_klass_type()) continue; // skip klass dependencies - Klass* witness = deps.check_dependency(); - if (witness != NULL) { - return deps.type(); - } - } - - // Klass dependencies must be checked when the system dictionary - // changes. If logging is enabled all violated dependences will be - // recorded in the log. In debug mode check dependencies even if - // the system dictionary hasn't changed to verify that no invalid - // dependencies were inserted. Any violated dependences in this - // case are dumped to the tty. - if (!counter_changed && !trueInDebug) { - return end_marker; - } - +Dependencies::DepType Dependencies::validate_dependencies(CompileTask* task, char** failure_detail) { int klass_violations = 0; DepType result = end_marker; for (Dependencies::DepStream deps(this); deps.next(); ) { - if (!deps.is_klass_type()) continue; // skip non-klass dependencies Klass* witness = deps.check_dependency(); if (witness != NULL) { if (klass_violations == 0) { @@ -665,12 +658,7 @@ } } klass_violations++; - if (!counter_changed) { - // Dependence failed but counter didn't change. Log a message - // describing what failed and allow the assert at the end to - // trigger. - deps.print_dependency(witness); - } else if (xtty == NULL) { + if (xtty == NULL) { // If we're not logging then a single violation is sufficient, // otherwise we want to log all the dependences which were // violated. @@ -679,15 +667,6 @@ } } - if (klass_violations != 0) { -#ifdef ASSERT - if (task != NULL && !counter_changed && !PrintCompilation) { - // Print out the compile task that failed - task->print_tty(); - } -#endif - assert(counter_changed, "failed dependencies, but counter didn't change"); - } return result; } @@ -1852,6 +1831,17 @@ return NULL; } +Klass* Dependencies::check_unique_implementor(Klass* ctxk, Klass* uniqk, KlassDepChange* changes) { + InstanceKlass* ctxik = InstanceKlass::cast(ctxk); + assert(ctxik->is_interface(), "sanity"); + assert(ctxik->nof_implementors() > 0, "no implementors"); + if (ctxik->nof_implementors() == 1) { + assert(ctxik->implementor() == uniqk, "sanity"); + return NULL; + } + return ctxik; // no unique implementor +} + // Search for AME. // There are two version of checks. // 1) Spot checking version(Classload time). Newly added class is checked for AME. @@ -2021,6 +2011,9 @@ case exclusive_concrete_methods_2: witness = check_exclusive_concrete_methods(context_type(), method_argument(1), method_argument(2), changes); break; + case unique_implementor: + witness = check_unique_implementor(context_type(), type_argument(1), changes); + break; case no_finalizable_subclasses: witness = check_has_no_finalizable_subclasses(context_type(), changes); break;
diff --git a/src/hotspot/share/code/dependencies.hpp b/src/hotspot/share/code/dependencies.hpp index 52409dc..75fc0d6 100644 --- a/src/hotspot/share/code/dependencies.hpp +++ b/src/hotspot/share/code/dependencies.hpp
@@ -26,6 +26,7 @@ #define SHARE_VM_CODE_DEPENDENCIES_HPP #include "ci/ciCallSite.hpp" +#include "ci/ciInstanceKlass.hpp" #include "ci/ciKlass.hpp" #include "ci/ciMethodHandle.hpp" #include "classfile/systemDictionary.hpp" @@ -156,6 +157,9 @@ // This dependency asserts that MM(CX, M1) is no greater than {M1,M2}. exclusive_concrete_methods_2, + // This dependency asserts that interface CX has a unique implementor class. + unique_implementor, // one unique implementor under CX + // This dependency asserts that no instances of class or it's // subclasses require finalization registration. no_finalizable_subclasses, @@ -341,6 +345,9 @@ check_ctxk(ctxk); assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract"); } + static void check_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) { + assert(ctxk->implementor() == uniqk, "not a unique implementor"); + } void assert_common_1(DepType dept, ciBaseObject* x); void assert_common_2(DepType dept, ciBaseObject* x0, ciBaseObject* x1); @@ -356,6 +363,7 @@ void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm); void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2); void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2); + void assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk); void assert_has_no_finalizable_subclasses(ciKlass* ctxk); void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle); @@ -375,6 +383,7 @@ void assert_evol_method(Method* m); void assert_has_no_finalizable_subclasses(Klass* ctxk); void assert_leaf_type(Klass* ctxk); + void assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk); void assert_unique_concrete_method(Klass* ctxk, Method* uniqm); void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck); void assert_call_site_target_value(oop callSite, oop methodHandle); @@ -427,6 +436,7 @@ KlassDepChange* changes = NULL); static Klass* check_concrete_with_no_concrete_subtype(Klass* ctxk, KlassDepChange* changes = NULL); + static Klass* check_unique_implementor(Klass* ctxk, Klass* uniqk, KlassDepChange* changes = NULL); static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm, KlassDepChange* changes = NULL); static Klass* check_abstract_with_exclusive_concrete_subtypes(Klass* ctxk, Klass* k1, Klass* k2, @@ -471,7 +481,7 @@ void copy_to(nmethod* nm); - DepType validate_dependencies(CompileTask* task, bool counter_changed, char** failure_detail = NULL); + DepType validate_dependencies(CompileTask* task, char** failure_detail = NULL); void log_all_dependencies();
diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 7a0a64c..b794865 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp
@@ -411,6 +411,7 @@ CompileTask::free(current); } _first = NULL; + _last = NULL; // Wake up all threads that block on the queue. MethodCompileQueue_lock->notify_all(); @@ -1665,16 +1666,10 @@ // Final sanity check - the compiler object must exist guarantee(comp != NULL, "Compiler object must exist"); - int system_dictionary_modification_counter; - { - MutexLocker locker(Compile_lock, thread); - system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); - } - { // Must switch to native to allocate ci_env ThreadToNativeFromVM ttn(thread); - ciEnv ci_env(NULL, system_dictionary_modification_counter); + ciEnv ci_env((CompileTask*)NULL); // Cache Jvmti state ci_env.cache_jvmti_state(); // Cache DTrace flags @@ -2119,12 +2114,6 @@ const char* failure_reason = NULL; const char* retry_message = NULL; - int system_dictionary_modification_counter; - { - MutexLocker locker(Compile_lock, thread); - system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); - } - #if INCLUDE_JVMCI if (UseJVMCICompiler && comp != NULL && comp->is_jvmci()) { JVMCICompiler* jvmci = (JVMCICompiler*) comp; @@ -2138,7 +2127,7 @@ retry_message = "not retryable"; compilable = ciEnv::MethodCompilable_never; } else { - JVMCIEnv env(task, system_dictionary_modification_counter); + JVMCIEnv env(task); methodHandle method(thread, target_handle); jvmci->compile_method(method, osr_bci, &env); @@ -2159,7 +2148,7 @@ NoHandleMark nhm; ThreadToNativeFromVM ttn(thread); - ciEnv ci_env(task, system_dictionary_modification_counter); + ciEnv ci_env(task); if (should_break) { ci_env.set_break_at_compile(true); }
diff --git a/src/hotspot/share/compiler/methodMatcher.cpp b/src/hotspot/share/compiler/methodMatcher.cpp index c920dc3..9c6f95e 100644 --- a/src/hotspot/share/compiler/methodMatcher.cpp +++ b/src/hotspot/share/compiler/methodMatcher.cpp
@@ -41,16 +41,20 @@ // 0x28 '(' and 0x29 ')' are used for the signature // 0x2e '.' is always replaced before the matching // 0x2f '/' is only used in the class name as package separator +// +// It seems hard to get Non-ASCII characters to work in all circumstances due +// to limitations in Windows. So only ASCII characters are supported on Windows. -#define RANGEBASE "\x1\x2\x3\x4\x5\x6\x7\x8\xa\xb\xc\xd\xe\xf" \ +#define RANGEBASE_ASCII "\x1\x2\x3\x4\x5\x6\x7\x8\xa\xb\xc\xd\xe\xf" \ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ "\x21\x22\x23\x24\x25\x26\x27\x2a\x2b\x2c\x2d" \ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5c\x5e\x5f" \ "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \ - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \ + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" + +#define RANGEBASE_NON_ASCII "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \ @@ -58,6 +62,8 @@ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" +#define RANGEBASE RANGEBASE_ASCII NOT_WINDOWS(RANGEBASE_NON_ASCII) + #define RANGE0 "[*" RANGEBASE "]" #define RANGESLASH "[*" RANGEBASE "/]" @@ -164,6 +170,15 @@ if (*lp == ':') *lp = ' '; } if (*lp == ',' || *lp == '.') *lp = ' '; + +#ifdef _WINDOWS + // It seems hard to get Non-ASCII characters to work in all circumstances due + // to limitations in Windows. So only ASCII characters are supported on Windows. + if (!isascii(*lp)) { + error_msg = "Non-ASCII characters are not supported on Windows."; + return false; + } +#endif } return true; } @@ -237,12 +252,6 @@ } } -#ifdef _MSC_VER -#pragma warning(push) -// warning C4189: The file contains a character that cannot be represented -// in the current code page -#pragma warning(disable : 4819) -#endif void MethodMatcher::parse_method_pattern(char*& line, const char*& error_msg, MethodMatcher* matcher) { MethodMatcher::Mode c_match; MethodMatcher::Mode m_match; @@ -312,9 +321,6 @@ error_msg = "Could not parse method pattern"; } } -#ifdef _MSC_VER -#pragma warning(pop) -#endif bool MethodMatcher::matches(const methodHandle& method) const { Symbol* class_name = method->method_holder()->name();
diff --git a/src/hotspot/share/gc/cms/cmsHeap.hpp b/src/hotspot/share/gc/cms/cmsHeap.hpp index 93f177a..a352b63 100644 --- a/src/hotspot/share/gc/cms/cmsHeap.hpp +++ b/src/hotspot/share/gc/cms/cmsHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp index 50eed38..fecefee 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2021, Red Hat, 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
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 83b7d6b..3b0e6eb 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,6 +78,7 @@ #include "logging/log.hpp" #include "memory/allocation.hpp" #include "memory/iterator.hpp" +#include "memory/heapInspection.hpp" #include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/access.inline.hpp" @@ -152,7 +153,6 @@ reset_from_card_cache(start_idx, num_regions); } - HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index, MemRegion mr) { return new HeapRegion(hrs_index, bot(), mr); @@ -2120,6 +2120,30 @@ heap_region_iterate(&blk); } +class G1ParallelObjectIterator : public ParallelObjectIterator { +private: + G1CollectedHeap* _heap; + HeapRegionClaimer _claimer; + +public: + G1ParallelObjectIterator(uint thread_num) : + _heap(G1CollectedHeap::heap()), + _claimer(thread_num == 0 ? G1CollectedHeap::heap()->workers()->active_workers() : thread_num) {} + + virtual void object_iterate(ObjectClosure* cl, uint worker_id) { + _heap->object_iterate_parallel(cl, worker_id, &_claimer); + } +}; + +ParallelObjectIterator* G1CollectedHeap::parallel_object_iterator(uint thread_num) { + return new G1ParallelObjectIterator(thread_num); +} + +void G1CollectedHeap::object_iterate_parallel(ObjectClosure* cl, uint worker_id, HeapRegionClaimer* claimer) { + IterateObjectClosureRegionClosure blk(cl); + heap_region_par_iterate_from_worker_offset(&blk, claimer, worker_id); +} + void G1CollectedHeap::keep_alive(oop obj) { G1BarrierSet::enqueue(obj); }
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index be160d0..1f2029a 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1116,6 +1116,8 @@ // Iteration functions. + void object_iterate_parallel(ObjectClosure* cl, uint worker_id, HeapRegionClaimer* claimer); + // Iterate over all objects, calling "cl.do_object" on each. virtual void object_iterate(ObjectClosure* cl); @@ -1123,6 +1125,8 @@ object_iterate(cl); } + virtual ParallelObjectIterator* parallel_object_iterator(uint thread_num); + // Keep alive an object that was loaded with AS_NO_KEEPALIVE. virtual void keep_alive(oop obj);
diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp index 1081806..ea1efdb 100644 --- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp +++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp
@@ -263,7 +263,7 @@ if (pretouch_gang != NULL) { size_t num_chunks = MAX2((size_t)1, size_in_pages * _page_size / MAX2(G1PretouchTask::chunk_size(), _page_size)); - uint num_workers = MIN2((uint)num_chunks, pretouch_gang->active_workers()); + uint num_workers = MIN2((uint)num_chunks, pretouch_gang->total_workers()); log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.", cl.name(), num_workers, num_chunks, size_in_pages * _page_size); pretouch_gang->run_task(&cl, num_workers);
diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 33eda79..820b4be 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index 5d18efb..82aeba6 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,7 @@ class PSAdaptiveSizePolicy; class PSCardTable; class PSHeapSummary; +class WorkGang; class ParallelScavengeHeap : public CollectedHeap { friend class VMStructs;
diff --git a/src/hotspot/share/gc/serial/serialHeap.hpp b/src/hotspot/share/gc/serial/serialHeap.hpp index 820e00a..f482871 100644 --- a/src/hotspot/share/gc/serial/serialHeap.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,6 +81,7 @@ template <typename OopClosureType1, typename OopClosureType2> void oop_since_save_marks_iterate(OopClosureType1* cur, OopClosureType2* older); + }; #endif // SHARE_VM_GC_CMS_CMSHEAP_HPP
diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 8cd4b86..8deb320 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ #include "gc/shared/gcCause.hpp" #include "gc/shared/gcWhen.hpp" #include "memory/allocation.hpp" +#include "memory/heapInspection.hpp" #include "runtime/handles.hpp" #include "runtime/perfData.hpp" #include "runtime/safepoint.hpp" @@ -42,6 +43,7 @@ // class defines the functions that a heap must implement, and contains // infrastructure common to all heaps. +class AbstractGangTask; class AdaptiveSizePolicy; class BarrierSet; class CollectorPolicy; @@ -83,6 +85,12 @@ } }; +class ParallelObjectIterator : public CHeapObj<mtGC> { +public: + virtual void object_iterate(ObjectClosure* cl, uint worker_id) = 0; + virtual ~ParallelObjectIterator() {} +}; + // // CollectedHeap // GenCollectedHeap @@ -465,6 +473,10 @@ // the block is an object. virtual bool block_is_obj(const HeapWord* addr) const = 0; + virtual ParallelObjectIterator* parallel_object_iterator(uint thread_num) { + return NULL; + } + // Keep alive an object that was loaded with AS_NO_KEEPALIVE. virtual void keep_alive(oop obj) {}
diff --git a/src/hotspot/share/gc/shared/oopStorage.cpp b/src/hotspot/share/gc/shared/oopStorage.cpp index ac66a13..bb6855c 100644 --- a/src/hotspot/share/gc/shared/oopStorage.cpp +++ b/src/hotspot/share/gc/shared/oopStorage.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,8 @@ #include "runtime/mutex.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/safepoint.hpp" -#include "runtime/stubRoutines.hpp" #include "runtime/thread.hpp" #include "utilities/align.hpp" #include "utilities/count_trailing_zeros.hpp"
diff --git a/src/hotspot/share/gc/shared/vmGCOperations.cpp b/src/hotspot/share/gc/shared/vmGCOperations.cpp index b02305a..c8202c2 100644 --- a/src/hotspot/share/gc/shared/vmGCOperations.cpp +++ b/src/hotspot/share/gc/shared/vmGCOperations.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -154,7 +154,7 @@ } HeapInspection inspect(_csv_format, _print_help, _print_class_stats, _columns); - inspect.heap_inspection(_out); + inspect.heap_inspection(_out, _parallel_thread_num); }
diff --git a/src/hotspot/share/gc/shared/vmGCOperations.hpp b/src/hotspot/share/gc/shared/vmGCOperations.hpp index 65876e5..402aa31 100644 --- a/src/hotspot/share/gc/shared/vmGCOperations.hpp +++ b/src/hotspot/share/gc/shared/vmGCOperations.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,18 +125,21 @@ private: outputStream* _out; bool _full_gc; + uint _parallel_thread_num; bool _csv_format; // "comma separated values" format for spreadsheet. bool _print_help; bool _print_class_stats; const char* _columns; public: - VM_GC_HeapInspection(outputStream* out, bool request_full_gc) : + VM_GC_HeapInspection(outputStream* out, bool request_full_gc, + uint parallel_thread_num = 1) : VM_GC_Operation(0 /* total collections, dummy, ignored */, GCCause::_heap_inspection /* GC Cause */, 0 /* total full collections, dummy, ignored */, request_full_gc) { _out = out; _full_gc = request_full_gc; + _parallel_thread_num = parallel_thread_num; _csv_format = false; _print_help = false; _print_class_stats = false;
diff --git a/src/hotspot/share/gc/shared/workgroup.cpp b/src/hotspot/share/gc/shared/workgroup.cpp index c6b6843..163e0e4 100644 --- a/src/hotspot/share/gc/shared/workgroup.cpp +++ b/src/hotspot/share/gc/shared/workgroup.cpp
@@ -106,6 +106,17 @@ } } +static void run_foreground_task_if_needed(AbstractGangTask* task, uint num_workers, + bool add_foreground_work) { + if (add_foreground_work) { + log_develop_trace(gc, workgang)("Running work gang: %s task: %s worker: foreground", + Thread::current()->name(), task->name()); + task->work(num_workers); + log_develop_trace(gc, workgang)("Finished work gang: %s task: %s worker: foreground " + "thread: " PTR_FORMAT, Thread::current()->name(), task->name(), p2i(Thread::current())); + } +} + // WorkGang dispatcher implemented with semaphores. // // Semaphores don't require the worker threads to re-claim the lock when they wake up. @@ -136,7 +147,7 @@ delete _end_semaphore; } - void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers) { + void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers, bool add_foreground_work) { // No workers are allowed to read the state variables until they have been signaled. _task = task; _not_finished = num_workers; @@ -144,6 +155,8 @@ // Dispatch 'num_workers' number of tasks. _start_semaphore->signal(num_workers); + run_foreground_task_if_needed(task, num_workers, add_foreground_work); + // Wait for the last worker to signal the coordinator. _end_semaphore->wait(); @@ -199,7 +212,7 @@ delete _monitor; } - void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers) { + void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers, bool add_foreground_work) { MutexLockerEx ml(_monitor, Mutex::_no_safepoint_check_flag); _task = task; @@ -208,6 +221,8 @@ // Tell the workers to get to work. _monitor->notify_all(); + run_foreground_task_if_needed(task, num_workers, add_foreground_work); + // Wait for them to finish. while (_finished < _num_workers) { _monitor->wait(/* no_safepoint_check */ true); @@ -274,14 +289,14 @@ run_task(task, active_workers()); } -void WorkGang::run_task(AbstractGangTask* task, uint num_workers) { +void WorkGang::run_task(AbstractGangTask* task, uint num_workers, bool add_foreground_work) { guarantee(num_workers <= total_workers(), "Trying to execute task %s with %u workers which is more than the amount of total workers %u.", task->name(), num_workers, total_workers()); guarantee(num_workers > 0, "Trying to execute task %s with zero workers", task->name()); uint old_num_workers = _active_workers; update_active_workers(num_workers); - _dispatcher->coordinator_execute_on_workers(task, num_workers); + _dispatcher->coordinator_execute_on_workers(task, num_workers, add_foreground_work); update_active_workers(old_num_workers); }
diff --git a/src/hotspot/share/gc/shared/workgroup.hpp b/src/hotspot/share/gc/shared/workgroup.hpp index f6879bc..5e00e08 100644 --- a/src/hotspot/share/gc/shared/workgroup.hpp +++ b/src/hotspot/share/gc/shared/workgroup.hpp
@@ -90,7 +90,8 @@ // Distributes the task out to num_workers workers. // Returns when the task has been completed by all workers. - virtual void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers) = 0; + virtual void coordinator_execute_on_workers(AbstractGangTask* task, uint num_workers, + bool add_foreground_work) = 0; // Worker API. @@ -199,6 +200,27 @@ virtual AbstractGangWorker* allocate_worker(uint which) = 0; }; +// Temporarily try to set the number of active workers. +// It's not guaranteed that it succeeds, and users need to +// query the number of active workers. +class WithUpdatedActiveWorkers : public StackObj { +private: + AbstractWorkGang* const _gang; + const uint _old_active_workers; + +public: + WithUpdatedActiveWorkers(AbstractWorkGang* gang, uint requested_num_workers) : + _gang(gang), + _old_active_workers(gang->active_workers()) { + uint capped_num_workers = MIN2(requested_num_workers, gang->total_workers()); + gang->update_active_workers(capped_num_workers); + } + + ~WithUpdatedActiveWorkers() { + _gang->update_active_workers(_old_active_workers); + } +}; + // An class representing a gang of workers. class WorkGang: public AbstractWorkGang { // To get access to the GangTaskDispatcher instance. @@ -222,8 +244,9 @@ // Run a task with the given number of workers, returns // when the task is done. The number of workers must be at most the number of // active workers. Additional workers may be created if an insufficient - // number currently exists. - void run_task(AbstractGangTask* task, uint num_workers); + // number currently exists. If the add_foreground_work flag is true, the current thread + // is used to run the task too. + void run_task(AbstractGangTask* task, uint num_workers, bool add_foreground_work = false); protected: virtual AbstractGangWorker* allocate_worker(uint which);
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index d07fc1a..1d1d37f 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
@@ -2324,48 +2324,7 @@ assert(call->is_Call(), ""); mem = call->in(TypeFunc::Memory); } else if (in->Opcode() == Op_NeverBranch) { - Node* head = in->in(0); - assert(head->is_Region(), "unexpected infinite loop graph shape"); - - Node* phi_mem = NULL; - for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) { - Node* u = head->fast_out(j); - if (u->is_Phi() && u->bottom_type() == Type::MEMORY) { - if (_phase->C->get_alias_index(u->adr_type()) == _alias) { - assert(phi_mem == NULL || phi_mem->adr_type() == TypePtr::BOTTOM, ""); - phi_mem = u; - } else if (u->adr_type() == TypePtr::BOTTOM) { - assert(phi_mem == NULL || _phase->C->get_alias_index(phi_mem->adr_type()) == _alias, ""); - if (phi_mem == NULL) { - phi_mem = u; - } - } - } - } - if (phi_mem == NULL) { - for (uint j = 1; j < head->req(); j++) { - Node* tail = head->in(j); - if (!_phase->is_dominator(head, tail)) { - continue; - } - Node* c = tail; - while (c != head) { - if (c->is_SafePoint() && !c->is_CallLeaf()) { - Node* m =c->in(TypeFunc::Memory); - if (m->is_MergeMem()) { - m = m->as_MergeMem()->memory_at(_alias); - } - assert(mem == NULL || mem == m, "several memory states"); - mem = m; - } - c = _phase->idom(c); - } - assert(mem != NULL, "should have found safepoint"); - } - assert(mem != NULL, "should have found safepoint"); - } else { - mem = phi_mem; - } + mem = collect_memory_for_infinite_loop(in); } } } else { @@ -2583,6 +2542,67 @@ } } +Node* MemoryGraphFixer::collect_memory_for_infinite_loop(const Node* in) { + Node* mem = NULL; + Node* head = in->in(0); + assert(head->is_Region(), "unexpected infinite loop graph shape"); + + Node* phi_mem = NULL; + for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) { + Node* u = head->fast_out(j); + if (u->is_Phi() && u->bottom_type() == Type::MEMORY) { + if (_phase->C->get_alias_index(u->adr_type()) == _alias) { + assert(phi_mem == NULL || phi_mem->adr_type() == TypePtr::BOTTOM, ""); + phi_mem = u; + } else if (u->adr_type() == TypePtr::BOTTOM) { + assert(phi_mem == NULL || _phase->C->get_alias_index(phi_mem->adr_type()) == _alias, ""); + if (phi_mem == NULL) { + phi_mem = u; + } + } + } + } + if (phi_mem == NULL) { + ResourceMark rm; + Node_Stack stack(0); + stack.push(head, 1); + do { + Node* n = stack.node(); + uint i = stack.index(); + if (i >= n->req()) { + stack.pop(); + } else { + stack.set_index(i + 1); + Node* c = n->in(i); + assert(c != head, "should have found a safepoint on the way"); + if (stack.size() != 1 || _phase->is_dominator(head, c)) { + for (;;) { + if (c->is_Region()) { + stack.push(c, 1); + break; + } else if (c->is_SafePoint() && !c->is_CallLeaf()) { + Node* m = c->in(TypeFunc::Memory); + if (m->is_MergeMem()) { + m = m->as_MergeMem()->memory_at(_alias); + } + assert(mem == NULL || mem == m, "several memory states"); + mem = m; + break; + } else { + assert(c != c->in(0), ""); + c = c->in(0); + } + } + } + } + } while (stack.size() > 0); + assert(mem != NULL, "should have found safepoint"); + } else { + mem = phi_mem; + } + return mem; +} + Node* MemoryGraphFixer::get_ctrl(Node* n) const { Node* c = _phase->get_ctrl(n); if (n->is_Proj() && n->in(0) != NULL && n->in(0)->is_Call()) {
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp index 8a56bf8..c00e331 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
@@ -131,6 +131,8 @@ Node* find_mem(Node* ctrl, Node* n) const; void fix_mem(Node* ctrl, Node* region, Node* mem, Node* mem_for_ctrl, Node* mem_phi, Unique_Node_List& uses); int alias() const { return _alias; } + + Node* collect_memory_for_infinite_loop(const Node* in); }; class ShenandoahCompareAndSwapPNode : public CompareAndSwapPNode {
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index c198533..1a9f3be 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2013, 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2013, 2021, Red Hat, 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 @@ -89,8 +90,10 @@ while (!in_graceful_shutdown() && !should_terminate()) { // Figure out if we have pending requests. bool alloc_failure_pending = _alloc_failure_gc.is_set(); - bool explicit_gc_requested = _gc_requested.is_set() && is_explicit_gc(_requested_gc_cause); - bool implicit_gc_requested = _gc_requested.is_set() && !is_explicit_gc(_requested_gc_cause); + bool is_gc_requested = _gc_requested.is_set(); + GCCause::Cause requested_gc_cause = _requested_gc_cause; + bool explicit_gc_requested = is_gc_requested && is_explicit_gc(requested_gc_cause); + bool implicit_gc_requested = is_gc_requested && !is_explicit_gc(requested_gc_cause); // This control loop iteration have seen this much allocations. size_t allocs_seen = Atomic::xchg<size_t>(0, &_allocs_seen, memory_order_relaxed); @@ -124,7 +127,7 @@ } } else if (explicit_gc_requested) { - cause = _requested_gc_cause; + cause = requested_gc_cause; log_info(gc)("Trigger: Explicit GC request (%s)", GCCause::to_string(cause)); heuristics->record_requested_gc(); @@ -140,7 +143,7 @@ mode = stw_full; } } else if (implicit_gc_requested) { - cause = _requested_gc_cause; + cause = requested_gc_cause; log_info(gc)("Trigger: Implicit GC request (%s)", GCCause::to_string(cause)); heuristics->record_requested_gc(); @@ -536,8 +539,11 @@ size_t current_gc_id = get_gc_id(); size_t required_gc_id = current_gc_id + 1; while (current_gc_id < required_gc_id) { - _gc_requested.set(); + // Although setting gc request is under _gc_waiters_lock, but read side (run_service()) + // does not take the lock. We need to enforce following order, so that read side sees + // latest requested gc cause when the flag is set. _requested_gc_cause = cause; + _gc_requested.set(); ml.wait(); current_gc_id = get_gc_id(); }
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 9bcaab2..e4b90d8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
@@ -1735,7 +1735,9 @@ } case _degenerated_mark: - op_final_mark(); + if (is_concurrent_mark_in_progress()) { + op_final_mark(); + } if (cancelled_gc()) { op_degenerated_fail(); return;
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 245f200..2b5267e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2013, 2021, Red Hat, Inc. All rights reserved. * * 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
diff --git a/src/hotspot/share/gc/z/zCollectedHeap.hpp b/src/hotspot/share/gc/z/zCollectedHeap.hpp index dbac779..44db7a4 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.hpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
diff --git a/src/hotspot/share/include/jmm.h b/src/hotspot/share/include/jmm.h index 670955e..33438a3 100644 --- a/src/hotspot/share/include/jmm.h +++ b/src/hotspot/share/include/jmm.h
@@ -331,7 +331,8 @@ void (JNICALL *GetDiagnosticCommandArgumentsInfo) (JNIEnv *env, jstring commandName, - dcmdArgInfo *infoArray); + dcmdArgInfo *infoArray, + jint count); jstring (JNICALL *ExecuteDiagnosticCommand) (JNIEnv *env, jstring command);
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index e556e7c..bb7f252 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h
@@ -160,7 +160,7 @@ JVM_IsUseContainerSupport(void); JNIEXPORT void * JNICALL -JVM_LoadLibrary(const char *name); +JVM_LoadLibrary(const char *name, jboolean throwException); JNIEXPORT void JNICALL JVM_UnloadLibrary(void * handle);
diff --git a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp index f5d1595..bdb1dae 100644 --- a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp +++ b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp
@@ -494,13 +494,13 @@ interpreterState orig = istate; #endif - register intptr_t* topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */ - register address pc = istate->bcp(); - register jubyte opcode; - register intptr_t* locals = istate->locals(); - register ConstantPoolCache* cp = istate->constants(); // method()->constants()->cache() + intptr_t* topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */ + address pc = istate->bcp(); + jubyte opcode; + intptr_t* locals = istate->locals(); + ConstantPoolCache* cp = istate->constants(); // method()->constants()->cache() #ifdef LOTS_OF_REGS - register JavaThread* THREAD = istate->thread(); + JavaThread* THREAD = istate->thread(); #else #undef THREAD #define THREAD istate->thread() @@ -589,7 +589,7 @@ /* 0xF8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xFC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default }; - register uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0]; + uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0]; #endif /* USELABELS */ #ifdef ASSERT @@ -3487,12 +3487,6 @@ tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base); tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit); tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base); -#ifdef SPARC - tty->print_cr("last_Java_pc: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_pc); - tty->print_cr("frame_bottom: " INTPTR_FORMAT, (uintptr_t) this->_frame_bottom); - tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult); - tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult); -#endif #if !defined(ZERO) && defined(PPC) tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp); #endif // !ZERO
diff --git a/src/hotspot/share/interpreter/bytecodes.cpp b/src/hotspot/share/interpreter/bytecodes.cpp index e377e36..4035927 100644 --- a/src/hotspot/share/interpreter/bytecodes.cpp +++ b/src/hotspot/share/interpreter/bytecodes.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -471,7 +471,7 @@ def(_new , "new" , "bkk" , NULL , T_OBJECT , 1, true ); def(_newarray , "newarray" , "bc" , NULL , T_OBJECT , 0, true ); def(_anewarray , "anewarray" , "bkk" , NULL , T_OBJECT , 0, true ); - def(_arraylength , "arraylength" , "b" , NULL , T_VOID , 0, true ); + def(_arraylength , "arraylength" , "b" , NULL , T_INT , 0, true ); def(_athrow , "athrow" , "b" , NULL , T_VOID , -1, true ); def(_checkcast , "checkcast" , "bkk" , NULL , T_OBJECT , 0, true ); def(_instanceof , "instanceof" , "bkk" , NULL , T_INT , 0, true );
diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp index aeafba2..24e4c98 100644 --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp
@@ -1015,6 +1015,9 @@ nmethod* InterpreterRuntime::frequency_counter_overflow(JavaThread* thread, address branch_bcp) { + // Enable WXWrite: the function is called directly by interpreter. + MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); + nmethod* nm = frequency_counter_overflow_inner(thread, branch_bcp); assert(branch_bcp != NULL || nm == NULL, "always returns null for non OSR requests"); if (branch_bcp != NULL && nm != NULL) {
diff --git a/src/hotspot/share/interpreter/oopMapCache.cpp b/src/hotspot/share/interpreter/oopMapCache.cpp index 58af707..fae88cb 100644 --- a/src/hotspot/share/interpreter/oopMapCache.cpp +++ b/src/hotspot/share/interpreter/oopMapCache.cpp
@@ -241,6 +241,8 @@ } public: + void pass_byte() { /* ignore */ } + void pass_short() { /* ignore */ } void pass_int() { /* ignore */ } void pass_long() { /* ignore */ } void pass_float() { /* ignore */ }
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp index a54aee4..f0d4e79 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
@@ -385,7 +385,7 @@ _subsystem_callback = &callback; do_klasses(); } else { - LeakKlassWriter lkw(_leakp_writer, _artifacts, _class_unload); + LeakKlassWriter lkw(_leakp_writer, _class_unload); CompositeKlassWriter ckw(&lkw, &kw); CompositeKlassWriterRegistration ckwr(&ckw, ®); CompositeKlassCallback callback(&ckwr);
diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 4c40034..c92a341 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp
@@ -54,9 +54,8 @@ #include "jvmci/jvmciRuntime.hpp" #include "jvmci/jvmciJavaClasses.hpp" -JVMCIEnv::JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter): +JVMCIEnv::JVMCIEnv(CompileTask* task): _task(task), - _system_dictionary_modification_counter(system_dictionary_modification_counter), _failure_reason(NULL), _retryable(true) { @@ -421,14 +420,13 @@ // Dependencies must be checked when the system dictionary changes // or if we don't know whether it has changed (i.e., env == NULL). - bool counter_changed = env == NULL || env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); CompileTask* task = env == NULL ? NULL : env->task(); - Dependencies::DepType result = dependencies->validate_dependencies(task, counter_changed, failure_detail); + Dependencies::DepType result = dependencies->validate_dependencies(task, failure_detail); if (result == Dependencies::end_marker) { return JVMCIEnv::ok; } - if (!Dependencies::is_klass_type(result) || counter_changed) { + if (!Dependencies::is_klass_type(result)) { return JVMCIEnv::dependencies_failed; } // The dependencies were invalid at the time of installation
diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp index 8a8c207..511cbd6b 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.hpp +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp
@@ -37,6 +37,7 @@ // Bring the JVMCI compiler thread into the VM state. #define JVMCI_VM_ENTRY_MARK \ JavaThread* thread = JavaThread::current(); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ ResetNoHandleMark rnhm; \ HandleMarkCleaner __hm(thread); \ @@ -92,11 +93,10 @@ int method_index, Bytecodes::Code bc, InstanceKlass* loading_klass); - JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter); + JVMCIEnv(CompileTask* task); private: CompileTask* _task; - int _system_dictionary_modification_counter; // Compilation result values const char* _failure_reason;
diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 4951b35..7467eb7 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
@@ -239,10 +239,10 @@ nonstatic_field(MethodData, _data_size, int) \ nonstatic_field(MethodData, _data[0], intptr_t) \ nonstatic_field(MethodData, _parameters_type_data_di, int) \ - nonstatic_field(MethodData, _nof_decompiles, uint) \ - nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \ - nonstatic_field(MethodData, _nof_overflow_traps, uint) \ - nonstatic_field(MethodData, _trap_hist._array[0], u1) \ + nonstatic_field(MethodData, _compiler_counters._nof_decompiles, uint) \ + nonstatic_field(MethodData, _compiler_counters._nof_overflow_recompiles, uint) \ + nonstatic_field(MethodData, _compiler_counters._nof_overflow_traps, uint) \ + nonstatic_field(MethodData, _compiler_counters._trap_hist._array[0], u1) \ nonstatic_field(MethodData, _eflags, intx) \ nonstatic_field(MethodData, _arg_local, intx) \ nonstatic_field(MethodData, _arg_stack, intx) \ @@ -521,7 +521,7 @@ declare_constant(Deoptimization::Reason_not_compiled_exception_handler) \ declare_constant(Deoptimization::Reason_unresolved) \ declare_constant(Deoptimization::Reason_jsr_mismatch) \ - declare_constant(Deoptimization::Reason_LIMIT) \ + declare_constant(Deoptimization::Reason_TRAP_HISTORY_LENGTH) \ \ declare_constant(FieldInfo::access_flags_offset) \ declare_constant(FieldInfo::name_index_offset) \
diff --git a/src/hotspot/share/libadt/dict.cpp b/src/hotspot/share/libadt/dict.cpp index 19c4f46..14e358a 100644 --- a/src/hotspot/share/libadt/dict.cpp +++ b/src/hotspot/share/libadt/dict.cpp
@@ -305,9 +305,9 @@ // limited to MAXID characters in length. Experimental evidence on 150K of // C text shows excellent spreading of values for any size hash table. int hashstr(const void *t) { - register char c, k = 0; - register int32_t sum = 0; - register const char *s = (const char *)t; + char c, k = 0; + int32_t sum = 0; + const char *s = (const char *)t; while( ((c = *s++) != '\0') && (k < MAXID-1) ) { // Get characters till null or MAXID-1 c = (c<<1)+1; // Characters are always odd!
diff --git a/src/hotspot/share/libadt/set.cpp b/src/hotspot/share/libadt/set.cpp index caeed32..8880046 100644 --- a/src/hotspot/share/libadt/set.cpp +++ b/src/hotspot/share/libadt/set.cpp
@@ -64,7 +64,7 @@ uint len = 128; // Total string space char *buf = NEW_C_HEAP_ARRAY(char,len, mtCompiler);// Some initial string space - register char *s = buf; // Current working string pointer + char *s = buf; // Current working string pointer *s++ = '{'; *s = '\0'; @@ -116,8 +116,8 @@ // Set. Return the amount of text parsed in "len", or zero in "len". int Set::parse(const char *s) { - register char c; // Parse character - register const char *t = s; // Save the starting position of s. + char c; // Parse character + const char *t = s; // Save the starting position of s. do c = *s++; // Skip characters while( c && (c <= ' ') ); // Till no more whitespace or EOS if( c != '{' ) return 0; // Oops, not a Set openner
diff --git a/src/hotspot/share/libadt/vectset.cpp b/src/hotspot/share/libadt/vectset.cpp index ac870de..e61e670 100644 --- a/src/hotspot/share/libadt/vectset.cpp +++ b/src/hotspot/share/libadt/vectset.cpp
@@ -101,8 +101,8 @@ // Insert a member into an existing Set. Set &VectorSet::operator <<= (uint elem) { - register uint word = elem >> 5; // Get the longword offset - register uint32_t mask = 1L << (elem & 31); // Get bit mask + uint word = elem >> 5; // Get the longword offset + uint32_t mask = 1L << (elem & 31); // Get bit mask if( word >= size ) // Need to grow set? grow(elem+1); // Then grow it @@ -114,10 +114,10 @@ // Delete a member from an existing Set. Set &VectorSet::operator >>= (uint elem) { - register uint word = elem >> 5; // Get the longword offset + uint word = elem >> 5; // Get the longword offset if( word >= size ) // Beyond the last? return *this; // Then it's clear & return clear - register uint32_t mask = 1L << (elem & 31); // Get bit mask + uint32_t mask = 1L << (elem & 31); // Get bit mask data[word] &= ~mask; // Clear bit return *this; } @@ -128,8 +128,8 @@ { // NOTE: The intersection is never any larger than the smallest set. if( s.size < size ) size = s.size; // Get smaller size - register uint32_t *u1 = data; // Pointer to the destination data - register uint32_t *u2 = s.data; // Pointer to the source data + uint32_t *u1 = data; // Pointer to the destination data + uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<size; i++) // For data in set *u1++ &= *u2++; // Copy and AND longwords return *this; // Return set @@ -147,9 +147,9 @@ VectorSet &VectorSet::operator |= (const VectorSet &s) { // This many words must be unioned - register uint cnt = ((size<s.size)?size:s.size); - register uint32_t *u1 = data; // Pointer to the destination data - register uint32_t *u2 = s.data; // Pointer to the source data + uint cnt = ((size<s.size)?size:s.size); + uint32_t *u1 = data; // Pointer to the destination data + uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<cnt; i++) // Copy and OR the two sets *u1++ |= *u2++; if( size < s.size ) { // Is set 2 larger than set 1? @@ -172,9 +172,9 @@ VectorSet &VectorSet::operator -= (const VectorSet &s) { // This many words must be unioned - register uint cnt = ((size<s.size)?size:s.size); - register uint32_t *u1 = data; // Pointer to the destination data - register uint32_t *u2 = s.data; // Pointer to the source data + uint cnt = ((size<s.size)?size:s.size); + uint32_t *u1 = data; // Pointer to the destination data + uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<cnt; i++ ) // For data in set *u1++ &= ~(*u2++); // A <-- A & ~B with longwords return *this; // Return new set @@ -195,17 +195,17 @@ // 1X -- B is a subset of A int VectorSet::compare (const VectorSet &s) const { - register uint32_t *u1 = data; // Pointer to the destination data - register uint32_t *u2 = s.data; // Pointer to the source data - register uint32_t AnotB = 0, BnotA = 0; + uint32_t *u1 = data; // Pointer to the destination data + uint32_t *u2 = s.data; // Pointer to the source data + uint32_t AnotB = 0, BnotA = 0; // This many words must be unioned - register uint cnt = ((size<s.size)?size:s.size); + uint cnt = ((size<s.size)?size:s.size); // Get bits for both sets uint i; // Exit value of loop for( i=0; i<cnt; i++ ) { // For data in BOTH sets - register uint32_t A = *u1++; // Data from one guy - register uint32_t B = *u2++; // Data from other guy + uint32_t A = *u1++; // Data from one guy + uint32_t B = *u2++; // Data from other guy AnotB |= (A & ~B); // Compute bits in A not B BnotA |= (B & ~A); // Compute bits in B not A } @@ -245,9 +245,9 @@ const VectorSet &s = *(set.asVectorSet()); // NOTE: The intersection is never any larger than the smallest set. - register uint small_size = ((size<s.size)?size:s.size); - register uint32_t *u1 = data; // Pointer to the destination data - register uint32_t *u2 = s.data; // Pointer to the source data + uint small_size = ((size<s.size)?size:s.size); + uint32_t *u1 = data; // Pointer to the destination data + uint32_t *u2 = s.data; // Pointer to the source data for( uint i=0; i<small_size; i++) // For data in set if( *u1++ & *u2++ ) // If any elements in common return 0; // Then not disjoint @@ -286,11 +286,11 @@ // Test for membership. A Zero/Non-Zero value is returned! int VectorSet::operator[](uint elem) const { - register uint word = elem >> 5; // Get the longword offset - if( word >= size ) // Beyond the last? - return 0; // Then it's clear - register uint32_t mask = 1L << (elem & 31); // Get bit mask - return ((data[word] & mask))!=0; // Return the sense of the bit + uint word = elem >> 5; // Get the longword offset + if( word >= size ) // Beyond the last? + return 0; // Then it's clear + uint32_t mask = 1L << (elem & 31); // Get bit mask + return ((data[word] & mask))!=0; // Return the sense of the bit } //------------------------------getelem----------------------------------------
diff --git a/src/hotspot/share/memory/arena.cpp b/src/hotspot/share/memory/arena.cpp index e5df5a7..c478d0b 100644 --- a/src/hotspot/share/memory/arena.cpp +++ b/src/hotspot/share/memory/arena.cpp
@@ -337,7 +337,7 @@ // Total of all Chunks in arena size_t Arena::used() const { size_t sum = _chunk->length() - (_max-_hwm); // Size leftover in this Chunk - register Chunk *k = _first; + Chunk *k = _first; while( k != _chunk) { // Whilst have Chunks in a row sum += k->length(); // Total size of this Chunk k = k->next(); // Bump along to next Chunk
diff --git a/src/hotspot/share/memory/heapInspection.cpp b/src/hotspot/share/memory/heapInspection.cpp index ee6504a..bb3076d 100644 --- a/src/hotspot/share/memory/heapInspection.cpp +++ b/src/hotspot/share/memory/heapInspection.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "oops/reflectionAccessorImplKlassHelper.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" @@ -236,6 +237,41 @@ return _size_of_instances_in_words; } +// Return false if the entry could not be recorded on account +// of running out of space required to create a new entry. +bool KlassInfoTable::merge_entry(const KlassInfoEntry* cie) { + Klass* k = cie->klass(); + KlassInfoEntry* elt = lookup(k); + // elt may be NULL if it's a new klass for which we + // could not allocate space for a new entry in the hashtable. + if (elt != NULL) { + elt->set_count(elt->count() + cie->count()); + elt->set_words(elt->words() + cie->words()); + _size_of_instances_in_words += cie->words(); + return true; + } + return false; +} + +class KlassInfoTableMergeClosure : public KlassInfoClosure { +private: + KlassInfoTable* _dest; + bool _success; +public: + KlassInfoTableMergeClosure(KlassInfoTable* table) : _dest(table), _success(true) {} + void do_cinfo(KlassInfoEntry* cie) { + _success &= _dest->merge_entry(cie); + } + bool success() { return _success; } +}; + +// merge from table +bool KlassInfoTable::merge(KlassInfoTable* table) { + KlassInfoTableMergeClosure closure(this); + table->iterate(&closure); + return closure.success(); +} + int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) { return (*e1)->compare(*e1,*e2); } @@ -687,7 +723,7 @@ class RecordInstanceClosure : public ObjectClosure { private: KlassInfoTable* _cit; - size_t _missed_count; + uintx _missed_count; BoolObjectClosure* _filter; public: RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) : @@ -701,7 +737,7 @@ } } - size_t missed_count() { return _missed_count; } + uintx missed_count() { return _missed_count; } private: bool should_visit(oop obj) { @@ -709,15 +745,73 @@ } }; -size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter) { +// Heap inspection for every worker. +// When native OOM happens for KlassInfoTable, set _success to false. +void ParHeapInspectTask::work(uint worker_id) { + uintx missed_count = 0; + bool merge_success = true; + if (!Atomic::load(&_success)) { + // other worker has failed on parallel iteration. + return; + } + + KlassInfoTable cit(false); + if (cit.allocation_failed()) { + // fail to allocate memory, stop parallel mode + Atomic::store(false, &_success); + return; + } + RecordInstanceClosure ric(&cit, _filter); + _poi->object_iterate(&ric, worker_id); + missed_count = ric.missed_count(); + { + MutexLocker x(&_mutex); + merge_success = _shared_cit->merge(&cit); + } + if (merge_success) { + Atomic::add(missed_count, &_missed_count); + } else { + Atomic::store(false, &_success); + } +} + +uintx HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter, uint parallel_thread_num) { + + // Try parallel first. + if (parallel_thread_num > 1) { + ResourceMark rm; + WorkGang* gang = Universe::heap()->get_safepoint_workers(); + if (gang != NULL) { + // The GC provided a WorkGang to be used during a safepoint. + + // Can't run with more threads than provided by the WorkGang. + WithUpdatedActiveWorkers update_and_restore(gang, parallel_thread_num); + + ParallelObjectIterator* poi = Universe::heap()->parallel_object_iterator(gang->active_workers()); + if (poi != NULL) { + // The GC supports parallel object iteration. + + ParHeapInspectTask task(poi, cit, filter); + // Run task with the active workers. + gang->run_task(&task); + + delete poi; + if (task.success()) { + return task.missed_count(); + } + } + } + } + ResourceMark rm; + // If no parallel iteration available, run serially. RecordInstanceClosure ric(cit, filter); Universe::heap()->safe_object_iterate(&ric); return ric.missed_count(); } -void HeapInspection::heap_inspection(outputStream* st) { +void HeapInspection::heap_inspection(outputStream* st, uint parallel_thread_num) { ResourceMark rm; if (_print_help) { @@ -741,9 +835,9 @@ KlassInfoTable cit(_print_class_stats); if (!cit.allocation_failed()) { // populate table with object allocation info - size_t missed_count = populate_table(&cit); + uintx missed_count = populate_table(&cit, NULL, parallel_thread_num); if (missed_count != 0) { - st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT + st->print_cr("WARNING: Ran out of C-heap; undercounted " UINTX_FORMAT " total instances in data below", missed_count); }
diff --git a/src/hotspot/share/memory/heapInspection.hpp b/src/hotspot/share/memory/heapInspection.hpp index d8935dc..0c4fb8f 100644 --- a/src/hotspot/share/memory/heapInspection.hpp +++ b/src/hotspot/share/memory/heapInspection.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,9 @@ #include "oops/oop.hpp" #include "oops/annotations.hpp" #include "utilities/macros.hpp" +#include "gc/shared/workgroup.hpp" + +class ParallelObjectIterator; #if INCLUDE_SERVICES @@ -261,6 +264,8 @@ void iterate(KlassInfoClosure* cic); bool allocation_failed() { return _buckets == NULL; } size_t size_of_instances_in_words() const; + bool merge(KlassInfoTable* table); + bool merge_entry(const KlassInfoEntry* cie); friend class KlassInfoHisto; friend class KlassHierarchy; @@ -364,11 +369,45 @@ bool print_class_stats, const char *columns) : _csv_format(csv_format), _print_help(print_help), _print_class_stats(print_class_stats), _columns(columns) {} - void heap_inspection(outputStream* st) NOT_SERVICES_RETURN; - size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL) NOT_SERVICES_RETURN_(0); + void heap_inspection(outputStream* st, uint parallel_thread_num = 1) NOT_SERVICES_RETURN; + uintx populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL, uint parallel_thread_num = 1) NOT_SERVICES_RETURN_(0); static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN; private: void iterate_over_heap(KlassInfoTable* cit, BoolObjectClosure* filter = NULL); }; +// Parallel heap inspection task. Parallel inspection can fail due to +// a native OOM when allocating memory for TL-KlassInfoTable. +// _success will be set false on an OOM, and serial inspection tried. +class ParHeapInspectTask : public AbstractGangTask { + private: + ParallelObjectIterator* _poi; + KlassInfoTable* _shared_cit; + BoolObjectClosure* _filter; + uintx _missed_count; + bool _success; + Mutex _mutex; + + public: + ParHeapInspectTask(ParallelObjectIterator* poi, + KlassInfoTable* shared_cit, + BoolObjectClosure* filter) : + AbstractGangTask("Iterating heap"), + _poi(poi), + _shared_cit(shared_cit), + _filter(filter), + _missed_count(0), + _success(true), + _mutex(Mutex::leaf, "Parallel heap iteration data merge lock") {} + + uintx missed_count() const { + return _missed_count; + } + + bool success() { + return _success; + } + + virtual void work(uint worker_id); +}; #endif // SHARE_VM_MEMORY_HEAPINSPECTION_HPP
diff --git a/src/hotspot/share/memory/virtualspace.cpp b/src/hotspot/share/memory/virtualspace.cpp index 2ff39ac..d67f624 100644 --- a/src/hotspot/share/memory/virtualspace.cpp +++ b/src/hotspot/share/memory/virtualspace.cpp
@@ -196,7 +196,8 @@ base = NULL; } } else { - base = os::reserve_memory(size, NULL, alignment, _fd_for_heap); + base = MACOS_ONLY(os::reserve_memory(size, NULL, alignment, _fd_for_heap, _executable)) + NOT_MACOS(os::reserve_memory(size, NULL, alignment, _fd_for_heap)); } if (base == NULL) return; @@ -990,7 +991,8 @@ assert(middle_high_boundary() <= aligned_upper_new_high && aligned_upper_new_high + upper_needs <= upper_high_boundary(), "must not shrink beyond region"); - if (!os::uncommit_memory(aligned_upper_new_high, upper_needs)) { + if (MACOS_ONLY(!os::uncommit_memory(aligned_upper_new_high, upper_needs, _executable)) + NOT_MACOS(!os::uncommit_memory(aligned_upper_new_high, upper_needs))) { debug_only(warning("os::uncommit_memory failed")); return; } else { @@ -1001,7 +1003,8 @@ assert(lower_high_boundary() <= aligned_middle_new_high && aligned_middle_new_high + middle_needs <= middle_high_boundary(), "must not shrink beyond region"); - if (!os::uncommit_memory(aligned_middle_new_high, middle_needs)) { + if (MACOS_ONLY(!os::uncommit_memory(aligned_middle_new_high, middle_needs, _executable)) + NOT_MACOS(!os::uncommit_memory(aligned_middle_new_high, middle_needs))) { debug_only(warning("os::uncommit_memory failed")); return; } else { @@ -1012,7 +1015,8 @@ assert(low_boundary() <= aligned_lower_new_high && aligned_lower_new_high + lower_needs <= lower_high_boundary(), "must not shrink beyond region"); - if (!os::uncommit_memory(aligned_lower_new_high, lower_needs)) { + if (MACOS_ONLY(!os::uncommit_memory(aligned_lower_new_high, lower_needs, _executable)) + NOT_MACOS(!os::uncommit_memory(aligned_lower_new_high, lower_needs))) { debug_only(warning("os::uncommit_memory failed")); return; } else {
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 34aed3f..9a6a668 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -1839,25 +1839,14 @@ return NULL; } -/* jni_id_for_impl for jfieldIds only */ -JNIid* InstanceKlass::jni_id_for_impl(int offset) { - MutexLocker ml(JfieldIdCreation_lock); - // Retry lookup after we got the lock - JNIid* probe = jni_ids() == NULL ? NULL : jni_ids()->find(offset); - if (probe == NULL) { - // Slow case, allocate new static field identifier - probe = new JNIid(this, offset, jni_ids()); - set_jni_ids(probe); - } - return probe; -} - - /* jni_id_for for jfieldIds only */ JNIid* InstanceKlass::jni_id_for(int offset) { + MutexLocker ml(JfieldIdCreation_lock); JNIid* probe = jni_ids() == NULL ? NULL : jni_ids()->find(offset); if (probe == NULL) { - probe = jni_id_for_impl(offset); + // Allocate new static field identifier + probe = new JNIid(this, offset, jni_ids()); + set_jni_ids(probe); } return probe; } @@ -2164,6 +2153,7 @@ for (int m = 0; m < methods()->length(); m++) { MethodData* mdo = methods()->at(m)->method_data(); if (mdo != NULL) { + MutexLockerEx ml(SafepointSynchronize::is_at_safepoint() ? NULL : mdo->extra_data_lock()); mdo->clean_method_data(/*always_clean*/false); } } @@ -2262,7 +2252,9 @@ it->push(&_transitive_interfaces); it->push(&_method_ordering); it->push(&_default_vtable_indices); - it->push(&_fields); + + // _fields might be written into by Rewriter::scan_method() -> fd.set_has_initialized_final_update() + it->push(&_fields, MetaspaceClosure::_writable); if (itable_length() > 0) { itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable(); @@ -2377,6 +2369,9 @@ constants()->restore_unshareable_info(CHECK); if (array_klasses() != NULL) { + // To get a consistent list of classes we need MultiArray_lock to ensure + // array classes aren't observed while they are being restored. + MutexLocker ml(MultiArray_lock); // Array classes have null protection domain. // --> see ArrayKlass::complete_create_array_klass() array_klasses()->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 4454171..653541f 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -738,9 +738,18 @@ } #if INCLUDE_JVMTI - // Redefinition locking. Class can only be redefined by one thread at a time. - bool is_being_redefined() const { return _is_being_redefined; } - void set_is_being_redefined(bool value) { _is_being_redefined = value; } + // The flag is in access_flags so that it can be set and reset using atomic + // operations, and not be reset by other misc_flag settings. + bool is_being_redefined() const { + return _access_flags.is_being_redefined(); + } + void set_is_being_redefined(bool value) { + if (value) { + _access_flags.set_is_being_redefined(); + } else { + _access_flags.clear_is_being_redefined(); + } + } // RedefineClasses() support for previous versions: void add_previous_version(InstanceKlass* ik, int emcp_method_count); @@ -1291,8 +1300,6 @@ void initialize_impl (TRAPS); void initialize_super_interfaces (TRAPS); void eager_initialize_impl (); - /* jni_id_for_impl for jfieldID only */ - JNIid* jni_id_for_impl (int offset); // Returns the array class for the n'th dimension Klass* array_klass_impl(bool or_null, int n, TRAPS);
diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index b77a19d..1d1c524 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp
@@ -347,19 +347,17 @@ static ByteSize access_flags_offset() { return in_ByteSize(offset_of(Klass, _access_flags)); } // Unpacking layout_helper: - enum { - _lh_neutral_value = 0, // neutral non-array non-instance value - _lh_instance_slow_path_bit = 0x01, - _lh_log2_element_size_shift = BitsPerByte*0, - _lh_log2_element_size_mask = BitsPerLong-1, - _lh_element_type_shift = BitsPerByte*1, - _lh_element_type_mask = right_n_bits(BitsPerByte), // shifted mask - _lh_header_size_shift = BitsPerByte*2, - _lh_header_size_mask = right_n_bits(BitsPerByte), // shifted mask - _lh_array_tag_bits = 2, - _lh_array_tag_shift = BitsPerInt - _lh_array_tag_bits, - _lh_array_tag_obj_value = ~0x01 // 0x80000000 >> 30 - }; + static const int _lh_neutral_value = 0; // neutral non-array non-instance value + static const int _lh_instance_slow_path_bit = 0x01; + static const int _lh_log2_element_size_shift = BitsPerByte*0; + static const int _lh_log2_element_size_mask = BitsPerLong-1; + static const int _lh_element_type_shift = BitsPerByte*1; + static const int _lh_element_type_mask = right_n_bits(BitsPerByte); // shifted mask + static const int _lh_header_size_shift = BitsPerByte*2; + static const int _lh_header_size_mask = right_n_bits(BitsPerByte); // shifted mask + static const int _lh_array_tag_bits = 2; + static const int _lh_array_tag_shift = BitsPerInt - _lh_array_tag_bits; + static const int _lh_array_tag_obj_value = ~0x01; // 0x80000000 >> 30 static const unsigned int _lh_array_tag_type_value = 0Xffffffff; // ~0x00, // 0xC0000000 >> 30
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 576da96..b55918d 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp
@@ -251,14 +251,11 @@ if (is_native() && bcp == 0) { return 0; } -#ifdef ASSERT - { - ResourceMark rm; - assert(is_native() && bcp == code_base() || contains(bcp) || VMError::is_error_reported(), - "bcp doesn't belong to this method: bcp: " INTPTR_FORMAT ", method: %s", - p2i(bcp), name_and_sig_as_C_string()); - } -#endif + // Do not have a ResourceMark here because AsyncGetCallTrace stack walking code + // may call this after interrupting a nested ResourceMark. + assert(is_native() && bcp == code_base() || contains(bcp) || VMError::is_error_reported(), + "bcp doesn't belong to this method. bcp: " INTPTR_FORMAT, p2i(bcp)); + return bcp - code_base(); } @@ -1956,7 +1953,6 @@ Thread *thread = Thread::current(); *method->bcp_from(_bci) = Bytecodes::_breakpoint; method->incr_number_of_breakpoints(thread); - SystemDictionary::notice_modification(); { // Deoptimize all dependents on this method HandleMark hm(thread);
diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index 6b99eb1..f3a645a 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp
@@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "ci/ciMethodData.hpp" #include "classfile/systemDictionary.hpp" #include "compiler/compilerOracle.hpp" #include "interpreter/bytecode.hpp" @@ -709,7 +710,7 @@ int size = MethodData::compute_allocation_size_in_words(method); return new (loader_data, size, MetaspaceObj::MethodDataType, THREAD) - MethodData(method(), size, THREAD); + MethodData(method()); } int MethodData::bytecode_cell_count(Bytecodes::Code code) { @@ -1131,11 +1132,11 @@ } // Initialize the MethodData* corresponding to a given method. -MethodData::MethodData(const methodHandle& method, int size, TRAPS) - : _extra_data_lock(Monitor::leaf, "MDO extra data lock"), +MethodData::MethodData(const methodHandle& method) + : _method(method()), + _extra_data_lock(Mutex::leaf, "MDO extra data lock"), + _compiler_counters(method()), _parameters_type_data_di(parameters_uninitialized) { - // Set the method back-pointer. - _method = method(); initialize(); } @@ -1144,7 +1145,6 @@ ResourceMark rm; init(); - set_creation_mileage(mileage_of(method())); // Go through the bytecodes and allocate and initialize the // corresponding data cells. @@ -1244,14 +1244,8 @@ } #endif - // Initialize flags and trap history. - _nof_decompiles = 0; - _nof_overflow_recompiles = 0; - _nof_overflow_traps = 0; + // Initialize escape flags. clear_escape_info(); - assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align"); - Copy::zero_to_words((HeapWord*) &_trap_hist, - sizeof(_trap_hist) / sizeof(HeapWord)); } // Get a measure of how much mileage the method has on it. @@ -1656,11 +1650,6 @@ } } -class CleanExtraDataClosure : public StackObj { -public: - virtual bool is_live(Method* m) = 0; -}; - // Check for entries that reference an unloaded method class CleanExtraDataKlassClosure : public CleanExtraDataClosure { bool _always_clean;
diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp index 850f333..e4a413b 100644 --- a/src/hotspot/share/oops/methodData.hpp +++ b/src/hotspot/share/oops/methodData.hpp
@@ -31,7 +31,9 @@ #include "oops/method.hpp" #include "oops/oop.hpp" #include "runtime/atomic.hpp" +#include "runtime/deoptimization.hpp" #include "utilities/align.hpp" +#include "utilities/copy.hpp" #if INCLUDE_JVMCI #include "jvmci/jvmci_globals.hpp" #endif @@ -1943,7 +1945,13 @@ // adjusted in the event of a change in control flow. // -class CleanExtraDataClosure; +class CleanExtraDataClosure : public StackObj { +public: + virtual bool is_live(Method* m) = 0; +}; + + +class ciMethodData; class MethodData : public Metadata { friend class VMStructs; @@ -1951,6 +1959,7 @@ private: friend class ProfileData; friend class TypeEntriesAtCall; + friend class ciMethodData; // If you add a new field that points to any metaspace object, you // must add this field to MethodData::metaspace_pointers_do(). @@ -1966,28 +1975,95 @@ Mutex _extra_data_lock; - MethodData(const methodHandle& method, int size, TRAPS); + MethodData(const methodHandle& method); public: static MethodData* allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS); - MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData bool is_methodData() const volatile { return true; } void initialize(); // Whole-method sticky bits and flags enum { - _trap_hist_limit = 24 JVMCI_ONLY(+5), // decoupled from Deoptimization::Reason_LIMIT + _trap_hist_limit = Deoptimization::Reason_TRAP_HISTORY_LENGTH, _trap_hist_mask = max_jubyte, _extra_data_count = 4 // extra DataLayout headers, for trap history }; // Public flag values + + // Compiler-related counters. + class CompilerCounters { + friend class VMStructs; + friend class JVMCIVMStructs; + + int _creation_mileage; // method mileage at MDO creation + uint _nof_decompiles; // count of all nmethod removals + uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits + uint _nof_overflow_traps; // trap count, excluding _trap_hist + union { + intptr_t _align; + // JVMCI separates trap history for OSR compilations from normal compilations + u1 _array[JVMCI_ONLY(2 *) MethodData::_trap_hist_limit]; + } _trap_hist; + + void init_trap_hist() { + STATIC_ASSERT(sizeof(_trap_hist) % HeapWordSize == 0); // "align" + uint size_in_words = sizeof(_trap_hist) / HeapWordSize; + Copy::zero_to_words((HeapWord*) &_trap_hist, size_in_words); + } + public: + CompilerCounters(Method* m) : _creation_mileage(MethodData::mileage_of(m)), + _nof_decompiles(0), _nof_overflow_recompiles(0), _nof_overflow_traps(0) { + init_trap_hist(); + } + CompilerCounters() : _creation_mileage(0), // for ciMethodData + _nof_decompiles(0), _nof_overflow_recompiles(0), _nof_overflow_traps(0) { + init_trap_hist(); + } + + int creation_mileage() const { return _creation_mileage; } + + // Return (uint)-1 for overflow. + uint trap_count(int reason) const { + assert((uint)reason < ARRAY_SIZE(_trap_hist._array), "oob"); + return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; + } + + uint inc_trap_count(int reason) { + // Count another trap, anywhere in this method. + assert(reason >= 0, "must be single trap"); + assert((uint)reason < ARRAY_SIZE(_trap_hist._array), "oob"); + uint cnt1 = 1 + _trap_hist._array[reason]; + if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow... + _trap_hist._array[reason] = cnt1; + return cnt1; + } else { + return _trap_hist_mask + (++_nof_overflow_traps); + } + } + + uint overflow_trap_count() const { + return _nof_overflow_traps; + } + uint overflow_recompile_count() const { + return _nof_overflow_recompiles; + } + uint inc_overflow_recompile_count() { + return ++_nof_overflow_recompiles; + } + uint decompile_count() const { + return _nof_decompiles; + } + uint inc_decompile_count() { + return ++_nof_decompiles; + } + + // Support for code generation + static ByteSize trap_history_offset() { + return byte_offset_of(CompilerCounters, _trap_hist._array); + } + }; + private: - uint _nof_decompiles; // count of all nmethod removals - uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits - uint _nof_overflow_traps; // trap count, excluding _trap_hist - union { - intptr_t _align; - u1 _array[JVMCI_ONLY(2 *) _trap_hist_limit]; - } _trap_hist; + CompilerCounters _compiler_counters; // Support for interprocedural escape analysis, from Thomas Kotzmann. intx _eflags; // flags on escape information @@ -1995,8 +2071,6 @@ intx _arg_stack; // bit set of stack-allocatable arguments intx _arg_returned; // bit set of returned arguments - int _creation_mileage; // method mileage at MDO creation - // How many invocations has this MDO seen? // These counters are used to determine the exact age of MDO. // We need those because in tiered a method can be concurrently @@ -2036,10 +2110,6 @@ // parameter profiling. enum { no_parameters = -2, parameters_uninitialized = -1 }; int _parameters_type_data_di; - int parameters_size_in_bytes() const { - ParametersTypeData* param = parameters_type_data(); - return param == NULL ? 0 : param->size_in_bytes(); - } // Beginning of the data entries intptr_t _data[1]; @@ -2116,11 +2186,12 @@ static bool profile_parameters_jsr292_only(); static bool profile_all_parameters(); - void clean_extra_data(CleanExtraDataClosure* cl); void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false); void verify_extra_data_clean(CleanExtraDataClosure* cl); public: + void clean_extra_data(CleanExtraDataClosure* cl); + static int header_size() { return sizeof(MethodData)/wordSize; } @@ -2145,8 +2216,7 @@ void collect_statistics(KlassSizeStats *sz) const; #endif - int creation_mileage() const { return _creation_mileage; } - void set_creation_mileage(int x) { _creation_mileage = x; } + int creation_mileage() const { return _compiler_counters.creation_mileage(); } int invocation_count() { if (invocation_counter()->carry()) { @@ -2250,6 +2320,11 @@ return _data_size; } + int parameters_size_in_bytes() const { + ParametersTypeData* param = parameters_type_data(); + return param == NULL ? 0 : param->size_in_bytes(); + } + // Accessors Method* method() const { return _method; } @@ -2308,42 +2383,33 @@ // Return (uint)-1 for overflow. uint trap_count(int reason) const { - assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob"); - return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; + return _compiler_counters.trap_count(reason); } // For loops: static uint trap_reason_limit() { return _trap_hist_limit; } static uint trap_count_limit() { return _trap_hist_mask; } uint inc_trap_count(int reason) { - // Count another trap, anywhere in this method. - assert(reason >= 0, "must be single trap"); - assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob"); - uint cnt1 = 1 + _trap_hist._array[reason]; - if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow... - _trap_hist._array[reason] = cnt1; - return cnt1; - } else { - return _trap_hist_mask + (++_nof_overflow_traps); - } + return _compiler_counters.inc_trap_count(reason); } uint overflow_trap_count() const { - return _nof_overflow_traps; + return _compiler_counters.overflow_trap_count(); } uint overflow_recompile_count() const { - return _nof_overflow_recompiles; + return _compiler_counters.overflow_recompile_count(); } - void inc_overflow_recompile_count() { - _nof_overflow_recompiles += 1; + uint inc_overflow_recompile_count() { + return _compiler_counters.inc_overflow_recompile_count(); } uint decompile_count() const { - return _nof_decompiles; + return _compiler_counters.decompile_count(); } - void inc_decompile_count() { - _nof_decompiles += 1; - if (decompile_count() > (uint)PerMethodRecompilationCutoff) { + uint inc_decompile_count() { + uint dec_count = _compiler_counters.inc_decompile_count(); + if (dec_count > (uint)PerMethodRecompilationCutoff) { method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); } + return dec_count; } uint tenure_traps() const { return _tenure_traps; @@ -2369,7 +2435,7 @@ } static ByteSize trap_history_offset() { - return byte_offset_of(MethodData, _trap_hist._array); + return byte_offset_of(MethodData, _compiler_counters) + CompilerCounters::trap_history_offset(); } static ByteSize invocation_counter_offset() {
diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp index 59a02fb..7b2189c 100644 --- a/src/hotspot/share/opto/callGenerator.cpp +++ b/src/hotspot/share/opto/callGenerator.cpp
@@ -96,14 +96,6 @@ Parse parser(jvms, method(), _expected_uses); // Grab signature for matching/allocation -#ifdef ASSERT - if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) { - MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag); - assert(C->env()->system_dictionary_modification_counter_changed(), - "Must invalidate if TypeFuncs differ"); - } -#endif - GraphKit& exits = parser.exits(); if (C->failing()) {
diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index 836baca..32ca753 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp
@@ -2006,13 +2006,13 @@ // Phi(...MergeMem(m0, m1:AT1, m2:AT2)...) into // MergeMem(Phi(...m0...), Phi:AT1(...m1...), Phi:AT2(...m2...)) PhaseIterGVN* igvn = phase->is_IterGVN(); + assert(igvn != NULL, "sanity check"); Node* hook = new Node(1); PhiNode* new_base = (PhiNode*) clone(); // Must eagerly register phis, since they participate in loops. - if (igvn) { - igvn->register_new_node_with_optimizer(new_base); - hook->add_req(new_base); - } + igvn->register_new_node_with_optimizer(new_base); + hook->add_req(new_base); + MergeMemNode* result = MergeMemNode::make(new_base); for (uint i = 1; i < req(); ++i) { Node *ii = in(i); @@ -2024,10 +2024,8 @@ if (mms.is_empty()) { Node* new_phi = new_base->slice_memory(mms.adr_type(phase->C)); made_new_phi = true; - if (igvn) { - igvn->register_new_node_with_optimizer(new_phi); - hook->add_req(new_phi); - } + igvn->register_new_node_with_optimizer(new_phi); + hook->add_req(new_phi); mms.set_memory(new_phi); } Node* phi = mms.memory(); @@ -2045,6 +2043,13 @@ } } } + // Already replace this phi node to cut it off from the graph to not interfere in dead loop checks during the + // transformations of the new phi nodes below. Otherwise, we could wrongly conclude that there is no dead loop + // because we are finding this phi node again. Also set the type of the new MergeMem node in case we are also + // visiting it in the transformations below. + igvn->replace_node(this, result); + igvn->set_type(result, result->bottom_type()); + // now transform the new nodes, and return the mergemem for (MergeMemStream mms(result); mms.next_non_empty(); ) { Node* phi = mms.memory(); @@ -2401,7 +2406,7 @@ //------------------------------Ideal------------------------------------------ // Check for no longer being part of a loop Node *NeverBranchNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (can_reshape && !in(0)->is_Loop()) { + if (can_reshape && !in(0)->is_Region()) { // Dead code elimination can sometimes delete this projection so // if it's not there, there's nothing to do. Node* fallthru = proj_out_or_null(0);
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 027b151..3a420cd 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp
@@ -2285,10 +2285,6 @@ if (failing()) return; } - // Now that all inlining is over, cut edge from root to loop - // safepoints - remove_root_to_sfpts_edges(igvn); - // Remove the speculative part of types and clean up the graph from // the extra CastPP nodes whose only purpose is to carry them. Do // that early so that optimizations are not disrupted by the extra @@ -2313,6 +2309,10 @@ igvn.optimize(); } + // Now that all inlining is over and no PhaseRemoveUseless will run, cut edge from root to loop + // safepoints + remove_root_to_sfpts_edges(igvn); + // Perform escape analysis if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { if (has_loops()) {
diff --git a/src/hotspot/share/opto/convertnode.cpp b/src/hotspot/share/opto/convertnode.cpp index 59291ee..ee2373d 100644 --- a/src/hotspot/share/opto/convertnode.cpp +++ b/src/hotspot/share/opto/convertnode.cpp
@@ -108,8 +108,10 @@ //------------------------------Ideal------------------------------------------ // If converting to an int type, skip any rounding nodes Node *ConvD2INode::Ideal(PhaseGVN *phase, bool can_reshape) { - if( in(1)->Opcode() == Op_RoundDouble ) - set_req(1,in(1)->in(1)); + if (in(1)->Opcode() == Op_RoundDouble) { + set_req(1, in(1)->in(1)); + return this; + } return NULL; } @@ -142,8 +144,10 @@ //------------------------------Ideal------------------------------------------ // If converting to an int type, skip any rounding nodes Node *ConvD2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if( in(1)->Opcode() == Op_RoundDouble ) - set_req(1,in(1)->in(1)); + if (in(1)->Opcode() == Op_RoundDouble) { + set_req(1, in(1)->in(1)); + return this; + } return NULL; } @@ -179,8 +183,10 @@ //------------------------------Ideal------------------------------------------ // If converting to an int type, skip any rounding nodes Node *ConvF2INode::Ideal(PhaseGVN *phase, bool can_reshape) { - if( in(1)->Opcode() == Op_RoundFloat ) - set_req(1,in(1)->in(1)); + if (in(1)->Opcode() == Op_RoundFloat) { + set_req(1, in(1)->in(1)); + return this; + } return NULL; } @@ -206,8 +212,10 @@ //------------------------------Ideal------------------------------------------ // If converting to an int type, skip any rounding nodes Node *ConvF2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if( in(1)->Opcode() == Op_RoundFloat ) - set_req(1,in(1)->in(1)); + if (in(1)->Opcode() == Op_RoundFloat) { + set_req(1, in(1)->in(1)); + return this; + } return NULL; }
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index cfc6634..b44bc31 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp
@@ -525,13 +525,6 @@ void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) { bool must_throw = true; - if (env()->jvmti_can_post_on_exceptions()) { - // check if we must post exception events, take uncommon trap if so - uncommon_trap_if_should_post_on_exceptions(reason, must_throw); - // here if should_post_on_exceptions is false - // continue on with the normal codegen - } - // If this particular condition has not yet happened at this // bytecode, then use the uncommon trap mechanism, and allow for // a future recompilation if several traps occur here. @@ -594,6 +587,13 @@ } if (failing()) { stop(); return; } // exception allocation might fail if (ex_obj != NULL) { + if (env()->jvmti_can_post_on_exceptions()) { + // check if we must post exception events, take uncommon trap if so + uncommon_trap_if_should_post_on_exceptions(reason, must_throw); + // here if should_post_on_exceptions is false + // continue on with the normal codegen + } + // Cheat with a preallocated exception object. if (C->log() != NULL) C->log()->elem("hot_throw preallocated='1' reason='%s'",
diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp index 7e493c5..d537ea1 100644 --- a/src/hotspot/share/opto/ifnode.cpp +++ b/src/hotspot/share/opto/ifnode.cpp
@@ -115,10 +115,11 @@ if( !t->singleton() ) return NULL; // No intervening control, like a simple Call - Node *r = iff->in(0); - if( !r->is_Region() ) return NULL; - if (r->is_Loop()) return NULL; - if( phi->region() != r ) return NULL; + Node* r = iff->in(0); + if (!r->is_Region() || r->is_Loop() || phi->region() != r || r->as_Region()->is_copy()) { + return NULL; + } + // No other users of the cmp/bool if (b->outcnt() != 1 || cmp->outcnt() != 1) { //tty->print_cr("many users of cmp/bool"); @@ -244,13 +245,23 @@ } Node* proj = PhaseIdealLoop::find_predicate(r->in(ii)); if (proj != NULL) { + // Bail out if splitting through a region with a predicate input (could + // also be a loop header before loop opts creates a LoopNode for it). return NULL; } } // If all the defs of the phi are the same constant, we already have the desired end state. // Skip the split that would create empty phi and region nodes. - if((r->req() - req_c) == 1) { + if ((r->req() - req_c) == 1) { + return NULL; + } + + // At this point we know that we can apply the split if optimization. If the region is still on the worklist, + // we should wait until it is processed. The region might be removed which makes this optimization redundant. + // This also avoids the creation of dead data loops when rewiring data nodes below when a region is dying. + if (igvn->_worklist.member(r)) { + igvn->_worklist.push(iff); // retry split if later again return NULL; }
diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp index 53f79cf..37d378a 100644 --- a/src/hotspot/share/opto/lcm.cpp +++ b/src/hotspot/share/opto/lcm.cpp
@@ -519,7 +519,7 @@ uint score = 0; // Bigger is better int idx = -1; // Index in worklist int cand_cnt = 0; // Candidate count - bool block_size_threshold_ok = (block->number_of_nodes() > 10) ? true : false; + bool block_size_threshold_ok = (recalc_pressure_nodes != NULL) && (block->number_of_nodes() > 10); for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist // Order in worklist is used to break ties. @@ -933,7 +933,7 @@ return true; } - bool block_size_threshold_ok = (block->number_of_nodes() > 10) ? true : false; + bool block_size_threshold_ok = (recalc_pressure_nodes != NULL) && (block->number_of_nodes() > 10); // We track the uses of local definitions as input dependences so that // we know when a given instruction is avialable to be scheduled.
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index a89c39f..900e956 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1775,7 +1775,7 @@ false, false, true /* mismatched */); } else { ch = make_load(control(), adr, TypeInt::CHAR, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered, - LoadNode::DependsOnlyOnTest, false, false, true /* mismatched */); + LoadNode::Pinned, false, false, true /* mismatched */); set_result(ch); } return true;
diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp index 933f6f2..c91fbb9 100644 --- a/src/hotspot/share/opto/loopPredicate.cpp +++ b/src/hotspot/share/opto/loopPredicate.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -438,6 +438,7 @@ Node_List _old_new; // map of old to new (clone) IdealLoopTree* _lpt; PhaseIdealLoop* _phase; + Node* _data_dependency_on; // The projection into the loop on which data nodes are dependent or NULL otherwise // Helper function to set up the invariance for invariance computation // If n is a known invariant, set up directly. Otherwise, look up the @@ -538,7 +539,8 @@ Invariance(Arena* area, IdealLoopTree* lpt) : _lpt(lpt), _phase(lpt->_phase), _visited(area), _invariant(area), _stack(area, 10 /* guess */), - _clone_visited(area), _old_new(area) + _clone_visited(area), _old_new(area), + _data_dependency_on(NULL) { LoopNode* head = _lpt->_head->as_Loop(); Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl); @@ -546,7 +548,12 @@ // If a node is pinned between the predicates and the loop // entry, we won't be able to move any node in the loop that // depends on it above it in a predicate. Mark all those nodes - // as non loop invariatnt. + // as non-loop-invariant. + // Loop predication could create new nodes for which the below + // invariant information is missing. Mark the 'entry' node to + // later check again if a node needs to be treated as non-loop- + // invariant as well. + _data_dependency_on = entry; Unique_Node_List wq; wq.push(entry); for (uint next = 0; next < wq.size(); ++next) { @@ -565,6 +572,12 @@ } } + // Did we explicitly mark some nodes non-loop-invariant? If so, return the entry node on which some data nodes + // are dependent that prevent loop predication. Otherwise, return NULL. + Node* data_dependency_on() { + return _data_dependency_on; + } + // Map old to n for invariance computation and clone void map_ctrl(Node* old, Node* n) { assert(old->is_CFG() && n->is_CFG(), "must be"); @@ -594,7 +607,7 @@ // Returns true if the predicate of iff is in "scale*iv + offset u< load_range(ptr)" format // Note: this function is particularly designed for loop predication. We require load_range // and offset to be loop invariant computed on the fly by "invar" -bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const { +bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar DEBUG_ONLY(COMMA ProjNode *predicate_proj)) const { if (!is_loop_exit(iff)) { return false; } @@ -626,15 +639,44 @@ if (!invar.is_invariant(range)) { return false; } + + Compile* C = Compile::current(); + uint old_unique_idx = C->unique(); Node *iv = _head->as_CountedLoop()->phi(); int scale = 0; Node *offset = NULL; if (!phase->is_scaled_iv_plus_offset(cmp->in(1), iv, &scale, &offset)) { return false; } - if (offset && !invar.is_invariant(offset)) { // offset must be invariant - return false; + if (offset != NULL) { + if (!invar.is_invariant(offset)) { // offset must be invariant + return false; + } + Node* data_dependency_on = invar.data_dependency_on(); + if (data_dependency_on != NULL && old_unique_idx < C->unique()) { + // 'offset' node was newly created by is_scaled_iv_plus_offset(). Check that it does not depend on the entry projection + // into the loop. If it does, we cannot perform loop predication (see Invariant::Invariant()). + assert(!offset->is_CFG(), "offset must be a data node"); + if (_phase->get_ctrl(offset) == data_dependency_on) { + return false; + } + } } +#ifdef ASSERT + if (offset && phase->has_ctrl(offset)) { + Node* offset_ctrl = phase->get_ctrl(offset); + if (phase->get_loop(predicate_proj) == phase->get_loop(offset_ctrl) && + phase->is_dominator(predicate_proj, offset_ctrl)) { + // If the control of offset is loop predication promoted by previous pass, + // then it will lead to cyclic dependency. + // Previously promoted loop predication is in the same loop of predication + // point. + // This situation can occur when pinning nodes too conservatively - can we do better? + assert(false, "cyclic dependency prevents range check elimination, idx: offset %d, offset_ctrl %d, predicate_proj %d", + offset->_idx, offset_ctrl->_idx, predicate_proj->_idx); + } + } +#endif return true; } @@ -656,7 +698,7 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, int scale, Node* offset, Node* init, Node* limit, jint stride, - Node* range, bool upper, bool &overflow) { + Node* range, bool upper, bool &overflow, bool negate) { jint con_limit = (limit != NULL && limit->is_Con()) ? limit->get_int() : 0; jint con_init = init->is_Con() ? init->get_int() : 0; jint con_offset = offset->is_Con() ? offset->get_int() : 0; @@ -782,7 +824,7 @@ cmp = new CmpUNode(max_idx_expr, range); } register_new_node(cmp, ctrl); - BoolNode* bol = new BoolNode(cmp, BoolTest::lt); + BoolNode* bol = new BoolNode(cmp, negate ? BoolTest::ge : BoolTest::lt); register_new_node(bol, ctrl); if (TraceLoopPredicate) { @@ -1114,7 +1156,7 @@ loop->dump_head(); } #endif - } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) { + } else if (cl != NULL && loop->is_range_check_if(iff, this, invar DEBUG_ONLY(COMMA predicate_proj))) { // Range check for counted loops const Node* cmp = bol->in(1)->as_Cmp(); Node* idx = cmp->in(1); @@ -1149,36 +1191,26 @@ } // If predicate expressions may overflow in the integer range, longs are used. bool overflow = false; + bool negate = (proj->_con != predicate_proj->_con); // Test the lower bound - BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow); - // Negate test if necessary - bool negated = false; - if (proj->_con != predicate_proj->_con) { - lower_bound_bol = new BoolNode(lower_bound_bol->in(1), lower_bound_bol->_test.negate()); - register_new_node(lower_bound_bol, ctrl); - negated = true; - } + BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow, negate); + ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode()); IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); _igvn.hash_delete(lower_bound_iff); lower_bound_iff->set_req(1, lower_bound_bol); - if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx); + if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negate ? " negated" : "", lower_bound_iff->_idx); // Test the upper bound - BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow); - negated = false; - if (proj->_con != predicate_proj->_con) { - upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate()); - register_new_node(upper_bound_bol, ctrl); - negated = true; - } + BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow, negate); + ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode()); assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); _igvn.hash_delete(upper_bound_iff); upper_bound_iff->set_req(1, upper_bound_bol); - if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx); + if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negate ? " negated" : "", lower_bound_iff->_idx); // Fall through into rest of the clean up code which will move // any dependent nodes onto the upper bound test. @@ -1224,10 +1256,10 @@ Node* rng, bool &overflow, Deoptimization::DeoptReason reason) { // First predicate for the initial value on first loop iteration - assert(proj->_con && predicate_proj->_con, "not a range check?"); Node* opaque_init = new OpaqueLoopInitNode(C, init); register_new_node(opaque_init, upper_bound_proj); - BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0) != (scale > 0), overflow); + bool negate = (proj->_con != predicate_proj->_con); + BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0) != (scale > 0), overflow, negate); Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1)); // This will go away once loop opts are over register_new_node(opaque_bol, upper_bound_proj); ProjNode* new_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode()); @@ -1244,7 +1276,7 @@ register_new_node(max_value, new_proj); max_value = new AddINode(opaque_init, max_value); register_new_node(max_value, new_proj); - bol = rc_predicate(loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0), overflow); + bol = rc_predicate(loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0), overflow, negate); opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1)); register_new_node(opaque_bol, new_proj); new_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode());
diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index f055cb4..5f23eaf 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp
@@ -45,13 +45,13 @@ // Given an IfNode, return the loop-exiting projection or NULL if both // arms remain in the loop. Node *IdealLoopTree::is_loop_exit(Node *iff) const { - if( iff->outcnt() != 2 ) return NULL; // Ignore partially dead tests + if (iff->outcnt() != 2) return NULL; // Ignore partially dead tests PhaseIdealLoop *phase = _phase; // Test is an IfNode, has 2 projections. If BOTH are in the loop // we need loop unswitching instead of peeling. - if( !is_member(phase->get_loop( iff->raw_out(0) )) ) + if (!is_member(phase->get_loop(iff->raw_out(0)))) return iff->raw_out(0); - if( !is_member(phase->get_loop( iff->raw_out(1) )) ) + if (!is_member(phase->get_loop(iff->raw_out(1)))) return iff->raw_out(1); return NULL; } @@ -63,7 +63,7 @@ //------------------------------record_for_igvn---------------------------- // Put loop body on igvn work list void IdealLoopTree::record_for_igvn() { - for( uint i = 0; i < _body.size(); i++ ) { + for (uint i = 0; i < _body.size(); i++) { Node *n = _body.at(i); _phase->_igvn._worklist.push(n); } @@ -145,7 +145,9 @@ Node *exit = is_loop_exit(iff); if (exit) { float exit_prob = iff->_prob; - if (exit->Opcode() == Op_IfFalse) exit_prob = 1.0 - exit_prob; + if (exit->Opcode() == Op_IfFalse) { + exit_prob = 1.0 - exit_prob; + } if (exit_prob > PROB_MIN) { float exit_cnt = iff->_fcnt * exit_prob; return exit_cnt; @@ -202,7 +204,7 @@ // Now compute a loop exit count float loop_exit_cnt = 0.0f; if (_child == NULL) { - for( uint i = 0; i < _body.size(); i++ ) { + for (uint i = 0; i < _body.size(); i++) { Node *n = _body[i]; loop_exit_cnt += compute_profile_trip_cnt_helper(n); } @@ -342,33 +344,39 @@ //------------------------------policy_peeling--------------------------------- // Return TRUE or FALSE if the loop should be peeled or not. Peel if we can // make some loop-invariant test (usually a null-check) happen before the loop. -bool IdealLoopTree::policy_peeling( PhaseIdealLoop *phase ) const { - Node *test = ((IdealLoopTree*)this)->tail(); - int body_size = ((IdealLoopTree*)this)->_body.size(); +bool IdealLoopTree::policy_peeling(PhaseIdealLoop *phase) const { + IdealLoopTree *loop = (IdealLoopTree*)this; + Node *test = loop->tail(); + int body_size = loop->_body.size(); // Peeling does loop cloning which can result in O(N^2) node construction - if( body_size > 255 /* Prevent overflow for large body_size */ - || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit() ) { + if (body_size > 255 /* Prevent overflow for large body_size */ + || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit()) { return false; // too large to safely clone } // check for vectorized loops, any peeling done was already applied - if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) return false; - - if (_head->is_CountedLoop() && _head->as_CountedLoop()->trip_count() == 1) { - return false; + if (_head->is_CountedLoop()) { + CountedLoopNode* cl = _head->as_CountedLoop(); + if (cl->is_unroll_only() || cl->trip_count() == 1) { + return false; + } } - while( test != _head ) { // Scan till run off top of loop - if( test->is_If() ) { // Test? + while (test != _head) { // Scan till run off top of loop + if (test->is_If()) { // Test? Node *ctrl = phase->get_ctrl(test->in(1)); - if (ctrl->is_top()) + if (ctrl->is_top()) { return false; // Found dead test on live IF? No peeling! + } // Standard IF only has one input value to check for loop invariance - assert(test->Opcode() == Op_If || test->Opcode() == Op_CountedLoopEnd || test->Opcode() == Op_RangeCheck, "Check this code when new subtype is added"); + assert(test->Opcode() == Op_If || + test->Opcode() == Op_CountedLoopEnd || + test->Opcode() == Op_RangeCheck, + "Check this code when new subtype is added"); // Condition is not a member of this loop? - if( !is_member(phase->get_loop(ctrl)) && - is_loop_exit(test) ) + if (!is_member(phase->get_loop(ctrl)) && is_loop_exit(test)) { return true; // Found reason to peel! + } } // Walk up dominators to loop _head looking for test which is // executed on every path thru loop. @@ -554,7 +562,7 @@ // v // exit // -void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) { +void PhaseIdealLoop::do_peeling(IdealLoopTree *loop, Node_List &old_new) { C->set_major_progress(); // Peeling a 'main' loop in a pre/main/post situation obfuscates the @@ -603,7 +611,7 @@ Node* old = head->fast_out(j); if (old->in(0) == loop->_head && old->req() == 3 && old->is_Phi()) { Node* new_exit_value = old_new[old->in(LoopNode::LoopBackControl)->_idx]; - if (!new_exit_value ) // Backedge value is ALSO loop invariant? + if (!new_exit_value) // Backedge value is ALSO loop invariant? // Then loop body backedge value remains the same. new_exit_value = old->in(LoopNode::LoopBackControl); _igvn.hash_delete(old); @@ -632,8 +640,9 @@ for (uint j3 = 0; j3 < loop->_body.size(); j3++) { Node *old = loop->_body.at(j3); Node *nnn = old_new[old->_idx]; - if (!has_ctrl(nnn)) + if (!has_ctrl(nnn)) { set_idom(nnn, idom(nnn), dd-1); + } } // Now force out all loop-invariant dominating tests. The optimizer @@ -648,12 +657,12 @@ //------------------------------policy_maximally_unroll------------------------ // Calculate exact loop trip count and return true if loop can be maximally // unrolled. -bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const { +bool IdealLoopTree::policy_maximally_unroll(PhaseIdealLoop *phase) const { CountedLoopNode *cl = _head->as_CountedLoop(); assert(cl->is_normal_loop(), ""); - if (!cl->is_valid_counted_loop()) + if (!cl->is_valid_counted_loop()) { return false; // Malformed counted loop - + } if (!cl->has_exact_trip_count()) { // Trip count is not exact. return false; @@ -669,7 +678,7 @@ // size. After all, it will no longer be a loop. uint body_size = _body.size(); uint unroll_limit = (uint)LoopUnrollLimit * 4; - assert( (intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits"); + assert((intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits"); if (trip_count > unroll_limit || body_size > unroll_limit) { return false; } @@ -739,17 +748,17 @@ _local_loop_unroll_limit = LoopUnrollLimit; _local_loop_unroll_factor = 4; - int future_unroll_ct = cl->unrolled_count() * 2; + int future_unroll_cnt = cl->unrolled_count() * 2; if (!cl->is_vectorized_loop()) { - if (future_unroll_ct > LoopMaxUnroll) return false; + if (future_unroll_cnt > LoopMaxUnroll) return false; } else { // obey user constraints on vector mapped loops with additional unrolling applied int unroll_constraint = (cl->slp_max_unroll()) ? cl->slp_max_unroll() : 1; - if ((future_unroll_ct / unroll_constraint) > LoopMaxUnroll) return false; + if ((future_unroll_cnt / unroll_constraint) > LoopMaxUnroll) return false; } // Check for initial stride being a small enough constant - if (abs(cl->stride_con()) > (1<<2)*future_unroll_ct) return false; + if (abs(cl->stride_con()) > (1<<2)*future_unroll_cnt) return false; // Don't unroll if the next round of unrolling would push us // over the expected trip count of the loop. One is subtracted @@ -757,8 +766,8 @@ // executes 1 iteration. if (UnrollLimitForProfileCheck > 0 && cl->profile_trip_cnt() != COUNT_UNKNOWN && - future_unroll_ct > UnrollLimitForProfileCheck && - (float)future_unroll_ct > cl->profile_trip_cnt() - 1.0) { + future_unroll_cnt > UnrollLimitForProfileCheck && + (float)future_unroll_cnt > cl->profile_trip_cnt() - 1.0) { return false; } @@ -767,8 +776,8 @@ // and rounds of "unroll,optimize" are not making significant progress // Progress defined as current size less than 20% larger than previous size. if (UseSuperWord && cl->node_count_before_unroll() > 0 && - future_unroll_ct > LoopUnrollMin && - (future_unroll_ct - 1) * (100 / LoopPercentProfileLimit) > cl->profile_trip_cnt() && + future_unroll_cnt > LoopUnrollMin && + (future_unroll_cnt - 1) * (100.0 / LoopPercentProfileLimit) > cl->profile_trip_cnt() && 1.2 * cl->node_count_before_unroll() < (double)_body.size()) { return false; } @@ -852,8 +861,8 @@ if (LoopMaxUnroll > _local_loop_unroll_factor) { // Once policy_slp_analysis succeeds, mark the loop with the // maximal unroll factor so that we minimize analysis passes - if (future_unroll_ct >= _local_loop_unroll_factor) { - policy_unroll_slp_analysis(cl, phase, future_unroll_ct); + if (future_unroll_cnt >= _local_loop_unroll_factor) { + policy_unroll_slp_analysis(cl, phase, future_unroll_cnt); } } } @@ -863,7 +872,7 @@ LoopMaxUnroll = slp_max_unroll_factor; } if (cl->has_passed_slp()) { - if (slp_max_unroll_factor >= future_unroll_ct) return true; + if (slp_max_unroll_factor >= future_unroll_cnt) return true; // Normal case: loop too big return false; } @@ -877,9 +886,9 @@ return false; } - if (cl->do_unroll_only()) { + if (cl->is_unroll_only()) { if (TraceSuperWordLoopUnrollAnalysis) { - tty->print_cr("policy_unroll passed vector loop(vlen=%d,factor = %d)\n", slp_max_unroll_factor, future_unroll_ct); + tty->print_cr("policy_unroll passed vector loop(vlen=%d,factor = %d)\n", slp_max_unroll_factor, future_unroll_cnt); } } @@ -887,7 +896,7 @@ return true; } -void IdealLoopTree::policy_unroll_slp_analysis(CountedLoopNode *cl, PhaseIdealLoop *phase, int future_unroll_ct) { +void IdealLoopTree::policy_unroll_slp_analysis(CountedLoopNode *cl, PhaseIdealLoop *phase, int future_unroll_cnt) { // Enable this functionality target by target as needed if (SuperWordLoopUnrollAnalysis) { if (!cl->was_slp_analyzed()) { @@ -902,7 +911,7 @@ if (cl->has_passed_slp()) { int slp_max_unroll_factor = cl->slp_max_unroll(); - if (slp_max_unroll_factor >= future_unroll_ct) { + if (slp_max_unroll_factor >= future_unroll_cnt) { int new_limit = cl->node_count_before_unroll() * slp_max_unroll_factor; if (new_limit > LoopUnrollLimit) { if (TraceSuperWordLoopUnrollAnalysis) { @@ -921,14 +930,14 @@ // aligned in a loop (unless the VM guarantees mutual alignment). Note that // if we vectorize short memory ops into longer memory ops, we may want to // increase alignment. -bool IdealLoopTree::policy_align( PhaseIdealLoop *phase ) const { +bool IdealLoopTree::policy_align(PhaseIdealLoop *phase) const { return false; } //------------------------------policy_range_check----------------------------- // Return TRUE or FALSE if the loop should be range-check-eliminated. // Actually we do iteration-splitting, a more powerful form of RCE. -bool IdealLoopTree::policy_range_check( PhaseIdealLoop *phase ) const { +bool IdealLoopTree::policy_range_check(PhaseIdealLoop *phase) const { if (!RangeCheckElimination) return false; CountedLoopNode *cl = _head->as_CountedLoop(); @@ -939,7 +948,7 @@ Node *trip_counter = cl->phi(); // check for vectorized loops, some opts are no longer needed - if (cl->do_unroll_only()) return false; + if (cl->is_unroll_only()) return false; // Check loop body for tests of trip-counter plus loop-invariant vs // loop-invariant. @@ -950,28 +959,32 @@ // Comparing trip+off vs limit Node *bol = iff->in(1); - if (bol->req() != 2) continue; // dead constant test + if (bol->req() != 2) { + continue; // dead constant test + } if (!bol->is_Bool()) { assert(bol->Opcode() == Op_Conv2B, "predicate check only"); continue; } - if (bol->as_Bool()->_test._test == BoolTest::ne) + if (bol->as_Bool()->_test._test == BoolTest::ne) { continue; // not RC - + } Node *cmp = bol->in(1); Node *rc_exp = cmp->in(1); Node *limit = cmp->in(2); Node *limit_c = phase->get_ctrl(limit); - if( limit_c == phase->C->top() ) + if (limit_c == phase->C->top()) { return false; // Found dead test on live IF? No RCE! - if( is_member(phase->get_loop(limit_c) ) ) { + } + if (is_member(phase->get_loop(limit_c))) { // Compare might have operands swapped; commute them rc_exp = cmp->in(2); limit = cmp->in(1); limit_c = phase->get_ctrl(limit); - if( is_member(phase->get_loop(limit_c) ) ) + if (is_member(phase->get_loop(limit_c))) { continue; // Both inputs are loop varying; cannot RCE + } } if (!phase->is_scaled_iv_plus_offset(rc_exp, trip_counter, NULL, NULL)) { @@ -980,8 +993,9 @@ // Yeah! Found a test like 'trip+off vs limit' // Test is an IfNode, has 2 projections. If BOTH are in the loop // we need loop unswitching instead of iteration splitting. - if( is_loop_exit(iff) ) + if (is_loop_exit(iff)) { return true; // Found reason to split iterations + } } // End of is IF } @@ -991,14 +1005,17 @@ //------------------------------policy_peel_only------------------------------- // Return TRUE or FALSE if the loop should NEVER be RCE'd or aligned. Useful // for unrolling loops with NO array accesses. -bool IdealLoopTree::policy_peel_only( PhaseIdealLoop *phase ) const { +bool IdealLoopTree::policy_peel_only(PhaseIdealLoop *phase) const { // check for vectorized loops, any peeling done was already applied - if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) return false; + if (_head->is_CountedLoop() && _head->as_CountedLoop()->is_unroll_only()) { + return false; + } - for( uint i = 0; i < _body.size(); i++ ) - if( _body[i]->is_Mem() ) + for (uint i = 0; i < _body.size(); i++) { + if (_body[i]->is_Mem()) { return false; - + } + } // No memory accesses at all! return true; } @@ -1006,33 +1023,31 @@ //------------------------------clone_up_backedge_goo-------------------------- // If Node n lives in the back_ctrl block and cannot float, we clone a private // version of n in preheader_ctrl block and return that, otherwise return n. -Node *PhaseIdealLoop::clone_up_backedge_goo( Node *back_ctrl, Node *preheader_ctrl, Node *n, VectorSet &visited, Node_Stack &clones ) { - if( get_ctrl(n) != back_ctrl ) return n; +Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctrl, Node *n, VectorSet &visited, Node_Stack &clones) { + if (get_ctrl(n) != back_ctrl) return n; // Only visit once if (visited.test_set(n->_idx)) { Node *x = clones.find(n->_idx); - if (x != NULL) - return x; - return n; + return (x != NULL) ? x : n; } Node *x = NULL; // If required, a clone of 'n' // Check for 'n' being pinned in the backedge. - if( n->in(0) && n->in(0) == back_ctrl ) { + if (n->in(0) && n->in(0) == back_ctrl) { assert(clones.find(n->_idx) == NULL, "dead loop"); x = n->clone(); // Clone a copy of 'n' to preheader clones.push(x, n->_idx); - x->set_req( 0, preheader_ctrl ); // Fix x's control input to preheader + x->set_req(0, preheader_ctrl); // Fix x's control input to preheader } // Recursive fixup any other input edges into x. // If there are no changes we can just return 'n', otherwise // we need to clone a private copy and change it. - for( uint i = 1; i < n->req(); i++ ) { - Node *g = clone_up_backedge_goo( back_ctrl, preheader_ctrl, n->in(i), visited, clones ); - if( g != n->in(i) ) { - if( !x ) { + for (uint i = 1; i < n->req(); i++) { + Node *g = clone_up_backedge_goo(back_ctrl, preheader_ctrl, n->in(i), visited, clones); + if (g != n->in(i)) { + if (!x) { assert(clones.find(n->_idx) == NULL, "dead loop"); x = n->clone(); clones.push(x, n->_idx); @@ -1040,11 +1055,11 @@ x->set_req(i, g); } } - if( x ) { // x can legally float to pre-header location - register_new_node( x, preheader_ctrl ); + if (x) { // x can legally float to pre-header location + register_new_node(x, preheader_ctrl); return x; } else { // raise n to cover LCA of uses - set_ctrl( n, find_non_split_ctrl(back_ctrl->in(0)) ); + set_ctrl(n, find_non_split_ctrl(back_ctrl->in(0))); } return n; } @@ -1330,7 +1345,7 @@ // Insert pre and post loops. If peel_only is set, the pre-loop can not have // more iterations added. It acts as a 'peel' only, no lower-bound RCE, no // alignment. Useful to unroll loops that do no array accesses. -void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only ) { +void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_new, bool peel_only) { #ifndef PRODUCT if (TraceLoopOpts) { @@ -1345,9 +1360,9 @@ // Find common pieces of the loop being guarded with pre & post loops CountedLoopNode *main_head = loop->_head->as_CountedLoop(); - assert( main_head->is_normal_loop(), "" ); + assert(main_head->is_normal_loop(), ""); CountedLoopEndNode *main_end = main_head->loopexit(); - assert( main_end->outcnt() == 2, "1 true, 1 false path only" ); + assert(main_end->outcnt() == 2, "1 true, 1 false path only"); Node *pre_header= main_head->in(LoopNode::EntryControl); Node *init = main_head->init_trip(); @@ -1359,13 +1374,13 @@ // Need only 1 user of 'bol' because I will be hacking the loop bounds. Node *bol = main_end->in(CountedLoopEndNode::TestValue); - if( bol->outcnt() != 1 ) { + if (bol->outcnt() != 1) { bol = bol->clone(); register_new_node(bol,main_end->in(CountedLoopEndNode::TestControl)); _igvn.replace_input_of(main_end, CountedLoopEndNode::TestValue, bol); } // Need only 1 user of 'cmp' because I will be hacking the loop bounds. - if( cmp->outcnt() != 1 ) { + if (cmp->outcnt() != 1) { cmp = cmp->clone(); register_new_node(cmp,main_end->in(CountedLoopEndNode::TestControl)); _igvn.replace_input_of(bol, 1, cmp); @@ -1402,9 +1417,9 @@ // Find the pre-loop normal exit. Node* pre_exit = pre_end->proj_out(false); - assert( pre_exit->Opcode() == Op_IfFalse, "" ); + assert(pre_exit->Opcode() == Op_IfFalse, ""); IfFalseNode *new_pre_exit = new IfFalseNode(pre_end); - _igvn.register_new_node_with_optimizer( new_pre_exit ); + _igvn.register_new_node_with_optimizer(new_pre_exit); set_idom(new_pre_exit, pre_end, dd_main_head); set_loop(new_pre_exit, outer_loop->_parent); @@ -1413,26 +1428,26 @@ // zero-trip guard will become the minimum-trip guard when we unroll // the main-loop. Node *min_opaq = new Opaque1Node(C, limit); - Node *min_cmp = new CmpINode( pre_incr, min_opaq ); - Node *min_bol = new BoolNode( min_cmp, b_test ); - register_new_node( min_opaq, new_pre_exit ); - register_new_node( min_cmp , new_pre_exit ); - register_new_node( min_bol , new_pre_exit ); + Node *min_cmp = new CmpINode(pre_incr, min_opaq); + Node *min_bol = new BoolNode(min_cmp, b_test); + register_new_node(min_opaq, new_pre_exit); + register_new_node(min_cmp , new_pre_exit); + register_new_node(min_bol , new_pre_exit); // Build the IfNode (assume the main-loop is executed always). - IfNode *min_iff = new IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN ); - _igvn.register_new_node_with_optimizer( min_iff ); + IfNode *min_iff = new IfNode(new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN); + _igvn.register_new_node_with_optimizer(min_iff); set_idom(min_iff, new_pre_exit, dd_main_head); set_loop(min_iff, outer_loop->_parent); // Plug in the false-path, taken if we need to skip main-loop - _igvn.hash_delete( pre_exit ); + _igvn.hash_delete(pre_exit); pre_exit->set_req(0, min_iff); set_idom(pre_exit, min_iff, dd_main_head); set_idom(pre_exit->unique_ctrl_out(), min_iff, dd_main_head); // Make the true-path, must enter the main loop - Node *min_taken = new IfTrueNode( min_iff ); - _igvn.register_new_node_with_optimizer( min_taken ); + Node *min_taken = new IfTrueNode(min_iff); + _igvn.register_new_node_with_optimizer(min_taken); set_idom(min_taken, min_iff, dd_main_head); set_loop(min_taken, outer_loop->_parent); // Plug in the true path @@ -1447,14 +1462,14 @@ // fall-out values of the pre-loop. for (DUIterator i2 = main_head->outs(); main_head->has_out(i2); i2++) { Node* main_phi = main_head->out(i2); - if( main_phi->is_Phi() && main_phi->in(0) == main_head && main_phi->outcnt() > 0 ) { + if (main_phi->is_Phi() && main_phi->in(0) == main_head && main_phi->outcnt() > 0) { Node* pre_phi = old_new[main_phi->_idx]; Node* fallpre = clone_up_backedge_goo(pre_head->back_control(), main_head->skip_strip_mined()->in(LoopNode::EntryControl), pre_phi->in(LoopNode::LoopBackControl), visited, clones); _igvn.hash_delete(main_phi); - main_phi->set_req( LoopNode::EntryControl, fallpre ); + main_phi->set_req(LoopNode::EntryControl, fallpre); } } @@ -1469,7 +1484,7 @@ // dependencies. // CastII for the main loop: - Node* castii = cast_incr_before_loop( pre_incr, min_taken, main_head ); + Node* castii = cast_incr_before_loop(pre_incr, min_taken, main_head); assert(castii != NULL, "no castII inserted"); assert(post_head->in(1)->is_IfProj(), "must be zero-trip guard If node projection of the post loop"); copy_skeleton_predicates_to_main_loop(pre_head, castii, stride, outer_loop, outer_main_head, dd_main_head, @@ -1478,18 +1493,18 @@ // Step B4: Shorten the pre-loop to run only 1 iteration (for now). // RCE and alignment may change this later. Node *cmp_end = pre_end->cmp_node(); - assert( cmp_end->in(2) == limit, "" ); - Node *pre_limit = new AddINode( init, stride ); + assert(cmp_end->in(2) == limit, ""); + Node *pre_limit = new AddINode(init, stride); // Save the original loop limit in this Opaque1 node for // use by range check elimination. Node *pre_opaq = new Opaque1Node(C, pre_limit, limit); - register_new_node( pre_limit, pre_head->in(0) ); - register_new_node( pre_opaq , pre_head->in(0) ); + register_new_node(pre_limit, pre_head->in(0)); + register_new_node(pre_opaq , pre_head->in(0)); // Since no other users of pre-loop compare, I can hack limit directly - assert( cmp_end->outcnt() == 1, "no other users" ); + assert(cmp_end->outcnt() == 1, "no other users"); _igvn.hash_delete(cmp_end); cmp_end->set_req(2, peel_only ? pre_limit : pre_opaq); @@ -1509,24 +1524,26 @@ // Modify pre loop end condition Node* pre_bol = pre_end->in(CountedLoopEndNode::TestValue)->as_Bool(); BoolNode* new_bol0 = new BoolNode(pre_bol->in(1), new_test); - register_new_node( new_bol0, pre_head->in(0) ); + register_new_node(new_bol0, pre_head->in(0)); _igvn.replace_input_of(pre_end, CountedLoopEndNode::TestValue, new_bol0); // Modify main loop guard condition assert(min_iff->in(CountedLoopEndNode::TestValue) == min_bol, "guard okay"); BoolNode* new_bol1 = new BoolNode(min_bol->in(1), new_test); - register_new_node( new_bol1, new_pre_exit ); + register_new_node(new_bol1, new_pre_exit); _igvn.hash_delete(min_iff); min_iff->set_req(CountedLoopEndNode::TestValue, new_bol1); // Modify main loop end condition BoolNode* main_bol = main_end->in(CountedLoopEndNode::TestValue)->as_Bool(); BoolNode* new_bol2 = new BoolNode(main_bol->in(1), new_test); - register_new_node( new_bol2, main_end->in(CountedLoopEndNode::TestControl) ); + register_new_node(new_bol2, main_end->in(CountedLoopEndNode::TestControl)); _igvn.replace_input_of(main_end, CountedLoopEndNode::TestValue, new_bol2); } // Flag main loop main_head->set_main_loop(); - if( peel_only ) main_head->set_main_no_pre_loop(); + if (peel_only) { + main_head->set_main_no_pre_loop(); + } // Subtract a trip count for the pre-loop. main_head->set_trip_count(main_head->trip_count() - 1); @@ -1545,8 +1562,9 @@ //------------------------------insert_vector_post_loop------------------------ // Insert a copy of the atomic unrolled vectorized main loop as a post loop, -// unroll_policy has already informed us that more unrolling is about to happen to -// the main loop. The resultant post loop will serve as a vectorized drain loop. +// unroll_policy has already informed us that more unrolling is about to +// happen to the main loop. The resultant post loop will serve as a +// vectorized drain loop. void PhaseIdealLoop::insert_vector_post_loop(IdealLoopTree *loop, Node_List &old_new) { if (!loop->_head->is_CountedLoop()) return; @@ -1795,7 +1813,7 @@ //------------------------------do_unroll-------------------------------------- // Unroll the loop body one step - make each trip do 2 iterations. -void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip ) { +void PhaseIdealLoop::do_unroll(IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip) { assert(LoopUnrollLimit, ""); CountedLoopNode *loop_head = loop->_head->as_CountedLoop(); CountedLoopEndNode *loop_end = loop_head->loopexit(); @@ -1818,8 +1836,8 @@ Node_List rpo_list; VectorSet visited(arena); visited.set(loop_head->_idx); - rpo( loop_head, stack, visited, rpo_list ); - dump(loop, rpo_list.size(), rpo_list ); + rpo(loop_head, stack, visited, rpo_list); + dump(loop, rpo_list.size(), rpo_list); } #endif @@ -1914,8 +1932,8 @@ // zero trip guard limit will be different from loop limit. assert(has_ctrl(opaq), "should have it"); Node* opaq_ctrl = get_ctrl(opaq); - limit = new Opaque2Node( C, limit ); - register_new_node( limit, opaq_ctrl ); + limit = new Opaque2Node(C, limit); + register_new_node(limit, opaq_ctrl); } if ((stride_con > 0 && (java_subtract(limit_type->_lo, stride_con) < limit_type->_lo)) || (stride_con < 0 && (java_subtract(limit_type->_hi, stride_con) > limit_type->_hi))) { @@ -1956,11 +1974,11 @@ adj_limit = new SubINode(limit, stride); } assert(old_limit != NULL && adj_limit != NULL, ""); - register_new_node( adj_limit, ctrl ); // adjust amount + register_new_node(adj_limit, ctrl); // adjust amount Node* adj_cmp = new CmpINode(old_limit, adj_limit); - register_new_node( adj_cmp, ctrl ); + register_new_node(adj_cmp, ctrl); Node* adj_bool = new BoolNode(adj_cmp, bt); - register_new_node( adj_bool, ctrl ); + register_new_node(adj_bool, ctrl); new_limit = new CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT); } register_new_node(new_limit, ctrl); @@ -2014,10 +2032,10 @@ // Make the fall-in from the original come from the fall-out of the clone. for (DUIterator_Fast jmax, j = loop_head->fast_outs(jmax); j < jmax; j++) { Node* phi = loop_head->fast_out(j); - if( phi->is_Phi() && phi->in(0) == loop_head && phi->outcnt() > 0 ) { + if (phi->is_Phi() && phi->in(0) == loop_head && phi->outcnt() > 0) { Node *newphi = old_new[phi->_idx]; - _igvn.hash_delete( phi ); - _igvn.hash_delete( newphi ); + _igvn.hash_delete(phi); + _igvn.hash_delete(newphi); phi ->set_req(LoopNode:: EntryControl, newphi->in(LoopNode::LoopBackControl)); newphi->set_req(LoopNode::LoopBackControl, phi ->in(LoopNode::LoopBackControl)); @@ -2025,7 +2043,7 @@ } } Node *clone_head = old_new[loop_head->_idx]; - _igvn.hash_delete( clone_head ); + _igvn.hash_delete(clone_head); loop_head ->set_req(LoopNode:: EntryControl, clone_head->in(LoopNode::LoopBackControl)); clone_head->set_req(LoopNode::LoopBackControl, loop_head ->in(LoopNode::LoopBackControl)); loop_head ->set_req(LoopNode::LoopBackControl, C->top()); @@ -2036,18 +2054,19 @@ // Kill the clone's backedge Node *newcle = old_new[loop_end->_idx]; - _igvn.hash_delete( newcle ); + _igvn.hash_delete(newcle); Node *one = _igvn.intcon(1); set_ctrl(one, C->root()); newcle->set_req(1, one); // Force clone into same loop body uint max = loop->_body.size(); - for( uint k = 0; k < max; k++ ) { + for (uint k = 0; k < max; k++) { Node *old = loop->_body.at(k); Node *nnn = old_new[old->_idx]; loop->_body.push(nnn); - if (!has_ctrl(old)) + if (!has_ctrl(old)) { set_loop(nnn, loop); + } } loop->record_for_igvn(); @@ -2059,7 +2078,7 @@ for (uint i = 0; i < loop->_body.size(); i++) { loop->_body.at(i)->dump(); } - if(C->clone_map().is_debug()) { + if (C->clone_map().is_debug()) { tty->print("\nCloneMap\n"); Dict* dict = C->clone_map().dict(); DictI i(dict); @@ -2080,7 +2099,7 @@ //------------------------------do_maximally_unroll---------------------------- -void PhaseIdealLoop::do_maximally_unroll( IdealLoopTree *loop, Node_List &old_new ) { +void PhaseIdealLoop::do_maximally_unroll(IdealLoopTree *loop, Node_List &old_new) { CountedLoopNode *cl = loop->_head->as_CountedLoop(); assert(cl->has_exact_trip_count(), "trip count is not exact"); assert(cl->trip_count() > 0, ""); @@ -2283,7 +2302,7 @@ Node* one = _igvn.longcon(1); set_ctrl(one, C->root()); Node* plus_one = new AddLNode(offset, one); - register_new_node( plus_one, pre_ctrl ); + register_new_node(plus_one, pre_ctrl); *pre_limit = adjust_limit(!is_positive_stride, scale, plus_one, upper_limit, *pre_limit, pre_ctrl, round); // The underflow limit: low_limit <= scale*I+offset @@ -2400,7 +2419,7 @@ Node* predicate_proj, int scale_con, Node* offset, Node* limit, jint stride_con, Node* value) { bool overflow = false; - BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, value, NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow); + BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, value, NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow, false); Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1)); register_new_node(opaque_bol, predicate_proj); IfNode* new_iff = NULL; @@ -2424,7 +2443,7 @@ //------------------------------do_range_check--------------------------------- // Eliminate range-checks and other trip-counter vs loop-invariant tests. -int PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { +int PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) { #ifndef PRODUCT if (PrintOpto && VerifyLoopOptimizations) { tty->print("Range Check Elimination "); @@ -2434,15 +2453,16 @@ loop->dump_head(); } #endif + assert(RangeCheckElimination, ""); CountedLoopNode *cl = loop->_head->as_CountedLoop(); // If we fail before trying to eliminate range checks, set multiversion state int closed_range_checks = 1; // protect against stride not being a constant - if (!cl->stride_is_con()) + if (!cl->stride_is_con()) { return closed_range_checks; - + } // Find the trip counter; we are iteration splitting based on it Node *trip_counter = cl->phi(); // Find the main loop limit; we will trim it's iterations @@ -2457,7 +2477,7 @@ } // Need to find the main-loop zero-trip guard - Node *ctrl = cl->skip_predicates(); + Node *ctrl = cl->skip_predicates(); Node *iffm = ctrl->in(0); Node *opqzm = iffm->in(1)->in(1)->in(2); assert(opqzm->in(1) == main_limit, "do not understand situation"); @@ -2475,8 +2495,9 @@ // Occasionally it's possible for a pre-loop Opaque1 node to be // optimized away and then another round of loop opts attempted. // We can not optimize this particular loop in that case. - if (pre_opaq1->Opcode() != Op_Opaque1) + if (pre_opaq1->Opcode() != Op_Opaque1) { return closed_range_checks; + } Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1; Node *pre_limit = pre_opaq->in(1); @@ -2486,9 +2507,9 @@ // Ensure the original loop limit is available from the // pre-loop Opaque1 node. Node *orig_limit = pre_opaq->original_loop_limit(); - if (orig_limit == NULL || _igvn.type(orig_limit) == Type::TOP) + if (orig_limit == NULL || _igvn.type(orig_limit) == Type::TOP) { return closed_range_checks; - + } // Must know if its a count-up or count-down loop int stride_con = cl->stride_con(); @@ -2506,8 +2527,9 @@ Node* predicate_proj = cl->skip_strip_mined()->in(LoopNode::EntryControl); assert(predicate_proj->is_Proj() && predicate_proj->in(0)->is_If(), "if projection only"); + // Check loop body for tests of trip-counter plus loop-invariant vs loop-variant. - for( uint i = 0; i < loop->_body.size(); i++ ) { + for (uint i = 0; i < loop->_body.size(); i++) { Node *iff = loop->_body[i]; if (iff->Opcode() == Op_If || iff->Opcode() == Op_RangeCheck) { // Test? @@ -2515,18 +2537,18 @@ // we need loop unswitching instead of iteration splitting. closed_range_checks++; Node *exit = loop->is_loop_exit(iff); - if( !exit ) continue; + if (!exit) continue; int flip = (exit->Opcode() == Op_IfTrue) ? 1 : 0; // Get boolean condition to test Node *i1 = iff->in(1); - if( !i1->is_Bool() ) continue; + if (!i1->is_Bool()) continue; BoolNode *bol = i1->as_Bool(); BoolTest b_test = bol->_test; // Flip sense of test if exit condition is flipped - if( flip ) + if (flip) { b_test = b_test.negate(); - + } // Get compare Node *cmp = bol->in(1); @@ -2536,14 +2558,15 @@ int scale_con= 1; // Assume trip counter not scaled Node *limit_c = get_ctrl(limit); - if( loop->is_member(get_loop(limit_c) ) ) { + if (loop->is_member(get_loop(limit_c))) { // Compare might have operands swapped; commute them b_test = b_test.commute(); rc_exp = cmp->in(2); limit = cmp->in(1); limit_c = get_ctrl(limit); - if( loop->is_member(get_loop(limit_c) ) ) + if (loop->is_member(get_loop(limit_c))) { continue; // Both inputs are loop varying; cannot RCE + } } // Here we know 'limit' is loop invariant @@ -2562,8 +2585,9 @@ } Node *offset_c = get_ctrl(offset); - if( loop->is_member( get_loop(offset_c) ) ) + if (loop->is_member(get_loop(offset_c))) { continue; // Offset is not really loop invariant + } // Here we know 'offset' is loop invariant. // As above for the 'limit', the 'offset' maybe pinned below the @@ -2594,8 +2618,8 @@ register_new_node(limit, pre_ctrl); // Adjust pre and main loop limits to guard the correct iteration set - if( cmp->Opcode() == Op_CmpU ) {// Unsigned compare is really 2 tests - if( b_test._test == BoolTest::lt ) { // Range checks always use lt + if (cmp->Opcode() == Op_CmpU) {// Unsigned compare is really 2 tests + if (b_test._test == BoolTest::lt) { // Range checks always use lt // The underflow and overflow limits: 0 <= scale*I+offset < limit add_constraint(stride_con, lscale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit); Node* init = cl->init_trip(); @@ -2626,22 +2650,22 @@ continue; // In release mode, ignore it } } else { // Otherwise work on normal compares - switch( b_test._test ) { + switch (b_test._test) { case BoolTest::gt: // Fall into GE case case BoolTest::ge: // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit lscale_con = -lscale_con; offset = new SubLNode(zero, offset); - register_new_node( offset, pre_ctrl ); + register_new_node(offset, pre_ctrl); limit = new SubLNode(zero, limit); - register_new_node( limit, pre_ctrl ); + register_new_node(limit, pre_ctrl); // Fall into LE case case BoolTest::le: if (b_test._test != BoolTest::gt) { // Convert X <= Y to X < Y+1 limit = new AddLNode(limit, one); - register_new_node( limit, pre_ctrl ); + register_new_node(limit, pre_ctrl); } // Fall into LT case case BoolTest::lt: @@ -2660,7 +2684,7 @@ // Kill the eliminated test C->set_major_progress(); - Node *kill_con = _igvn.intcon( 1-flip ); + Node *kill_con = _igvn.intcon(1-flip); set_ctrl(kill_con, C->root()); _igvn.replace_input_of(iff, 1, kill_con); // Find surviving projection @@ -2680,9 +2704,7 @@ if (int_limit->Opcode() == Op_LoadRange) { closed_range_checks--; } - } // End of is IF - } if (predicate_proj != cl->skip_strip_mined()->in(LoopNode::EntryControl)) { _igvn.replace_input_of(cl->skip_strip_mined(), LoopNode::EntryControl, predicate_proj); @@ -2704,15 +2726,15 @@ Node *main_cle = cl->loopexit(); Node *main_bol = main_cle->in(1); // Hacking loop bounds; need private copies of exit test - if( main_bol->outcnt() > 1 ) {// BoolNode shared? - main_bol = main_bol->clone();// Clone a private BoolNode - register_new_node( main_bol, main_cle->in(0) ); + if (main_bol->outcnt() > 1) { // BoolNode shared? + main_bol = main_bol->clone(); // Clone a private BoolNode + register_new_node(main_bol, main_cle->in(0)); _igvn.replace_input_of(main_cle, 1, main_bol); } Node *main_cmp = main_bol->in(1); - if( main_cmp->outcnt() > 1 ) { // CmpNode shared? - main_cmp = main_cmp->clone();// Clone a private CmpNode - register_new_node( main_cmp, main_cle->in(0) ); + if (main_cmp->outcnt() > 1) { // CmpNode shared? + main_cmp = main_cmp->clone(); // Clone a private CmpNode + register_new_node(main_cmp, main_cle->in(0)); _igvn.replace_input_of(main_bol, 1, main_cmp); } assert(main_limit == cl->limit() || get_ctrl(main_limit) == pre_ctrl, "wrong control for added limit"); @@ -2728,7 +2750,7 @@ // Hack the now-private loop bounds _igvn.replace_input_of(main_cmp, 2, main_limit); // The OpaqueNode is unshared by design - assert( opqzm->outcnt() == 1, "cannot hack shared node" ); + assert(opqzm->outcnt() == 1, "cannot hack shared node"); _igvn.replace_input_of(opqzm, 1, main_limit); return closed_range_checks; @@ -2897,66 +2919,68 @@ //------------------------------DCE_loop_body---------------------------------- // Remove simplistic dead code from loop body void IdealLoopTree::DCE_loop_body() { - for( uint i = 0; i < _body.size(); i++ ) - if( _body.at(i)->outcnt() == 0 ) - _body.map( i--, _body.pop() ); + for (uint i = 0; i < _body.size(); i++) { + if (_body.at(i)->outcnt() == 0) { + _body.map(i--, _body.pop()); + } + } } //------------------------------adjust_loop_exit_prob-------------------------- // Look for loop-exit tests with the 50/50 (or worse) guesses from the parsing stage. // Replace with a 1-in-10 exit guess. -void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) { +void IdealLoopTree::adjust_loop_exit_prob(PhaseIdealLoop *phase) { Node *test = tail(); - while( test != _head ) { + while (test != _head) { uint top = test->Opcode(); - if( top == Op_IfTrue || top == Op_IfFalse ) { + if (top == Op_IfTrue || top == Op_IfFalse) { int test_con = ((ProjNode*)test)->_con; assert(top == (uint)(test_con? Op_IfTrue: Op_IfFalse), "sanity"); IfNode *iff = test->in(0)->as_If(); - if( iff->outcnt() == 2 ) { // Ignore dead tests + if (iff->outcnt() == 2) { // Ignore dead tests Node *bol = iff->in(1); - if( bol && bol->req() > 1 && bol->in(1) && - ((bol->in(1)->Opcode() == Op_StorePConditional ) || - (bol->in(1)->Opcode() == Op_StoreIConditional ) || - (bol->in(1)->Opcode() == Op_StoreLConditional ) || + if (bol && bol->req() > 1 && bol->in(1) && + ((bol->in(1)->Opcode() == Op_StorePConditional) || + (bol->in(1)->Opcode() == Op_StoreIConditional) || + (bol->in(1)->Opcode() == Op_StoreLConditional) || #if INCLUDE_SHENANDOAHGC - (bol->in(1)->Opcode() == Op_ShenandoahCompareAndExchangeP ) || - (bol->in(1)->Opcode() == Op_ShenandoahCompareAndExchangeN ) || - (bol->in(1)->Opcode() == Op_ShenandoahWeakCompareAndSwapP ) || - (bol->in(1)->Opcode() == Op_ShenandoahWeakCompareAndSwapN ) || - (bol->in(1)->Opcode() == Op_ShenandoahCompareAndSwapP ) || - (bol->in(1)->Opcode() == Op_ShenandoahCompareAndSwapN ) || + (bol->in(1)->Opcode() == Op_ShenandoahCompareAndExchangeP) || + (bol->in(1)->Opcode() == Op_ShenandoahCompareAndExchangeN) || + (bol->in(1)->Opcode() == Op_ShenandoahWeakCompareAndSwapP) || + (bol->in(1)->Opcode() == Op_ShenandoahWeakCompareAndSwapN) || + (bol->in(1)->Opcode() == Op_ShenandoahCompareAndSwapP) || + (bol->in(1)->Opcode() == Op_ShenandoahCompareAndSwapN) || #endif - (bol->in(1)->Opcode() == Op_CompareAndExchangeB ) || - (bol->in(1)->Opcode() == Op_CompareAndExchangeS ) || - (bol->in(1)->Opcode() == Op_CompareAndExchangeI ) || - (bol->in(1)->Opcode() == Op_CompareAndExchangeL ) || - (bol->in(1)->Opcode() == Op_CompareAndExchangeP ) || - (bol->in(1)->Opcode() == Op_CompareAndExchangeN ) || - (bol->in(1)->Opcode() == Op_WeakCompareAndSwapB ) || - (bol->in(1)->Opcode() == Op_WeakCompareAndSwapS ) || - (bol->in(1)->Opcode() == Op_WeakCompareAndSwapI ) || - (bol->in(1)->Opcode() == Op_WeakCompareAndSwapL ) || - (bol->in(1)->Opcode() == Op_WeakCompareAndSwapP ) || - (bol->in(1)->Opcode() == Op_WeakCompareAndSwapN ) || - (bol->in(1)->Opcode() == Op_CompareAndSwapB ) || - (bol->in(1)->Opcode() == Op_CompareAndSwapS ) || - (bol->in(1)->Opcode() == Op_CompareAndSwapI ) || - (bol->in(1)->Opcode() == Op_CompareAndSwapL ) || - (bol->in(1)->Opcode() == Op_CompareAndSwapP ) || - (bol->in(1)->Opcode() == Op_CompareAndSwapN ))) + (bol->in(1)->Opcode() == Op_CompareAndExchangeB) || + (bol->in(1)->Opcode() == Op_CompareAndExchangeS) || + (bol->in(1)->Opcode() == Op_CompareAndExchangeI) || + (bol->in(1)->Opcode() == Op_CompareAndExchangeL) || + (bol->in(1)->Opcode() == Op_CompareAndExchangeP) || + (bol->in(1)->Opcode() == Op_CompareAndExchangeN) || + (bol->in(1)->Opcode() == Op_WeakCompareAndSwapB) || + (bol->in(1)->Opcode() == Op_WeakCompareAndSwapS) || + (bol->in(1)->Opcode() == Op_WeakCompareAndSwapI) || + (bol->in(1)->Opcode() == Op_WeakCompareAndSwapL) || + (bol->in(1)->Opcode() == Op_WeakCompareAndSwapP) || + (bol->in(1)->Opcode() == Op_WeakCompareAndSwapN) || + (bol->in(1)->Opcode() == Op_CompareAndSwapB) || + (bol->in(1)->Opcode() == Op_CompareAndSwapS) || + (bol->in(1)->Opcode() == Op_CompareAndSwapI) || + (bol->in(1)->Opcode() == Op_CompareAndSwapL) || + (bol->in(1)->Opcode() == Op_CompareAndSwapP) || + (bol->in(1)->Opcode() == Op_CompareAndSwapN))) return; // Allocation loops RARELY take backedge // Find the OTHER exit path from the IF Node* ex = iff->proj_out(1-test_con); float p = iff->_prob; - if( !phase->is_member( this, ex ) && iff->_fcnt == COUNT_UNKNOWN ) { - if( top == Op_IfTrue ) { - if( p < (PROB_FAIR + PROB_UNLIKELY_MAG(3))) { + if (!phase->is_member(this, ex) && iff->_fcnt == COUNT_UNKNOWN) { + if (top == Op_IfTrue) { + if (p < (PROB_FAIR + PROB_UNLIKELY_MAG(3))) { iff->_prob = PROB_STATIC_FREQUENT; } } else { - if( p > (PROB_FAIR - PROB_UNLIKELY_MAG(3))) { + if (p > (PROB_FAIR - PROB_UNLIKELY_MAG(3))) { iff->_prob = PROB_STATIC_INFREQUENT; } } @@ -3019,26 +3043,28 @@ phase->_igvn.replace_input_of(main_cmp, 2, main_cmp->in(2)->in(1)); } -//------------------------------policy_do_remove_empty_loop-------------------- -// Micro-benchmark spamming. Policy is to always remove empty loops. -// The 'DO' part is to replace the trip counter with the value it will -// have on the last iteration. This will break the loop. -bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) { +//------------------------------do_remove_empty_loop--------------------------- +// We always attempt remove empty loops. The approach is to replace the trip +// counter with the value it will have on the last iteration. This will break +// the loop. +bool IdealLoopTree::do_remove_empty_loop(PhaseIdealLoop *phase) { // Minimum size must be empty loop - if (_body.size() > EMPTY_LOOP_SIZE) + if (_body.size() > EMPTY_LOOP_SIZE) { return false; - - if (!_head->is_CountedLoop()) - return false; // Dead loop + } + if (!_head->is_CountedLoop()) { + return false; // Dead loop + } CountedLoopNode *cl = _head->as_CountedLoop(); - if (!cl->is_valid_counted_loop()) - return false; // Malformed loop - if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue)))) - return false; // Infinite loop - + if (!cl->is_valid_counted_loop()) { + return false; // Malformed loop + } + if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue)))) { + return false; // Infinite loop + } if (cl->is_pre_loop()) { - // If the loop we are removing is a pre-loop then the main and - // post loop can be removed as well + // If the loop we are removing is a pre-loop then the main and post loop + // can be removed as well. remove_main_post_loops(cl, phase); } @@ -3048,11 +3074,11 @@ for (DUIterator_Fast imax, i = cl->fast_outs(imax); i < imax; i++) { Node* n = cl->fast_out(i); if (n->Opcode() == Op_Phi) { - assert(iv == NULL, "Too many phis" ); + assert(iv == NULL, "Too many phis"); iv = n; } } - assert(iv == cl->phi(), "Wrong phi" ); + assert(iv == cl->phi(), "Wrong phi"); #endif // main and post loops have explicitly created zero trip guard @@ -3133,26 +3159,26 @@ } // Note: the final value after increment should not overflow since // counted loop has limit check predicate. - Node *final = new SubINode( exact_limit, cl->stride() ); + Node *final = new SubINode(exact_limit, cl->stride()); phase->register_new_node(final,cl->in(LoopNode::EntryControl)); phase->_igvn.replace_node(phi,final); phase->C->set_major_progress(); return true; } -//------------------------------policy_do_one_iteration_loop------------------- +//------------------------------do_one_iteration_loop-------------------------- // Convert one iteration loop into normal code. -bool IdealLoopTree::policy_do_one_iteration_loop( PhaseIdealLoop *phase ) { - if (!_head->as_Loop()->is_valid_counted_loop()) +bool IdealLoopTree::do_one_iteration_loop(PhaseIdealLoop *phase) { + if (!_head->as_Loop()->is_valid_counted_loop()) { return false; // Only for counted loop - + } CountedLoopNode *cl = _head->as_CountedLoop(); if (!cl->has_exact_trip_count() || cl->trip_count() != 1) { return false; } #ifndef PRODUCT - if(TraceLoopOpts) { + if (TraceLoopOpts) { tty->print("OneIteration "); this->dump_head(); } @@ -3173,18 +3199,18 @@ //============================================================================= //------------------------------iteration_split_impl--------------------------- -bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { +bool IdealLoopTree::iteration_split_impl(PhaseIdealLoop *phase, Node_List &old_new) { // Compute loop trip count if possible. compute_trip_count(phase); // Convert one iteration loop into normal code. - if (policy_do_one_iteration_loop(phase)) + if (do_one_iteration_loop(phase)) { return true; - + } // Check and remove empty loops (spam micro-benchmarks) - if (policy_do_remove_empty_loop(phase)) + if (do_remove_empty_loop(phase)) { return true; // Here we removed an empty loop - + } bool should_peel = policy_peeling(phase); // Should we peel? bool should_unswitch = policy_unswitching(phase); @@ -3301,14 +3327,14 @@ phase->do_unroll(this, old_new, true); } - // Adjust the pre-loop limits to align the main body - // iterations. - if (should_align) + // Adjust the pre-loop limits to align the main body iterations. + if (should_align) { Unimplemented(); - + } } else { // Else we have an unchanged counted loop - if (should_peel) // Might want to peel but do nothing else + if (should_peel) { // Might want to peel but do nothing else phase->do_peeling(this,old_new); + } } return true; } @@ -3316,33 +3342,27 @@ //============================================================================= //------------------------------iteration_split-------------------------------- -bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) { +bool IdealLoopTree::iteration_split(PhaseIdealLoop* phase, Node_List &old_new) { // Recursively iteration split nested loops - if (_child && !_child->iteration_split(phase, old_new)) + if (_child && !_child->iteration_split(phase, old_new)) { return false; + } // Clean out prior deadwood DCE_loop_body(); - // Look for loop-exit tests with my 50/50 guesses from the Parsing stage. // Replace with a 1-in-10 exit guess. - if (_parent /*not the root loop*/ && - !_irreducible && - // Also ignore the occasional dead backedge - !tail()->is_top()) { + if (!is_root() && is_loop()) { adjust_loop_exit_prob(phase); } - // Gate unrolling, RCE and peeling efforts. - if (!_child && // If not an inner loop, do not split - !_irreducible && - _allow_optimizations && - !tail()->is_top()) { // Also ignore the occasional dead backedge + // Unrolling, RCE and peeling efforts, iff innermost loop. + if (_allow_optimizations && is_innermost()) { if (!_has_call) { - if (!iteration_split_impl(phase, old_new)) { - return false; - } + if (!iteration_split_impl(phase, old_new)) { + return false; + } } else if (policy_unswitching(phase)) { phase->do_unswitching(this, old_new); return false; // need to recalculate idom data @@ -3353,8 +3373,9 @@ // trip counter when there was no major reshaping. phase->reorg_offsets(this); - if (_next && !_next->iteration_split(phase, old_new)) + if (_next && !_next->iteration_split(phase, old_new)) { return false; + } return true; } @@ -3616,7 +3637,7 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) { // Only for counted inner loops - if (!lpt->is_counted() || !lpt->is_inner()) { + if (!lpt->is_counted() || !lpt->is_innermost()) { return false; }
diff --git a/src/hotspot/share/opto/loopUnswitch.cpp b/src/hotspot/share/opto/loopUnswitch.cpp index 9928356..f27f499 100644 --- a/src/hotspot/share/opto/loopUnswitch.cpp +++ b/src/hotspot/share/opto/loopUnswitch.cpp
@@ -63,7 +63,7 @@ } // check for vectorized loops, any unswitching was already applied - if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) { + if (_head->is_CountedLoop() && _head->as_CountedLoop()->is_unroll_only()) { return false; }
diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index 72b813f..5454d13 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp
@@ -46,17 +46,13 @@ #endif //============================================================================= -//------------------------------is_loop_iv------------------------------------- -// Determine if a node is Counted loop induction variable. -// The method is declared in node.hpp. -const Node* Node::is_loop_iv() const { - if (this->is_Phi() && !this->as_Phi()->is_copy() && - this->as_Phi()->region()->is_CountedLoop() && - this->as_Phi()->region()->as_CountedLoop()->phi() == this) { - return this; - } else { - return NULL; - } +//--------------------------is_cloop_ind_var----------------------------------- +// Determine if a node is a counted loop induction variable. +// NOTE: The method is declared in "node.hpp". +bool Node::is_cloop_ind_var() const { + return (is_Phi() && !as_Phi()->is_copy() && + as_Phi()->region()->is_CountedLoop() && + as_Phi()->region()->as_CountedLoop()->phi() == this); } //============================================================================= @@ -978,33 +974,6 @@ Node* sfpt = outer_le->in(0); assert(sfpt->Opcode() == Op_SafePoint, "where's the safepoint?"); Node* inner_out = sfpt->in(0); - if (inner_out->outcnt() != 1) { - ResourceMark rm; - Unique_Node_List wq; - - for (DUIterator_Fast imax, i = inner_out->fast_outs(imax); i < imax; i++) { - Node* u = inner_out->fast_out(i); - if (u == sfpt) { - continue; - } - wq.clear(); - wq.push(u); - bool found_sfpt = false; - for (uint next = 0; next < wq.size() && !found_sfpt; next++) { - Node *n = wq.at(next); - for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !found_sfpt; i++) { - Node* u = n->fast_out(i); - if (u == sfpt) { - found_sfpt = true; - } - if (!u->is_CFG()) { - wq.push(u); - } - } - } - assert(found_sfpt, "no node in loop that's not input to safepoint"); - } - } CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd(); assert(cle == inner->loopexit_or_null(), "mismatch"); bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0; @@ -3037,10 +3006,10 @@ for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) { IdealLoopTree* lpt = iter.current(); bool is_counted = lpt->is_counted(); - if (!is_counted || !lpt->is_inner()) continue; + if (!is_counted || !lpt->is_innermost()) continue; // check for vectorized loops, any reassociation of invariants was already done - if (is_counted && lpt->_head->as_CountedLoop()->do_unroll_only()) continue; + if (is_counted && lpt->_head->as_CountedLoop()->is_unroll_only()) continue; lpt->reassociate_invariants(this);
diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 6cf2d2a..b8d69f9 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp
@@ -264,7 +264,7 @@ bool is_reduction_loop() const { return (_loop_flags&HasReductions) == HasReductions; } bool was_slp_analyzed () const { return (_loop_flags&WasSlpAnalyzed) == WasSlpAnalyzed; } bool has_passed_slp () const { return (_loop_flags&PassedSlpAnalysis) == PassedSlpAnalysis; } - bool do_unroll_only () const { return (_loop_flags&DoUnrollOnly) == DoUnrollOnly; } + bool is_unroll_only () const { return (_loop_flags&DoUnrollOnly) == DoUnrollOnly; } bool is_main_no_pre_loop() const { return _loop_flags & MainHasNoPreLoop; } bool has_atomic_post_loop () const { return (_loop_flags & HasAtomicPostLoop) == HasAtomicPostLoop; } void set_main_no_pre_loop() { _loop_flags |= MainHasNoPreLoop; } @@ -561,10 +561,10 @@ bool policy_unswitching( PhaseIdealLoop *phase ) const; // Micro-benchmark spamming. Remove empty loops. - bool policy_do_remove_empty_loop( PhaseIdealLoop *phase ); + bool do_remove_empty_loop( PhaseIdealLoop *phase ); // Convert one iteration loop into normal code. - bool policy_do_one_iteration_loop( PhaseIdealLoop *phase ); + bool do_one_iteration_loop( PhaseIdealLoop *phase ); // Return TRUE or FALSE if the loop should be peeled or not. Peel if we can // make some loop-invariant test (usually a null-check) happen before the @@ -595,7 +595,7 @@ bool policy_align( PhaseIdealLoop *phase ) const; // Return TRUE if "iff" is a range check. - bool is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const; + bool is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar DEBUG_ONLY(COMMA ProjNode *predicate_proj)) const; // Compute loop trip count if possible void compute_trip_count(PhaseIdealLoop* phase); @@ -618,9 +618,11 @@ // Put loop body on igvn work list void record_for_igvn(); - bool is_loop() { return !_irreducible && _tail && !_tail->is_top(); } - bool is_inner() { return is_loop() && _child == NULL; } - bool is_counted() { return is_loop() && _head != NULL && _head->is_CountedLoop(); } + bool is_root() { return _parent == NULL; } + // A proper/reducible loop w/o any (occasional) dead back-edge. + bool is_loop() { return !_irreducible && !tail()->is_top(); } + bool is_counted() { return is_loop() && _head->is_CountedLoop(); } + bool is_innermost() { return is_loop() && _child == NULL; } void remove_main_post_loops(CountedLoopNode *cl, PhaseIdealLoop *phase); @@ -1103,7 +1105,8 @@ BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl, int scale, Node* offset, Node* init, Node* limit, jint stride, - Node* range, bool upper, bool &overflow); + Node* range, bool upper, bool &overflow, + bool negate); // Implementation of the loop predication to promote checks outside the loop bool loop_predication_impl(IdealLoopTree *loop); @@ -1307,6 +1310,14 @@ ProjNode* output_proj, IdealLoopTree* loop); void check_created_predicate_for_unswitching(const Node* new_entry) const PRODUCT_RETURN; + // Determine if a method is too big for a/another round of split-if, based on + // a magic (approximate) ratio derived from the equally magic constant 35000, + // previously used for this purpose (but without relating to the node limit). + bool must_throttle_split_if() { + uint threshold = C->max_node_limit() * 2 / 5; + return C->live_nodes() > threshold; + } + bool _created_loop_node; #ifdef ASSERT void dump_real_LCA(Node* early, Node* wrong_lca); @@ -1408,14 +1419,11 @@ };// class CountedLoopReserveKit inline Node* IdealLoopTree::tail() { -// Handle lazy update of _tail field - Node *n = _tail; - //while( !n->in(0) ) // Skip dead CFG nodes - //n = n->in(1); - if (n->in(0) == NULL) - n = _phase->get_ctrl(n); - _tail = n; - return n; + // Handle lazy update of _tail field. + if (_tail->in(0) == NULL) { + _tail = _phase->get_ctrl(_tail); + } + return _tail; } inline Node* IdealLoopTree::head() {
diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index d6cc112..096c96a 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp
@@ -1009,8 +1009,7 @@ } } - // Use same limit as split_if_with_blocks_post - if( C->live_nodes() > 35000 ) return n; // Method too big + if (must_throttle_split_if()) return n; // Split 'n' through the merge point if it is profitable Node *phi = split_thru_phi( n, n_blk, policy ); @@ -1096,6 +1095,16 @@ if (!n->in(0)->is_Region()) { return false; } + + IfNode* n_if = n->as_If(); + if (n_if->proj_out(0)->outcnt() > 1 || n_if->proj_out(1)->outcnt() > 1) { + // Removing the dominated If node by using the split-if optimization does not work if there are data dependencies. + // Some data dependencies depend on its immediate dominator If node and should not be separated from it (e.g. null + // checks, division by zero checks etc.). Bail out for now until data dependencies are correctly handled when + // optimizing back-to-back ifs. + return false; + } + Node* region = n->in(0); Node* dom = idom(region); if (!dom->is_If() || dom->in(1) != n->in(1)) { @@ -1118,9 +1127,10 @@ return true; } -bool PhaseIdealLoop::can_split_if(Node *n_ctrl) { - if (C->live_nodes() > 35000) { - return false; // Method too big + +bool PhaseIdealLoop::can_split_if(Node* n_ctrl) { + if (must_throttle_split_if()) { + return false; } // Do not do 'split-if' if irreducible loops are present. @@ -1483,12 +1493,13 @@ // Check for aggressive application of 'split-if' optimization, // using basic block level info. void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack, bool last_round) { - Node *n = C->root(); - visited.set(n->_idx); // first, mark node as visited + Node* root = C->root(); + visited.set(root->_idx); // first, mark root as visited // Do pre-visit work for root - n = split_if_with_blocks_pre( n ); - uint cnt = n->outcnt(); - uint i = 0; + Node* n = split_if_with_blocks_pre(root); + uint cnt = n->outcnt(); + uint i = 0; + while (true) { // Visit all children if (i < cnt) { @@ -1496,7 +1507,7 @@ ++i; if (use->outcnt() != 0 && !visited.test_set(use->_idx)) { // Now do pre-visit work for this use - use = split_if_with_blocks_pre( use ); + use = split_if_with_blocks_pre(use); nstack.push(n, i); // Save parent and next use's index. n = use; // Process all children of current use. cnt = use->outcnt(); @@ -1507,7 +1518,10 @@ // All of n's children have been processed, complete post-processing. if (cnt != 0 && !n->is_Con()) { assert(has_node(n), "no dead nodes"); - split_if_with_blocks_post( n, last_round ); + split_if_with_blocks_post(n, last_round); + } + if (must_throttle_split_if()) { + nstack.clear(); } if (nstack.is_empty()) { // Finished all nodes on stack. @@ -1854,7 +1868,10 @@ Node* c = phase->get_ctrl(u); IdealLoopTree* u_loop = phase->get_loop(c); assert(!loop->is_member(u_loop), "can be in outer loop or out of both loops only"); - if (outer_loop->is_member(u_loop)) { + if (outer_loop->is_member(u_loop) || + // nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of + // the outer loop too + (u->in(0) != NULL && outer_loop->is_member(phase->get_loop(u->in(0))))) { wq.push(u); } } @@ -1974,11 +1991,20 @@ Node* old = extra_data_nodes.at(i); clone_outer_loop_helper(old, loop, outer_loop, old_new, wq, this, true); } + + Node* inner_out = sfpt->in(0); + if (inner_out->outcnt() > 1) { + clone_outer_loop_helper(inner_out, loop, outer_loop, old_new, wq, this, true); + } + Node* new_ctrl = cl->outer_loop_exit(); assert(get_loop(new_ctrl) != outer_loop, "must be out of the loop nest"); for (uint i = 0; i < wq.size(); i++) { Node* n = wq.at(i); set_ctrl(n, new_ctrl); + if (n->in(0) != NULL) { + _igvn.replace_input_of(n, 0, new_ctrl); + } clone_outer_loop_helper(n, loop, outer_loop, old_new, wq, this, false); } } else {
diff --git a/src/hotspot/share/opto/machnode.cpp b/src/hotspot/share/opto/machnode.cpp index 737cca8..8d526b1 100644 --- a/src/hotspot/share/opto/machnode.cpp +++ b/src/hotspot/share/opto/machnode.cpp
@@ -292,7 +292,7 @@ } offset = disp; - // In i486.ad, indOffset32X uses base==RegI and disp==RegP, + // In x86_32.ad, indOffset32X uses base==RegI and disp==RegP, // this will prevent alias analysis without the following support: // Lookup the TypePtr used by indOffset32X, a compile-time constant oop, // Add the offset determined by the "base", or use Type::OffsetBot.
diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index 030907f..a523256 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp
@@ -150,7 +150,7 @@ virtual int index_position() const; // index edge position, or -1 // Access the TypeKlassPtr of operands with a base==RegI and disp==RegP - // Only returns non-null value for i486.ad's indOffset32X + // Only returns non-null value for x86_32.ad's indOffset32X virtual const TypePtr *disp_as_type() const { return NULL; } // Return the label
diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 9becac0..eed1156 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp
@@ -592,7 +592,7 @@ ArrayCopyNode* MemNode::find_array_copy_clone(PhaseTransform* phase, Node* ld_alloc, Node* mem) const { if (mem->is_Proj() && mem->in(0) != NULL && (mem->in(0)->Opcode() == Op_MemBarStoreStore || - mem->in(0)->Opcode() == Op_MemBarCPUOrder)) { + mem->in(0)->Opcode() == Op_MemBarCPUOrder)) { if (ld_alloc != NULL) { // Check if there is an array copy for a clone Node* mb = mem->in(0); @@ -1060,7 +1060,6 @@ // This is more general than load from boxing objects. if (skip_through_membars(atp, tp, phase->C->eliminate_boxing())) { uint alias_idx = atp->index(); - bool final = !atp->is_rewritable(); Node* result = NULL; Node* current = st; // Skip through chains of MemBarNodes checking the MergeMems for @@ -1068,17 +1067,19 @@ // kind of node is encountered. Loads from final memory can skip // through any kind of MemBar but normal loads shouldn't skip // through MemBarAcquire since the could allow them to move out of - // a synchronized region. + // a synchronized region. It is not safe to step over MemBarCPUOrder, + // because alias info above them may be inaccurate (e.g., due to + // mixed/mismatched unsafe accesses). + bool is_final_mem = !atp->is_rewritable(); while (current->is_Proj()) { int opc = current->in(0)->Opcode(); - if ((final && (opc == Op_MemBarAcquire || - opc == Op_MemBarAcquireLock || - opc == Op_LoadFence)) || + if ((is_final_mem && (opc == Op_MemBarAcquire || + opc == Op_MemBarAcquireLock || + opc == Op_LoadFence)) || opc == Op_MemBarRelease || opc == Op_StoreFence || opc == Op_MemBarReleaseLock || - opc == Op_MemBarStoreStore || - opc == Op_MemBarCPUOrder) { + opc == Op_MemBarStoreStore) { Node* mem = current->in(0)->in(TypeFunc::Memory); if (mem->is_MergeMem()) { MergeMemNode* merge = mem->as_MergeMem();
diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index fba19bd..6616fa0 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp
@@ -51,7 +51,7 @@ //------------------------------Identity--------------------------------------- // Multiplying a one preserves the other argument Node* MulNode::Identity(PhaseGVN* phase) { - register const Type *one = mul_id(); // The multiplicative identity + const Type *one = mul_id(); // The multiplicative identity if( phase->type( in(1) )->higher_equal( one ) ) return in(2); if( phase->type( in(2) )->higher_equal( one ) ) return in(1);
diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 95aea80..bc48df2 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp
@@ -1021,9 +1021,9 @@ // value, if it appears (by local graph inspection) to be computed by a simple conditional. bool is_iteratively_computed(); - // Determine if a node is Counted loop induction variable. - // The method is defined in loopnode.cpp. - const Node* is_loop_iv() const; + // Determine if a node is a counted loop induction variable. + // NOTE: The method is defined in "loopnode.cpp". + bool is_cloop_ind_var() const; // Return a node with opcode "opc" and same inputs as "this" if one can // be found; Otherwise return NULL;
diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp index 04f8eca..4e06d08 100644 --- a/src/hotspot/share/opto/parse1.cpp +++ b/src/hotspot/share/opto/parse1.cpp
@@ -524,11 +524,6 @@ #ifdef ASSERT if (depth() == 1) { assert(C->is_osr_compilation() == this->is_osr_parse(), "OSR in sync"); - if (C->tf() != tf()) { - MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag); - assert(C->env()->system_dictionary_modification_counter_changed(), - "Must invalidate if TypeFuncs differ"); - } } else { assert(!this->is_osr_parse(), "no recursive OSR"); } @@ -1035,20 +1030,12 @@ const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); Node* ret_phi = _gvn.transform( _exits.argument(0) ); if (!_exits.control()->is_top() && _gvn.type(ret_phi)->empty()) { - // In case of concurrent class loading, the type we set for the - // ret_phi in build_exits() may have been too optimistic and the - // ret_phi may be top now. - // Otherwise, we've encountered an error and have to mark the method as - // not compilable. Just using an assertion instead would be dangerous - // as this could lead to an infinite compile loop in non-debug builds. - { - MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag); - if (C->env()->system_dictionary_modification_counter_changed()) { - C->record_failure(C2Compiler::retry_class_loading_during_parsing()); - } else { - C->record_method_not_compilable("Can't determine return type."); - } - } + // If the type we set for the ret_phi in build_exits() is too optimistic and + // the ret_phi is top now, there's an extremely small chance that it may be due to class + // loading. It could also be due to an error, so mark this method as not compilable because + // otherwise this could lead to an infinite compile loop. + // In any case, this code path is rarely (and never in my testing) reached. + C->record_method_not_compilable("Can't determine return type."); return; } if (ret_type->isa_int()) {
diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index cf73e92..8d84b4f 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp
@@ -2386,7 +2386,7 @@ if (Matcher::convL2FSupported()) { a = pop_pair(); b = _gvn.transform( new ConvL2FNode(a)); - // For i486.ad, FILD doesn't restrict precision to 24 or 53 bits. + // For x86_32.ad, FILD doesn't restrict precision to 24 or 53 bits. // Rather than storing the result into an FP register then pushing // out to memory to round, the machine instruction that implements // ConvL2D is responsible for rounding. @@ -2401,7 +2401,7 @@ case Bytecodes::_l2d: a = pop_pair(); b = _gvn.transform( new ConvL2DNode(a)); - // For i486.ad, rounding is always necessary (see _l2f above). + // For x86_32.ad, rounding is always necessary (see _l2f above). // c = dprecision_rounding(b); c = _gvn.transform(b); push_pair(c);
diff --git a/src/hotspot/share/opto/postaloc.cpp b/src/hotspot/share/opto/postaloc.cpp index d572ac9..46766b6 100644 --- a/src/hotspot/share/opto/postaloc.cpp +++ b/src/hotspot/share/opto/postaloc.cpp
@@ -600,7 +600,7 @@ if( phi != x && u != x ) // Found a different input u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input } - if (u != NodeSentinel) { // Junk Phi. Remove + if (u != NodeSentinel || phi->outcnt() == 0) { // Junk Phi. Remove phi->replace_by(u); j -= yank_if_dead(phi, block, &value, ®nd); phi_dex--;
diff --git a/src/hotspot/share/opto/runtime.cpp b/src/hotspot/share/opto/runtime.cpp index d2ea10b..4c86b60 100644 --- a/src/hotspot/share/opto/runtime.cpp +++ b/src/hotspot/share/opto/runtime.cpp
@@ -68,6 +68,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" #include "runtime/threadCritical.hpp" +#include "runtime/threadWXSetters.inline.hpp" #include "runtime/vframe.hpp" #include "runtime/vframeArray.hpp" #include "runtime/vframe_hp.hpp" @@ -1444,6 +1445,10 @@ // *THIS IS NOT RECOMMENDED PROGRAMMING STYLE* // address OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc) { + + // Enable WXWrite: the function called directly by compiled code. + MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); + #ifndef PRODUCT SharedRuntime::_rethrow_ctr++; // count rethrows #endif
diff --git a/src/hotspot/share/opto/stringopts.cpp b/src/hotspot/share/opto/stringopts.cpp index 1681333..e8e493b 100644 --- a/src/hotspot/share/opto/stringopts.cpp +++ b/src/hotspot/share/opto/stringopts.cpp
@@ -62,7 +62,8 @@ StringMode, IntMode, CharMode, - StringNullCheckMode + StringNullCheckMode, + NegativeIntCheckMode }; StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end): @@ -119,12 +120,19 @@ void push_string(Node* value) { push(value, StringMode); } + void push_string_null_check(Node* value) { push(value, StringNullCheckMode); } + + void push_negative_int_check(Node* value) { + push(value, NegativeIntCheckMode); + } + void push_int(Node* value) { push(value, IntMode); } + void push_char(Node* value) { push(value, CharMode); } @@ -274,6 +282,20 @@ C->gvn_replace_by(n, n->in(0)->in(0)); // get rid of the other projection C->gvn_replace_by(n->in(0)->as_If()->proj_out(false), C->top()); + } else if (n->is_Region()) { + Node* iff = n->in(1)->in(0); + assert(n->req() == 3 && n->in(2)->in(0) == iff, "not a diamond"); + assert(iff->is_If(), "no if for the diamond"); + Node* bol = iff->in(1); + assert(bol->is_Bool(), "unexpected if shape"); + Node* cmp = bol->in(1); + assert(cmp->is_Cmp(), "unexpected if shape"); + if (cmp->in(1)->is_top() || cmp->in(2)->is_top()) { + // This region should lose its Phis and be optimized out by igvn but there's a chance the if folds to top first + // which then causes a reachable part of the graph to become dead. + Compile* C = _stringopts->C; + C->gvn_replace_by(n, iff->in(0)); + } } } } @@ -485,13 +507,35 @@ #ifndef PRODUCT if (PrintOptimizeStringConcat) { tty->print("giving up because StringBuilder(null) throws exception"); - alloc->jvms()->dump_spec(tty); tty->cr(); + alloc->jvms()->dump_spec(tty); + tty->cr(); } #endif return NULL; } // StringBuilder(str) argument needs null check. sc->push_string_null_check(use->in(TypeFunc::Parms + 1)); + } else if (sig == ciSymbol::int_void_signature()) { + // StringBuilder(int) case. + Node* parm = use->in(TypeFunc::Parms + 1); + assert(parm != NULL, "must exist"); + const TypeInt* type = _gvn->type(parm)->is_int(); + if (type->_hi < 0) { + // Initial capacity argument is always negative in which case StringBuilder(int) throws + // a NegativeArraySizeException. Bail out from string opts. +#ifndef PRODUCT + if (PrintOptimizeStringConcat) { + tty->print("giving up because a negative argument is passed to StringBuilder(int) which " + "throws a NegativeArraySizeException"); + alloc->jvms()->dump_spec(tty); + tty->cr(); + } +#endif + return NULL; + } else if (type->_lo < 0) { + // Argument could be negative: We need a runtime check to throw NegativeArraySizeException in that case. + sc->push_negative_int_check(parm); + } } // The int variant takes an initial size for the backing // array so just treat it like the void version. @@ -1001,6 +1045,7 @@ // The IGVN will make this simple diamond go away when it // transforms the Region. Make sure it sees it. Compile::current()->record_for_igvn(ptr); + _control.push(ptr); ptr = ptr->in(1)->in(0)->in(0); continue; } @@ -1777,6 +1822,23 @@ for (int argi = 0; argi < sc->num_arguments(); argi++) { Node* arg = sc->argument(argi); switch (sc->mode(argi)) { + case StringConcat::NegativeIntCheckMode: { + // Initial capacity argument might be negative in which case StringBuilder(int) throws + // a NegativeArraySizeException. Insert a runtime check with an uncommon trap. + const TypeInt* type = kit.gvn().type(arg)->is_int(); + assert(type->_hi >= 0 && type->_lo < 0, "no runtime int check needed"); + Node* p = __ Bool(__ CmpI(arg, kit.intcon(0)), BoolTest::ge); + IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN); + { + // Negative int -> uncommon trap. + PreserveJVMState pjvms(&kit); + kit.set_control(__ IfFalse(iff)); + kit.uncommon_trap(Deoptimization::Reason_intrinsic, + Deoptimization::Action_maybe_recompile); + } + kit.set_control(__ IfTrue(iff)); + break; + } case StringConcat::IntMode: { Node* string_size = int_stringSize(kit, arg); @@ -1946,6 +2008,8 @@ for (int argi = 0; argi < sc->num_arguments(); argi++) { Node* arg = sc->argument(argi); switch (sc->mode(argi)) { + case StringConcat::NegativeIntCheckMode: + break; // Nothing to do, was only needed to add a runtime check earlier. case StringConcat::IntMode: { start = int_getChars(kit, arg, dst_array, coder, start, string_sizes->in(argi)); break;
diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index a3c171a..906ba33 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp
@@ -114,31 +114,37 @@ } //============================================================================= - //------------------------------Helper function-------------------------------- -static bool ok_to_convert(Node* inc, Node* iv) { - // Do not collapse (x+c0)-y if "+" is a loop increment, because the - // "-" is loop invariant and collapsing extends the live-range of "x" - // to overlap with the "+", forcing another register to be used in - // the loop. - // This test will be clearer with '&&' (apply DeMorgan's rule) - // but I like the early cutouts that happen here. - const PhiNode *phi; - if( ( !inc->in(1)->is_Phi() || - !(phi=inc->in(1)->as_Phi()) || - phi->is_copy() || - !phi->region()->is_CountedLoop() || - inc != phi->region()->as_CountedLoop()->incr() ) - && - // Do not collapse (x+c0)-iv if "iv" is a loop induction variable, - // because "x" maybe invariant. - ( !iv->is_loop_iv() ) - ) { - return true; - } else { - return false; - } + +static bool is_cloop_increment(Node* inc) { + precond(inc->Opcode() == Op_AddI || inc->Opcode() == Op_AddL); + + if (!inc->in(1)->is_Phi()) { + return false; + } + const PhiNode* phi = inc->in(1)->as_Phi(); + + if (phi->is_copy() || !phi->region()->is_CountedLoop()) { + return false; + } + + return inc == phi->region()->as_CountedLoop()->incr(); } + +// Given the expression '(x + C) - v', or +// 'v - (x + C)', we examine nodes '+' and 'v': +// +// 1. Do not convert if '+' is a counted-loop increment, because the '-' is +// loop invariant and converting extends the live-range of 'x' to overlap +// with the '+', forcing another register to be used in the loop. +// +// 2. Do not convert if 'v' is a counted-loop induction variable, because +// 'x' might be invariant. +// +static bool ok_to_convert(Node* inc, Node* var) { + return !(is_cloop_increment(inc) || var->is_cloop_ind_var()); +} + //------------------------------Ideal------------------------------------------ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ Node *in1 = in(1);
diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 92f70b7..393d271 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp
@@ -148,7 +148,7 @@ // Skip any loops already optimized by slp if (cl->is_vectorized_loop()) return; - if (cl->do_unroll_only()) return; + if (cl->is_unroll_only()) return; if (cl->is_main_loop()) { // Check for pre-loop ending with CountedLoopEnd(Bool(Cmp(x,Opaque1(limit))))
diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index aea5d70..012eb93 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp
@@ -1,6 +1,7 @@ /* * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 Red Hat, Inc. + * Copyright (c) 2021, Azul Systems, 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 @@ -97,7 +98,7 @@ static jint CurrentVersion = JNI_VERSION_10; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* ); #endif @@ -4055,6 +4056,7 @@ // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving. ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); + MACOS_AARCH64_ONLY(thread->enable_wx(WXExec)); } else { // If create_vm exits because of a pending exception, exit with that // exception. In the future when we figure out how to reclaim memory, @@ -4093,11 +4095,11 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) { jint result = JNI_ERR; // On Windows, let CreateJavaVM run with SEH protection -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) __try { #endif result = JNI_CreateJavaVM_inner(vm, penv, args); -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } @@ -4149,6 +4151,10 @@ // Since this is not a JVM_ENTRY we have to set the thread state manually before entering. JavaThread* thread = JavaThread::current(); + + // We are going to VM, change W^X state to the expected one. + MACOS_AARCH64_ONLY(WXMode oldmode = thread->enable_wx(WXWrite)); + ThreadStateTransition::transition_from_native(thread, _thread_in_vm); if (Threads::destroy_vm()) { // Should not change thread state, VM is gone @@ -4157,6 +4163,7 @@ return res; } else { ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); + MACOS_AARCH64_ONLY(thread->enable_wx(oldmode)); res = JNI_ERR; return res; } @@ -4165,11 +4172,11 @@ jint JNICALL jni_DestroyJavaVM(JavaVM *vm) { jint result = JNI_ERR; // On Windows, we need SEH protection -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) __try { #endif result = jni_DestroyJavaVM_inner(vm); -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } @@ -4210,6 +4217,7 @@ thread->record_stack_base_and_size(); thread->register_thread_stack_with_NMT(); thread->initialize_thread_current(); + MACOS_AARCH64_ONLY(thread->init_wx()); if (!os::create_attached_thread(thread)) { thread->smr_delete(); @@ -4256,7 +4264,7 @@ if (attach_failed) { // Added missing cleanup - thread->cleanup_failed_attach_current_thread(); + thread->cleanup_failed_attach_current_thread(daemon); return JNI_ERR; } @@ -4284,6 +4292,7 @@ // needed. ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); + MACOS_AARCH64_ONLY(thread->enable_wx(WXExec)); // Perform any platform dependent FPU setup os::setup_fpu(); @@ -4338,6 +4347,9 @@ return JNI_ERR; } + // We are going to VM, change W^X state to the expected one. + MACOS_AARCH64_ONLY(thread->enable_wx(WXWrite)); + // Safepoint support. Have to do call-back to safepoint code, if in the // middle of a safepoint operation ThreadStateTransition::transition_from_native(thread, _thread_in_vm); @@ -4354,6 +4366,10 @@ thread->exit(false, JavaThread::jni_detach); thread->smr_delete(); + // Go to the execute mode, the initial state of the thread on creation. + // Use os interface as the thread is not a JavaThread anymore. + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXExec)); + HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK); return JNI_OK; }
diff --git a/src/hotspot/share/prims/jniCheck.cpp b/src/hotspot/share/prims/jniCheck.cpp index 6ccefea..26db55a 100644 --- a/src/hotspot/share/prims/jniCheck.cpp +++ b/src/hotspot/share/prims/jniCheck.cpp
@@ -100,6 +100,7 @@ if (env != xenv) { \ NativeReportJNIFatalError(thr, warn_wrong_jnienv); \ } \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thr)); \ VM_ENTRY_BASE(result_type, header, thr)
diff --git a/src/hotspot/share/prims/jniFastGetField.hpp b/src/hotspot/share/prims/jniFastGetField.hpp index e8e65d4..8d62a63 100644 --- a/src/hotspot/share/prims/jniFastGetField.hpp +++ b/src/hotspot/share/prims/jniFastGetField.hpp
@@ -65,6 +65,11 @@ static address generate_fast_get_int_field0(BasicType type); static address generate_fast_get_float_field0(BasicType type); +#ifdef AARCH64 + template<int BType> + static address generate_fast_get_int_field1(); +#endif // AARCH64 + public: #if defined(_WINDOWS) && !defined(_WIN64) static GetBooleanField_t jni_fast_GetBooleanField_fp;
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 59bef6f..4911e59 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp
@@ -2387,7 +2387,7 @@ ConstantPool* cp = InstanceKlass::cast(k)->constants(); for (int index = cp->length() - 1; index >= 0; index--) { constantTag tag = cp->tag_at(index); - types[index] = (tag.is_unresolved_klass()) ? JVM_CONSTANT_Class : tag.value(); + types[index] = (tag.is_unresolved_klass()) ? (unsigned char) JVM_CONSTANT_Class : tag.value(); } } JVM_END @@ -3442,7 +3442,7 @@ // Library support /////////////////////////////////////////////////////////////////////////// -JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name)) +JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name, jboolean throwException)) //%note jvm_ct JVMWrapper("JVM_LoadLibrary"); char ebuf[1024]; @@ -3452,18 +3452,22 @@ load_result = os::dll_load(name, ebuf, sizeof ebuf); } if (load_result == NULL) { - char msg[1024]; - jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf); - // Since 'ebuf' may contain a string encoded using - // platform encoding scheme, we need to pass - // Exceptions::unsafe_to_utf8 to the new_exception method - // as the last argument. See bug 6367357. - Handle h_exception = - Exceptions::new_exception(thread, - vmSymbols::java_lang_UnsatisfiedLinkError(), - msg, Exceptions::unsafe_to_utf8); + if (throwException) { + char msg[1024]; + jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf); + // Since 'ebuf' may contain a string encoded using + // platform encoding scheme, we need to pass + // Exceptions::unsafe_to_utf8 to the new_exception method + // as the last argument. See bug 6367357. + Handle h_exception = + Exceptions::new_exception(thread, + vmSymbols::java_lang_UnsatisfiedLinkError(), + msg, Exceptions::unsafe_to_utf8); - THROW_HANDLE_0(h_exception); + THROW_HANDLE_0(h_exception); + } else { + return load_result; + } } return load_result; JVM_END
diff --git a/src/hotspot/share/prims/jvmtiEnter.xsl b/src/hotspot/share/prims/jvmtiEnter.xsl index 9388c26..a78f39a 100644 --- a/src/hotspot/share/prims/jvmtiEnter.xsl +++ b/src/hotspot/share/prims/jvmtiEnter.xsl
@@ -432,6 +432,8 @@ <xsl:if test="count(@impl)=0 or not(contains(@impl,'innative'))"> <xsl:text>JavaThread* current_thread = (JavaThread*)this_thread;</xsl:text> <xsl:value-of select="$space"/> + <xsl:text>MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread));</xsl:text> + <xsl:value-of select="$space"/> <xsl:text>ThreadInVMfromNative __tiv(current_thread);</xsl:text> <xsl:value-of select="$space"/> <xsl:text>VM_ENTRY_BASE(jvmtiError, </xsl:text>
diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 5e256db..570a2f3 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp
@@ -172,6 +172,7 @@ // other than the current thread is required we need to transition // from native so as to resolve the jthread. + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread)); ThreadInVMfromNative __tiv(current_thread); VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread) debug_only(VMNativeEntryWrapper __vew;) @@ -3286,6 +3287,8 @@ } else { int r = 0; Thread* thread = Thread::current(); + // 8266889: raw_enter changes Java thread state, needs WXWrite + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); if (thread->is_Java_thread()) { JavaThread* current_thread = (JavaThread*)thread; @@ -3383,6 +3386,8 @@ JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) { int r = 0; Thread* thread = Thread::current(); + // 8266889: raw_wait changes Java thread state, needs WXWrite + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); if (thread->is_Java_thread()) { JavaThread* current_thread = (JavaThread*)thread;
diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index efb7d36..093c790 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp
@@ -814,7 +814,7 @@ "at safepoint or target thread is suspended"); int count = 0; if (java_thread->has_last_Java_frame()) { - RegisterMap reg_map(java_thread); + RegisterMap reg_map(java_thread, false /* update_map */); Thread* current_thread = Thread::current(); ResourceMark rm(current_thread); javaVFrame *jvf = java_thread->last_java_vframe(®_map);
diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp index fb81189..aee84b1 100644 --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
@@ -219,9 +219,6 @@ ResolvedMethodTable::adjust_method_entries(&trace_name_printed); } - // Disable any dependent concurrent compilations - SystemDictionary::notice_modification(); - // Set flag indicating that some invariants are no longer true. // See jvmtiExport.hpp for detailed explanation. JvmtiExport::set_has_redefined_a_class();
diff --git a/src/hotspot/share/prims/whitebox.inline.hpp b/src/hotspot/share/prims/whitebox.inline.hpp index c03ecb4..f0cbc07 100644 --- a/src/hotspot/share/prims/whitebox.inline.hpp +++ b/src/hotspot/share/prims/whitebox.inline.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,8 @@ // Entry macro to transition from JNI to VM state. #define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header) \ - ClearPendingJniExcCheck _clearCheck(env); + ClearPendingJniExcCheck _clearCheck(env); \ + MACOS_AARCH64_ONLY(ThreadWXEnable _wx(WXWrite, thread)); #define WB_END JNI_END
diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index bd439aa..73444c4 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -450,12 +450,6 @@ static ArgsRange check_memory_size(julong size, julong min_size, julong max_size); static ArgsRange parse_memory_size(const char* s, julong* long_arg, julong min_size, julong max_size = max_uintx); - // Parse a string for a unsigned integer. Returns true if value - // is an unsigned integer greater than or equal to the minimum - // parameter passed and returns the value in uintx_arg. Returns - // false otherwise, with uintx_arg undefined. - static bool parse_uintx(const char* value, uintx* uintx_arg, - uintx min_size); // methods to build strings from individual args static void build_jvm_args(const char* arg); @@ -493,6 +487,12 @@ public: // Parses the arguments, first phase static jint parse(const JavaVMInitArgs* args); + // Parse a string for a unsigned integer. Returns true if value + // is an unsigned integer greater than or equal to the minimum + // parameter passed and returns the value in uintx_arg. Returns + // false otherwise, with uintx_arg undefined. + static bool parse_uintx(const char* value, uintx* uintx_arg, + uintx min_size); // Apply ergonomics static jint apply_ergo(); // Adjusts the arguments after the OS have adjusted the arguments
diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 024efd9..c87fd02 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp
@@ -54,6 +54,7 @@ #include "runtime/stubRoutines.hpp" #include "runtime/thread.hpp" #include "runtime/threadSMR.hpp" +#include "runtime/threadWXSetters.inline.hpp" #include "runtime/vframe.hpp" #include "runtime/vframeArray.hpp" #include "runtime/vframe_hp.hpp" @@ -687,6 +688,7 @@ // at an uncommon trap for an invoke (where the compiler // generates debug info before the invoke has executed) Bytecodes::Code cur_code = str.next(); + Bytecodes::Code next_code = Bytecodes::_shouldnotreachhere; if (Bytecodes::is_invoke(cur_code)) { Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci()); cur_invoke_parameter_size = invoke.size_of_parameters(); @@ -695,7 +697,7 @@ } } if (str.bci() < max_bci) { - Bytecodes::Code next_code = str.next(); + next_code = str.next(); if (next_code >= 0) { // The interpreter oop map generator reports results before // the current bytecode has executed except in the case of @@ -745,6 +747,10 @@ // Print out some information that will help us debug the problem tty->print_cr("Wrong number of expression stack elements during deoptimization"); tty->print_cr(" Error occurred while verifying frame %d (0..%d, 0 is topmost)", i, cur_array->frames() - 1); + tty->print_cr(" Current code %s", Bytecodes::name(cur_code)); + if (try_next_mask) { + tty->print_cr(" Next code %s", Bytecodes::name(next_code)); + } tty->print_cr(" Fabricated interpreter frame had %d expression stack elements", iframe->interpreter_frame_expression_stack_size()); tty->print_cr(" Interpreter oop map had %d expression stack elements", mask.expression_stack_size()); @@ -1986,7 +1992,8 @@ uint idx = reason; #if INCLUDE_JVMCI if (is_osr) { - idx += Reason_LIMIT; + // Upper half of history array used for traps in OSR compilations + idx += Reason_TRAP_HISTORY_LENGTH; } #endif uint prior_trap_count = trap_mdo->trap_count(idx); @@ -2073,6 +2080,9 @@ } Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request, jint exec_mode) { + // Enable WXWrite: current function is called from methods compiled by C2 directly + MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); + if (TraceDeoptimization) { tty->print("Uncommon trap "); }
diff --git a/src/hotspot/share/runtime/deoptimization.hpp b/src/hotspot/share/runtime/deoptimization.hpp index 79b5964..4b201cf 100644 --- a/src/hotspot/share/runtime/deoptimization.hpp +++ b/src/hotspot/share/runtime/deoptimization.hpp
@@ -38,6 +38,7 @@ public: // What condition caused the deoptimization? + // Note: Keep this enum in sync. with Deoptimization::_trap_reason_name. enum DeoptReason { Reason_many = -1, // indicates presence of several reasons Reason_none = 0, // indicates absence of a relevant deopt. @@ -88,20 +89,22 @@ Reason_jsr_mismatch, #endif + // Used to define MethodData::_trap_hist_limit where Reason_tenured isn't included + Reason_TRAP_HISTORY_LENGTH, + // Reason_tenured is counted separately, add normal counted Reasons above. - // Related to MethodData::_trap_hist_limit where Reason_tenured isn't included - Reason_tenured, // age of the code has reached the limit + Reason_tenured = Reason_TRAP_HISTORY_LENGTH, // age of the code has reached the limit Reason_LIMIT, - // Note: Keep this enum in sync. with _trap_reason_name. - Reason_RECORDED_LIMIT = Reason_profile_predicate // some are not recorded per bc // Note: Reason_RECORDED_LIMIT should fit into 31 bits of // DataLayout::trap_bits. This dependency is enforced indirectly // via asserts, to avoid excessive direct header-to-header dependencies. // See Deoptimization::trap_state_reason and class DataLayout. + Reason_RECORDED_LIMIT = Reason_profile_predicate, // some are not recorded per bc }; // What action must be taken by the runtime? + // Note: Keep this enum in sync. with Deoptimization::_trap_action_name. enum DeoptAction { Action_none, // just interpret, do not invalidate nmethod Action_maybe_recompile, // recompile the nmethod; need not invalidate @@ -109,7 +112,6 @@ Action_make_not_entrant, // invalidate the nmethod, recompile (probably) Action_make_not_compilable, // invalidate the nmethod and do not compile Action_LIMIT - // Note: Keep this enum in sync. with _trap_action_name. }; enum {
diff --git a/src/hotspot/share/runtime/fieldDescriptor.cpp b/src/hotspot/share/runtime/fieldDescriptor.cpp index fc5f01a..53d72a1 100644 --- a/src/hotspot/share/runtime/fieldDescriptor.cpp +++ b/src/hotspot/share/runtime/fieldDescriptor.cpp
@@ -55,7 +55,7 @@ } } assert(false, "should never happen"); - return NULL; + return vmSymbols::void_signature(); // return a default value (for code analyzers) } AnnotationArray* fieldDescriptor::annotations() const {
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 5c38950..3d2e4e6 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp
@@ -580,22 +580,22 @@ "Print malloc/free statistics") \ \ develop(bool, ZapResourceArea, trueInDebug, \ - "Zap freed resource/arena space with 0xABABABAB") \ + "Zap freed resource/arena space") \ \ notproduct(bool, ZapVMHandleArea, trueInDebug, \ - "Zap freed VM handle space with 0xBCBCBCBC") \ + "Zap freed VM handle space") \ \ notproduct(bool, ZapStackSegments, trueInDebug, \ - "Zap allocated/freed stack segments with 0xFADFADED") \ + "Zap allocated/freed stack segments") \ \ develop(bool, ZapUnusedHeapArea, trueInDebug, \ - "Zap unused heap space with 0xBAADBABE") \ + "Zap unused heap space") \ \ develop(bool, CheckZapUnusedHeapArea, false, \ "Check zapping of unused heap space") \ \ develop(bool, ZapFillerObjects, trueInDebug, \ - "Zap filler objects with 0xDEAFBABE") \ + "Zap filler objects") \ \ develop(bool, PrintVMMessages, true, \ "Print VM messages on console") \ @@ -1824,6 +1824,9 @@ "class pointers are used") \ range(1*M, 3*G) \ \ + diagnostic(bool, PrintMetaspaceStatisticsAtExit, false, \ + "Print metaspace statistics upon VM exit.") \ + \ manageable(uintx, MinHeapFreeRatio, 40, \ "The minimum percentage of heap free after GC to avoid expansion."\ " For most GCs this applies to the old generation. In G1 and" \
diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp index 0267345..5986d12 100644 --- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp
@@ -1,5 +1,6 @@ /* * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -32,6 +33,7 @@ #include "runtime/safepointMechanism.inline.hpp" #include "runtime/safepointVerifiers.hpp" #include "runtime/thread.hpp" +#include "runtime/threadWXSetters.inline.hpp" #include "runtime/vmOperations.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" @@ -403,6 +405,8 @@ #define VM_LEAF_BASE(result_type, header) \ TRACE_CALL(result_type, header) \ debug_only(NoHandleMark __hm;) \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, \ + Thread::current())); \ os::verify_stack_alignment(); \ /* begin of body */ @@ -440,6 +444,7 @@ #define IRT_ENTRY(result_type, header) \ result_type header { \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromJava __tiv(thread); \ VM_ENTRY_BASE(result_type, header, thread) \ debug_only(VMEntryWrapper __vew;) @@ -453,6 +458,7 @@ #define IRT_ENTRY_NO_ASYNC(result_type, header) \ result_type header { \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromJavaNoAsyncException __tiv(thread); \ VM_ENTRY_BASE(result_type, header, thread) \ debug_only(VMEntryWrapper __vew;) @@ -461,6 +467,7 @@ #define JRT_ENTRY(result_type, header) \ result_type header { \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromJava __tiv(thread); \ VM_ENTRY_BASE(result_type, header, thread) \ debug_only(VMEntryWrapper __vew;) @@ -474,6 +481,7 @@ #define JRT_ENTRY_NO_ASYNC(result_type, header) \ result_type header { \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromJavaNoAsyncException __tiv(thread); \ VM_ENTRY_BASE(result_type, header, thread) \ debug_only(VMEntryWrapper __vew;) @@ -482,6 +490,7 @@ // to get back into Java from the VM #define JRT_BLOCK_ENTRY(result_type, header) \ result_type header { \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ TRACE_CALL(result_type, header) \ HandleMarkCleaner __hm(thread); @@ -512,6 +521,7 @@ result_type JNICALL header { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ VM_ENTRY_BASE(result_type, header, thread) @@ -524,6 +534,7 @@ result_type JNICALL header { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ VM_QUICK_ENTRY_BASE(result_type, header, thread) @@ -548,6 +559,7 @@ extern "C" { \ result_type JNICALL header { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ VM_ENTRY_BASE(result_type, header, thread) @@ -557,6 +569,7 @@ extern "C" { \ result_type JNICALL header { \ JavaThread* thread = JavaThread::current(); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ VM_ENTRY_BASE(result_type, header, thread) @@ -566,6 +579,7 @@ extern "C" { \ result_type JNICALL header { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ VM_QUICK_ENTRY_BASE(result_type, header, thread)
diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index ff297fc..84123b2 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp
@@ -380,6 +380,10 @@ MemTracker::final_report(tty); } + if (PrintMetaspaceStatisticsAtExit) { + MetaspaceUtils::print_basic_report(tty, 0); + } + ThreadsSMRSupport::log_statistics(); } @@ -423,6 +427,10 @@ MemTracker::final_report(tty); } + if (PrintMetaspaceStatisticsAtExit) { + MetaspaceUtils::print_basic_report(tty, 0); + } + if (LogTouchedMethods && PrintTouchedMethodsAtExit) { Method::print_touched_methods(tty); }
diff --git a/src/hotspot/share/runtime/java.hpp b/src/hotspot/share/runtime/java.hpp index 6c809a1..a947ad5 100644 --- a/src/hotspot/share/runtime/java.hpp +++ b/src/hotspot/share/runtime/java.hpp
@@ -90,6 +90,19 @@ _thread_park_blocker(false), _post_vm_init_hook_enabled(false) {} + /** + * Letting MSVC generate the copy constructor results in incorrect ARM64 codegen + * on argument passing, triggering an assert failure in version_less_than() + * in src/hotspot/share/runtime/arguments.cpp. This trivial hand-written + * copy constructor works around the issue. + * https://developercommunity.visualstudio.com/t/arm64-incorrect-code-gen-when-compiler-decides-to/1541140 + */ + JDK_Version(const JDK_Version &v) : + _major(v._major), _minor(v._minor), _security(v._security), _patch(v._patch), + _build(v._build), _thread_park_blocker(v._thread_park_blocker), + _post_vm_init_hook_enabled(v._post_vm_init_hook_enabled) + {} + JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t security = 0, uint8_t patch = 0, uint8_t build = 0, bool thread_park_blocker = false, bool post_vm_init_hook_enabled = false) :
diff --git a/src/hotspot/share/runtime/javaCalls.cpp b/src/hotspot/share/runtime/javaCalls.cpp index 7709362..902264c 100644 --- a/src/hotspot/share/runtime/javaCalls.cpp +++ b/src/hotspot/share/runtime/javaCalls.cpp
@@ -1,5 +1,6 @@ /* * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -79,7 +80,6 @@ } } - // Make sure to set the oop's after the thread transition - since we can block there. No one is GC'ing // the JavaCallWrapper before the entry frame is on the stack. _callee_method = callee_method(); @@ -113,12 +113,16 @@ if (_anchor.last_Java_sp() == NULL) { _thread->record_base_of_stack_pointer(); } + + MACOS_AARCH64_ONLY(_thread->enable_wx(WXExec)); } JavaCallWrapper::~JavaCallWrapper() { assert(_thread == JavaThread::current(), "must still be the same thread"); + MACOS_AARCH64_ONLY(_thread->enable_wx(WXWrite)); + // restore previous handle block & Java frame linkage JNIHandleBlock *_old_handles = _thread->active_handles(); _thread->set_active_handles(_handles);
diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp index f069d41..a9690c2 100644 --- a/src/hotspot/share/runtime/objectMonitor.cpp +++ b/src/hotspot/share/runtime/objectMonitor.cpp
@@ -38,9 +38,9 @@ #include "runtime/objectMonitor.inline.hpp" #include "runtime/orderAccess.hpp" #include "runtime/osThread.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/safepointMechanism.inline.hpp" #include "runtime/sharedRuntime.hpp" -#include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" #include "services/threadService.hpp" #include "utilities/dtrace.hpp"
diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 013a9a8..389a1e9 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp
@@ -53,8 +53,8 @@ #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.inline.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/sharedRuntime.hpp" -#include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadSMR.hpp" #include "runtime/vm_version.hpp" @@ -1013,8 +1013,14 @@ struct tm tz; if (localtime_pd(&tloc, &tz) != NULL) { - ::strftime(buf, buflen, "%Z", &tz); - st->print("Time: %s %s", timestring, buf); + wchar_t w_buf[80]; + size_t n = ::wcsftime(w_buf, 80, L"%Z", &tz); + if (n > 0) { + ::wcstombs(buf, w_buf, buflen); + st->print("Time: %s %s", timestring, buf); + } else { + st->print("Time: %s", timestring); + } } else { st->print("Time: %s", timestring); } @@ -1737,7 +1743,8 @@ return os::pd_create_stack_guard_pages(addr, bytes); } -char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint, int file_desc) { +MACOS_ONLY(char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint, int file_desc, bool executable)) +NOT_MACOS(char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint, int file_desc)) { char* result = NULL; if (file_desc != -1) { @@ -1748,7 +1755,8 @@ MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC); } } else { - result = pd_reserve_memory(bytes, addr, alignment_hint); + result = MACOS_ONLY(pd_reserve_memory(bytes, addr, alignment_hint, executable)) + NOT_MACOS(pd_reserve_memory(bytes, addr, alignment_hint)); if (result != NULL) { MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); } @@ -1818,16 +1826,19 @@ MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC); } -bool os::uncommit_memory(char* addr, size_t bytes) { +MACOS_ONLY(bool os::uncommit_memory(char* addr, size_t bytes, bool executable)) +NOT_MACOS(bool os::uncommit_memory(char* addr, size_t bytes)) { bool res; if (MemTracker::tracking_level() > NMT_minimal) { Tracker tkr(Tracker::uncommit); - res = pd_uncommit_memory(addr, bytes); + res = MACOS_ONLY(pd_uncommit_memory(addr, bytes, executable)) + NOT_MACOS(pd_uncommit_memory(addr, bytes)); if (res) { tkr.record((address)addr, bytes); } } else { - res = pd_uncommit_memory(addr, bytes); + res = MACOS_ONLY(pd_uncommit_memory(addr, bytes, executable)) + NOT_MACOS(pd_uncommit_memory(addr, bytes)); } return res; }
diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 027085c..d52a3e1 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp
@@ -81,6 +81,11 @@ CriticalPriority = 11 // Critical thread priority }; +enum WXMode { + WXWrite, + WXExec +}; + // Executable parameter flag for os::commit_memory() and // os::commit_memory_or_exit(). const bool ExecMem = true; @@ -111,8 +116,12 @@ _page_sizes[1] = 0; // sentinel } - static char* pd_reserve_memory(size_t bytes, char* addr = 0, - size_t alignment_hint = 0); + + MACOS_ONLY(static char* pd_reserve_memory(size_t bytes, char* addr = 0, + size_t alignment_hint = 0, + bool executable = false);) + NOT_MACOS(static char* pd_reserve_memory(size_t bytes, char* addr = 0, + size_t alignment_hint = 0);) static char* pd_attempt_reserve_memory_at(size_t bytes, char* addr); static char* pd_attempt_reserve_memory_at(size_t bytes, char* addr, int file_desc); static void pd_split_reserved_memory(char *base, size_t size, @@ -127,7 +136,9 @@ static void pd_commit_memory_or_exit(char* addr, size_t size, size_t alignment_hint, bool executable, const char* mesg); - static bool pd_uncommit_memory(char* addr, size_t bytes); + MACOS_ONLY(static bool pd_uncommit_memory(char* addr, size_t bytes, + bool executable = false);) + NOT_MACOS(static bool pd_uncommit_memory(char* addr, size_t bytes);) static bool pd_release_memory(char* addr, size_t bytes); static char* pd_map_memory(int fd, const char* file_name, size_t file_offset, @@ -325,8 +336,11 @@ const size_t size); static int vm_allocation_granularity(); - static char* reserve_memory(size_t bytes, char* addr = 0, - size_t alignment_hint = 0, int file_desc = -1); + MACOS_ONLY(static char* reserve_memory(size_t bytes, char* addr = 0, + size_t alignment_hint = 0, int file_desc = -1, + bool executable = false);) + NOT_MACOS(static char* reserve_memory(size_t bytes, char* addr = 0, + size_t alignment_hint = 0, int file_desc = -1);) static char* reserve_memory(size_t bytes, char* addr, size_t alignment_hint, MEMFLAGS flags); static char* reserve_memory_aligned(size_t size, size_t alignment, int file_desc = -1); @@ -343,7 +357,8 @@ static void commit_memory_or_exit(char* addr, size_t size, size_t alignment_hint, bool executable, const char* mesg); - static bool uncommit_memory(char* addr, size_t bytes); + MACOS_ONLY(static bool uncommit_memory(char* addr, size_t bytes, bool executable = false);) + NOT_MACOS(static bool uncommit_memory(char* addr, size_t bytes);) static bool release_memory(char* addr, size_t bytes); // Touch memory pages that cover the memory range from start to end (exclusive) @@ -954,6 +969,11 @@ bool _done; }; +#if defined(__APPLE__) && defined(AARCH64) + // Enables write or execute access to writeable and executable pages. + static void current_thread_enable_wx(WXMode mode); +#endif // __APPLE__ && AARCH64 + #ifndef _WINDOWS // Suspend/resume support // Protocol:
diff --git a/src/hotspot/share/runtime/safefetch.inline.hpp b/src/hotspot/share/runtime/safefetch.inline.hpp new file mode 100644 index 0000000..ed40708 --- /dev/null +++ b/src/hotspot/share/runtime/safefetch.inline.hpp
@@ -0,0 +1,62 @@ +/* + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_RUNTIME_SAFEFETCH_INLINE_HPP +#define SHARE_RUNTIME_SAFEFETCH_INLINE_HPP + +#include "runtime/stubRoutines.hpp" +#include "runtime/threadWXSetters.inline.hpp" + +// Safefetch allows to load a value from a location that's not known +// to be valid. If the load causes a fault, the error value is returned. +inline int SafeFetch32(int* adr, int errValue) { + assert(StubRoutines::SafeFetch32_stub(), "stub not yet generated"); +#if defined(__APPLE__) && defined(AARCH64) + Thread* thread = Thread::current_or_null_safe(); + assert(thread != NULL, "required for W^X management"); + ThreadWXEnable wx(WXExec, thread); +#endif // __APPLE__ && AARCH64 + return StubRoutines::SafeFetch32_stub()(adr, errValue); +} + +inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) { + assert(StubRoutines::SafeFetchN_stub(), "stub not yet generated"); +#if defined(__APPLE__) && defined(AARCH64) + Thread* thread = Thread::current_or_null_safe(); + assert(thread != NULL, "required for W^X management"); + ThreadWXEnable wx(WXExec, thread); +#endif // __APPLE__ && AARCH64 + return StubRoutines::SafeFetchN_stub()(adr, errValue); +} + +// returns true if SafeFetch32 and SafeFetchN can be used safely (stubroutines are already generated) +inline bool CanUseSafeFetch32() { + return StubRoutines::SafeFetch32_stub() ? true : false; +} + +inline bool CanUseSafeFetchN() { + return StubRoutines::SafeFetchN_stub() ? true : false; +} + +#endif // SHARE_RUNTIME_SAFEFETCH_INLINE_HPP
diff --git a/src/hotspot/share/runtime/safepoint.cpp b/src/hotspot/share/runtime/safepoint.cpp index 4133a7a..fef77b8 100644 --- a/src/hotspot/share/runtime/safepoint.cpp +++ b/src/hotspot/share/runtime/safepoint.cpp
@@ -61,6 +61,7 @@ #include "runtime/synchronizer.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadSMR.hpp" +#include "runtime/threadWXSetters.inline.hpp" #include "runtime/timerTrace.hpp" #include "services/runtimeService.hpp" #include "utilities/events.hpp" @@ -954,6 +955,9 @@ assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization"); } + // Enable WXWrite: the function is called implicitly from java code. + MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); + if (PrintSafepointStatistics) { inc_page_trap_count(); }
diff --git a/src/hotspot/share/runtime/sharedRuntimeTrig.cpp b/src/hotspot/share/runtime/sharedRuntimeTrig.cpp index 6e3aa30..e086f794 100644 --- a/src/hotspot/share/runtime/sharedRuntimeTrig.cpp +++ b/src/hotspot/share/runtime/sharedRuntimeTrig.cpp
@@ -297,7 +297,12 @@ fw = 0.0; for (i=jz;i>=0;i--) fw += fq[i]; y[0] = (ih==0)? fw: -fw; + +PRAGMA_DIAG_PUSH +PRAGMA_MAYBE_UNINITIALIZED_IGNORED fw = fq[0]-fw; +PRAGMA_DIAG_POP + for (i=1;i<=jz;i++) fw += fq[i]; y[1] = (ih==0)? fw: -fw; break;
diff --git a/src/hotspot/share/runtime/signature.hpp b/src/hotspot/share/runtime/signature.hpp index 12ac4f9..aac8d87 100644 --- a/src/hotspot/share/runtime/signature.hpp +++ b/src/hotspot/share/runtime/signature.hpp
@@ -1,5 +1,6 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -282,16 +283,16 @@ int _prepended; // number of prepended JNI parameters (1 JNIEnv, plus 1 mirror if static) int _jni_offset; // the current parameter offset, starting with 0 - void do_bool () { pass_int(); _jni_offset++; _offset++; } - void do_char () { pass_int(); _jni_offset++; _offset++; } + void do_bool () { pass_byte(); _jni_offset++; _offset++; } + void do_char () { pass_short(); _jni_offset++; _offset++; } void do_float () { pass_float(); _jni_offset++; _offset++; } #ifdef _LP64 void do_double() { pass_double(); _jni_offset++; _offset += 2; } #else void do_double() { pass_double(); _jni_offset += 2; _offset += 2; } #endif - void do_byte () { pass_int(); _jni_offset++; _offset++; } - void do_short () { pass_int(); _jni_offset++; _offset++; } + void do_byte () { pass_byte(); _jni_offset++; _offset++; } + void do_short () { pass_short(); _jni_offset++; _offset++; } void do_int () { pass_int(); _jni_offset++; _offset++; } #ifdef _LP64 void do_long () { pass_long(); _jni_offset++; _offset += 2; } @@ -312,6 +313,8 @@ virtual void pass_long() = 0; virtual void pass_object() = 0; virtual void pass_float() = 0; + virtual void pass_byte() { pass_int(); }; + virtual void pass_short() { pass_int(); }; #ifdef _LP64 virtual void pass_double() = 0; #else
diff --git a/src/hotspot/share/runtime/stubRoutines.cpp b/src/hotspot/share/runtime/stubRoutines.cpp index 1ef9aa2..afefcf6 100644 --- a/src/hotspot/share/runtime/stubRoutines.cpp +++ b/src/hotspot/share/runtime/stubRoutines.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,8 @@ #include "oops/oop.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/timerTrace.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/sharedRuntime.hpp" -#include "runtime/stubRoutines.hpp" #include "utilities/align.hpp" #include "utilities/copy.hpp" #include "utilities/vmError.hpp" @@ -289,6 +289,8 @@ #ifdef ASSERT + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXExec)); + #define TEST_ARRAYCOPY(type) \ test_arraycopy_func( type##_arraycopy(), sizeof(type)); \ test_arraycopy_func( type##_disjoint_arraycopy(), sizeof(type)); \ @@ -369,6 +371,8 @@ test_safefetchN(); #endif + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXWrite)); + #endif }
diff --git a/src/hotspot/share/runtime/stubRoutines.hpp b/src/hotspot/share/runtime/stubRoutines.hpp index d864625..30f3804 100644 --- a/src/hotspot/share/runtime/stubRoutines.hpp +++ b/src/hotspot/share/runtime/stubRoutines.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -458,24 +458,4 @@ static void arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count); }; -// Safefetch allows to load a value from a location that's not known -// to be valid. If the load causes a fault, the error value is returned. -inline int SafeFetch32(int* adr, int errValue) { - assert(StubRoutines::SafeFetch32_stub(), "stub not yet generated"); - return StubRoutines::SafeFetch32_stub()(adr, errValue); -} -inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) { - assert(StubRoutines::SafeFetchN_stub(), "stub not yet generated"); - return StubRoutines::SafeFetchN_stub()(adr, errValue); -} - - -// returns true if SafeFetch32 and SafeFetchN can be used safely (stubroutines are already generated) -inline bool CanUseSafeFetch32() { - return StubRoutines::SafeFetch32_stub() ? true : false; -} - -inline bool CanUseSafeFetchN() { - return StubRoutines::SafeFetchN_stub() ? true : false; -} #endif // SHARE_VM_RUNTIME_STUBROUTINES_HPP
diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index 84cf372..e7b3272 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp
@@ -54,8 +54,8 @@ // The "core" versions of monitor enter and exit reside in this file. // The interpreter and compilers contain specialized transliterated -// variants of the enter-exit fast-path operations. See i486.ad fast_lock(), -// for instance. If you make changes here, make sure to modify the +// variants of the enter-exit fast-path operations. See c2_MacroAssembler_x86.cpp +// fast_lock(...) for instance. If you make changes here, make sure to modify the // interpreter, and both C1 and C2 fast-path inline locking code emission. // // -----------------------------------------------------------------------------
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index b6df811..159e877 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp
@@ -1,5 +1,6 @@ /* * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -97,6 +98,7 @@ #include "runtime/threadCritical.hpp" #include "runtime/threadSMR.inline.hpp" #include "runtime/threadStatisticalInfo.hpp" +#include "runtime/threadWXSetters.inline.hpp" #include "runtime/timer.hpp" #include "runtime/timerTrace.hpp" #include "runtime/vframe.inline.hpp" @@ -317,6 +319,8 @@ if (barrier_set != NULL) { barrier_set->on_thread_create(this); } + + MACOS_AARCH64_ONLY(DEBUG_ONLY(_wx_init = false)); } void Thread::initialize_thread_current() { @@ -370,6 +374,8 @@ register_thread_stack_with_NMT(); + MACOS_AARCH64_ONLY(this->init_wx()); + JFR_ONLY(Jfr::on_thread_start(this);) log_debug(os, thread)("Thread " UINTX_FORMAT " stack dimensions: " @@ -1999,6 +2005,10 @@ _timer_exit_phase1.stop(); _timer_exit_phase2.start(); } + + // Capture daemon status before the thread is marked as terminated. + bool daemon = is_daemon(threadObj()); + // Notify waiters on thread object. This has to be done after exit() is called // on the thread (if the thread is the last thread in a daemon ThreadGroup the // group should have the destroyed bit set before waiters are notified). @@ -2072,7 +2082,7 @@ _timer_exit_phase4.start(); } // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread - Threads::remove(this); + Threads::remove(this, daemon); if (log_is_enabled(Debug, os, thread, timer)) { _timer_exit_phase4.stop(); @@ -2090,7 +2100,7 @@ } } -void JavaThread::cleanup_failed_attach_current_thread() { +void JavaThread::cleanup_failed_attach_current_thread(bool is_daemon) { if (active_handles() != NULL) { JNIHandleBlock* block = active_handles(); set_active_handles(NULL); @@ -2112,7 +2122,7 @@ BarrierSet::barrier_set()->on_thread_detach(this); - Threads::remove(this); + Threads::remove(this, is_daemon); this->smr_delete(); } @@ -2534,6 +2544,9 @@ // Note only the native==>VM/Java barriers can call this function and when // thread state is _thread_in_native_trans. void JavaThread::check_special_condition_for_native_trans(JavaThread *thread) { + // Enable WXWrite: called directly from interpreter native wrapper. + MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); + check_safepoint_and_suspend_for_native_trans(thread); if (thread->has_async_exception()) { @@ -3678,6 +3691,8 @@ // Initialize the os module os::init(); + MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXWrite)); + // Record VM creation timing statistics TraceVmCreationTime create_vm_timer; create_vm_timer.start(); @@ -3781,6 +3796,7 @@ main_thread->record_stack_base_and_size(); main_thread->register_thread_stack_with_NMT(); main_thread->set_active_handles(JNIHandleBlock::allocate_block()); + MACOS_AARCH64_ONLY(main_thread->init_wx()); if (!main_thread->set_as_starting_thread()) { vm_shutdown_during_initialization( @@ -4440,7 +4456,7 @@ Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p)); } -void Threads::remove(JavaThread* p) { +void Threads::remove(JavaThread* p, bool is_daemon) { // Reclaim the objectmonitors from the omInUseList and omFreeList of the moribund thread. ObjectSynchronizer::omFlush(p); @@ -4469,11 +4485,8 @@ } _number_of_threads--; - oop threadObj = p->threadObj(); - bool daemon = true; - if (!is_daemon(threadObj)) { + if (!is_daemon) { _number_of_non_daemon_threads--; - daemon = false; // Only one thread left, do a notify on the Threads_lock so a thread waiting // on destroy_vm will wake up. @@ -4481,7 +4494,7 @@ Threads_lock->notify_all(); } } - ThreadService::remove_thread(p, daemon); + ThreadService::remove_thread(p, is_daemon); // Make sure that safepoint code disregard this thread. This is needed since // the thread might mess around with locks after this point. This can cause it @@ -4772,6 +4785,7 @@ CompileTask* task = ct->task(); if (task != NULL) { thread->print_name_on_error(st, buf, buflen); + st->print(" "); task->print(st, NULL, short_form, true); } }
diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index b7fcdfc..60e470e 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp
@@ -1,5 +1,6 @@ /* * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -752,6 +753,15 @@ static void muxAcquire(volatile intptr_t * Lock, const char * Name); static void muxAcquireW(volatile intptr_t * Lock, ParkEvent * ev); static void muxRelease(volatile intptr_t * Lock); + +#if defined(__APPLE__) && defined(AARCH64) + private: + DEBUG_ONLY(bool _wx_init); + WXMode _wx_state; + public: + void init_wx(); + WXMode enable_wx(WXMode new_state); +#endif // __APPLE__ && AARCH64 }; // Inline implementation of Thread::current() @@ -1179,7 +1189,7 @@ }; void exit(bool destroy_vm, ExitType exit_type = normal_exit); - void cleanup_failed_attach_current_thread(); + void cleanup_failed_attach_current_thread(bool is_daemon); // Testers virtual bool is_Java_thread() const { return true; } @@ -2172,7 +2182,7 @@ // force_daemon is a concession to JNI, where we may need to add a // thread to the thread list before allocating its thread object static void add(JavaThread* p, bool force_daemon = false); - static void remove(JavaThread* p); + static void remove(JavaThread* p, bool is_daemon); static void non_java_threads_do(ThreadClosure* tc); static void java_threads_do(ThreadClosure* tc); static void java_threads_and_vm_thread_do(ThreadClosure* tc);
diff --git a/src/hotspot/share/runtime/thread.inline.hpp b/src/hotspot/share/runtime/thread.inline.hpp index 5885d23..dee8534 100644 --- a/src/hotspot/share/runtime/thread.inline.hpp +++ b/src/hotspot/share/runtime/thread.inline.hpp
@@ -1,5 +1,6 @@ /* * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -93,6 +94,27 @@ OrderAccess::release_store_fence(&_threads_hazard_ptr, new_list); } +#if defined(__APPLE__) && defined(AARCH64) +inline void Thread::init_wx() { + assert(this == Thread::current(), "should only be called for current thread"); + assert(!_wx_init, "second init"); + _wx_state = WXWrite; + os::current_thread_enable_wx(_wx_state); + DEBUG_ONLY(_wx_init = true); +} + +inline WXMode Thread::enable_wx(WXMode new_state) { + assert(this == Thread::current(), "should only be called for current thread"); + assert(_wx_init, "should be inited"); + WXMode old = _wx_state; + if (_wx_state != new_state) { + _wx_state = new_state; + os::current_thread_enable_wx(new_state); + } + return old; +} +#endif // __APPLE__ && AARCH64 + inline void JavaThread::set_ext_suspended() { set_suspend_flag (_ext_suspended); }
diff --git a/src/hotspot/share/runtime/threadWXSetters.inline.hpp b/src/hotspot/share/runtime/threadWXSetters.inline.hpp new file mode 100644 index 0000000..02e2000 --- /dev/null +++ b/src/hotspot/share/runtime/threadWXSetters.inline.hpp
@@ -0,0 +1,49 @@ +/* + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_RUNTIME_THREADWXSETTERS_INLINE_HPP +#define SHARE_RUNTIME_THREADWXSETTERS_INLINE_HPP + +#include "runtime/thread.inline.hpp" + +#if defined(__APPLE__) && defined(AARCH64) +class ThreadWXEnable { + Thread* _thread; + WXMode _old_mode; +public: + ThreadWXEnable(WXMode new_mode, Thread* thread) : + _thread(thread), + _old_mode(_thread ? _thread->enable_wx(new_mode) : WXWrite) + { } + ~ThreadWXEnable() { + if (_thread) { + _thread->enable_wx(_old_mode); + } + } +}; +#endif // __APPLE__ && AARCH64 + +#endif // SHARE_RUNTIME_THREADWXSETTERS_INLINE_HPP +
diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 3056965..8553016 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp
@@ -277,10 +277,10 @@ nonstatic_field(MethodData, _data_size, int) \ nonstatic_field(MethodData, _data[0], intptr_t) \ nonstatic_field(MethodData, _parameters_type_data_di, int) \ - nonstatic_field(MethodData, _nof_decompiles, uint) \ - nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \ - nonstatic_field(MethodData, _nof_overflow_traps, uint) \ - nonstatic_field(MethodData, _trap_hist._array[0], u1) \ + nonstatic_field(MethodData, _compiler_counters._nof_decompiles, uint) \ + nonstatic_field(MethodData, _compiler_counters._nof_overflow_recompiles, uint) \ + nonstatic_field(MethodData, _compiler_counters._nof_overflow_traps, uint) \ + nonstatic_field(MethodData, _compiler_counters._trap_hist._array[0], u1) \ nonstatic_field(MethodData, _eflags, intx) \ nonstatic_field(MethodData, _arg_local, intx) \ nonstatic_field(MethodData, _arg_stack, intx) \ @@ -858,7 +858,6 @@ /* CI */ \ /************/ \ \ - nonstatic_field(ciEnv, _system_dictionary_modification_counter, int) \ nonstatic_field(ciEnv, _compiler_data, void*) \ nonstatic_field(ciEnv, _failure_reason, const char*) \ nonstatic_field(ciEnv, _factory, ciObjectFactory*) \ @@ -901,7 +900,7 @@ nonstatic_field(ciMethodData, _arg_stack, intx) \ nonstatic_field(ciMethodData, _arg_returned, intx) \ nonstatic_field(ciMethodData, _current_mileage, int) \ - nonstatic_field(ciMethodData, _orig, MethodData) \ + nonstatic_field(ciMethodData, _orig, MethodData::CompilerCounters) \ \ nonstatic_field(ciField, _holder, ciInstanceKlass*) \ nonstatic_field(ciField, _name, ciSymbol*) \ @@ -1310,6 +1309,8 @@ declare_type(MethodCounters, MetaspaceObj) \ declare_type(ConstMethod, MetaspaceObj) \ \ + declare_toplevel_type(MethodData::CompilerCounters) \ + \ declare_toplevel_type(narrowKlass) \ \ declare_toplevel_type(vtableEntry) \
diff --git a/src/hotspot/share/services/attachListener.cpp b/src/hotspot/share/services/attachListener.cpp index d4dd872..a08a440 100644 --- a/src/hotspot/share/services/attachListener.cpp +++ b/src/hotspot/share/services/attachListener.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -246,9 +246,11 @@ // // Input arguments :- // arg0: "-live" or "-all" +// arg1: parallel thread number static jint heap_inspection(AttachOperation* op, outputStream* out) { bool live_objects_only = true; // default is true to retain the behavior before this change is made const char* arg0 = op->arg(0); + uint parallel_thread_num = MAX2<uint>(1, (uint)os::initial_active_processor_count() * 3 / 8); if (arg0 != NULL && (strlen(arg0) > 0)) { if (strcmp(arg0, "-all") != 0 && strcmp(arg0, "-live") != 0) { out->print_cr("Invalid argument to inspectheap operation: %s", arg0); @@ -256,7 +258,18 @@ } live_objects_only = strcmp(arg0, "-live") == 0; } - VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */); + + const char* num_str = op->arg(1); + if (num_str != NULL && num_str[0] != '\0') { + uintx num; + if (!Arguments::parse_uintx(num_str, &num, 0)) { + out->print_cr("Invalid parallel thread number: [%s]", num_str); + return JNI_ERR; + } + parallel_thread_num = num == 0 ? parallel_thread_num : (uint)num; + } + + VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */, parallel_thread_num); VMThread::execute(&heapop); return JNI_OK; }
diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index c4db81a..4437cf4 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp
@@ -507,19 +507,34 @@ _filename("filename","Name of the dump file", "STRING",true), _all("-all", "Dump all objects, including unreachable objects", "BOOLEAN", false, "false"), + _gzip("-gz", "If specified, the heap dump is written in gzipped format " + "using the given compression level. 1 (recommended) is the fastest, " + "9 the strongest compression.", "INT", false, "1"), _overwrite("-overwrite", "If specified, the dump file will be overwritten if it exists", "BOOLEAN", false, "false") { _dcmdparser.add_dcmd_option(&_all); _dcmdparser.add_dcmd_argument(&_filename); + _dcmdparser.add_dcmd_option(&_gzip); _dcmdparser.add_dcmd_option(&_overwrite); } void HeapDumpDCmd::execute(DCmdSource source, TRAPS) { + jlong level = -1; // -1 means no compression. + + if (_gzip.is_set()) { + level = _gzip.value(); + + if (level < 1 || level > 9) { + output()->print_cr("Compression level out of range (1-9): " JLONG_FORMAT, level); + return; + } + } + // Request a full GC before heap dump if _all is false // This helps reduces the amount of unreachable objects in the dump // and makes it easier to browse. HeapDumper dumper(!_all.value() /* request GC if _all is false*/); - dumper.dump(_filename.value(), output(), _overwrite.value()); + dumper.dump(_filename.value(), output(), (int) level, _overwrite.value()); } int HeapDumpDCmd::num_arguments() {
diff --git a/src/hotspot/share/services/diagnosticCommand.hpp b/src/hotspot/share/services/diagnosticCommand.hpp index dc139b3..43ccefa 100644 --- a/src/hotspot/share/services/diagnosticCommand.hpp +++ b/src/hotspot/share/services/diagnosticCommand.hpp
@@ -331,6 +331,7 @@ protected: DCmdArgument<char*> _filename; DCmdArgument<bool> _all; + DCmdArgument<jlong> _gzip; DCmdArgument<bool> _overwrite; public: HeapDumpDCmd(outputStream* output, bool heap);
diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index 2cd8467..c2b6699 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp
@@ -29,6 +29,7 @@ #include "classfile/vmSymbols.hpp" #include "gc/shared/gcLocker.hpp" #include "gc/shared/vmGCOperations.hpp" +#include "gc/shared/workgroup.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -48,6 +49,7 @@ #include "runtime/vmThread.hpp" #include "runtime/vmOperations.hpp" #include "services/heapDumper.hpp" +#include "services/heapDumperCompression.hpp" #include "services/threadService.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" @@ -373,19 +375,16 @@ INITIAL_CLASS_COUNT = 200 }; -// Supports I/O operations on a dump file +// Supports I/O operations for a dump class DumpWriter : public StackObj { private: enum { - io_buffer_max_size = 8*M, - io_buffer_min_size = 64*K, + io_buffer_max_size = 1*M, + io_buffer_max_waste = 10*K, dump_segment_header_size = 9 }; - int _fd; // file descriptor (-1 if dump file not open) - julong _bytes_written; // number of byte written to dump file - char* _buffer; // internal buffer size_t _size; size_t _pos; @@ -395,12 +394,8 @@ DEBUG_ONLY(size_t _sub_record_left;) // The bytes not written for the current sub-record. DEBUG_ONLY(bool _sub_record_ended;) // True if we have called the end_sub_record(). - char* _error; // error message when I/O fails + CompressionBackend _backend; // Does the actual writing. - void set_file_descriptor(int fd) { _fd = fd; } - int file_descriptor() const { return _fd; } - - bool is_open() const { return file_descriptor() >= 0; } void flush(); char* buffer() const { return _buffer; } @@ -408,25 +403,26 @@ size_t position() const { return _pos; } void set_position(size_t pos) { _pos = pos; } - void set_error(const char* error) { _error = (char*)os::strdup(error); } + // Can be called if we have enough room in the buffer. + void write_fast(void* s, size_t len); - // all I/O go through this function - void write_internal(void* s, size_t len); + // Returns true if we have enough room in the buffer for 'len' bytes. + bool can_write_fast(size_t len); public: - DumpWriter(const char* path, bool overwrite); + // Takes ownership of the writer and compressor. + DumpWriter(AbstractWriter* writer, AbstractCompressor* compressor); + ~DumpWriter(); - void close(); - // total number of bytes written to the disk - julong bytes_written() const { return _bytes_written; } + julong bytes_written() const { return (julong) _backend.get_written(); } - char* error() const { return _error; } + char const* error() const { return _backend.error(); } // writer functions void write_raw(void* s, size_t len); - void write_u1(u1 x) { write_raw((void*)&x, 1); } + void write_u1(u1 x); void write_u2(u2 x); void write_u4(u4 x); void write_u8(u8 x); @@ -441,70 +437,37 @@ void end_sub_record(); // Finishes the current dump segment if not already finished. void finish_dump_segment(); + + // Called by threads used for parallel writing. + void writer_loop() { _backend.thread_loop(false); } + // Called when finished to release the threads. + void deactivate() { flush(); _backend.deactivate(); } }; -DumpWriter::DumpWriter(const char* path, bool overwrite) : _fd(-1), _bytes_written(0), _pos(0), - _in_dump_segment(false), _error(NULL) { - // try to allocate an I/O buffer of io_buffer_size. If there isn't - // sufficient memory then reduce size until we can allocate something. - _size = io_buffer_max_size; - do { - _buffer = (char*)os::malloc(_size, mtInternal); - if (_buffer == NULL) { - _size = _size >> 1; - } - } while (_buffer == NULL && _size >= io_buffer_min_size); - - if (_buffer == NULL) { - set_error("Could not allocate buffer memory for heap dump"); - } else { - _fd = os::create_binary_file(path, overwrite); // don't replace existing file - - // if the open failed we record the error - if (_fd < 0) { - set_error(os::strerror(errno)); - } - } +// Check for error after constructing the object and destroy it in case of an error. +DumpWriter::DumpWriter(AbstractWriter* writer, AbstractCompressor* compressor) : + _buffer(NULL), + _size(0), + _pos(0), + _in_dump_segment(false), + _backend(writer, compressor, io_buffer_max_size, io_buffer_max_waste) { + flush(); } DumpWriter::~DumpWriter() { - close(); - os::free(_buffer); - os::free(_error); + flush(); } -// closes dump file (if open) -void DumpWriter::close() { - // flush and close dump file - if (is_open()) { - flush(); - os::close(file_descriptor()); - set_file_descriptor(-1); - } +void DumpWriter::write_fast(void* s, size_t len) { + assert(!_in_dump_segment || (_sub_record_left >= len), "sub-record too large"); + assert(buffer_size() - position() >= len, "Must fit"); + debug_only(_sub_record_left -= len); + memcpy(buffer() + position(), s, len); + set_position(position() + len); } -// write directly to the file -void DumpWriter::write_internal(void* s, size_t len) { - if (is_open()) { - const char* pos = (char*)s; - ssize_t n = 0; - while (len > 0) { - uint tmp = (uint)MIN2(len, (size_t)INT_MAX); - n = os::write(file_descriptor(), pos, tmp); - - if (n < 0) { - // EINTR cannot happen here, os::write will take care of that - set_error(os::strerror(errno)); - os::close(file_descriptor()); - set_file_descriptor(-1); - return; - } - - _bytes_written += n; - pos += n; - len -= n; - } - } +bool DumpWriter::can_write_fast(size_t len) { + return buffer_size() - position() >= len; } // write raw bytes @@ -512,17 +475,17 @@ assert(!_in_dump_segment || (_sub_record_left >= len), "sub-record too large"); debug_only(_sub_record_left -= len); - // flush buffer to make room - if (len > buffer_size() - position()) { - assert(!_in_dump_segment || _is_huge_sub_record, "Cannot overflow in non-huge sub-record."); + // flush buffer to make room. + while (len > buffer_size() - position()) { + assert(!_in_dump_segment || _is_huge_sub_record, + "Cannot overflow in non-huge sub-record."); + + size_t to_write = buffer_size() - position(); + memcpy(buffer() + position(), s, to_write); + s = (void*) ((char*) s + to_write); + len -= to_write; + set_position(position() + to_write); flush(); - - // If larger than the buffer, just write it directly. - if (len > buffer_size()) { - write_internal(s, len); - - return; - } } memcpy(buffer() + position(), s, len); @@ -531,26 +494,33 @@ // flush any buffered bytes to the file void DumpWriter::flush() { - write_internal(buffer(), position()); - set_position(0); + _backend.get_new_buffer(&_buffer, &_pos, &_size); +} + +// Makes sure we inline the fast write into the write_u* functions. This is a big speedup. +#define WRITE_KNOWN_TYPE(p, len) do { if (can_write_fast((len))) write_fast((p), (len)); \ + else write_raw((p), (len)); } while (0) + +void DumpWriter::write_u1(u1 x) { + WRITE_KNOWN_TYPE((void*) &x, 1); } void DumpWriter::write_u2(u2 x) { u2 v; Bytes::put_Java_u2((address)&v, x); - write_raw((void*)&v, 2); + WRITE_KNOWN_TYPE((void*)&v, 2); } void DumpWriter::write_u4(u4 x) { u4 v; Bytes::put_Java_u4((address)&v, x); - write_raw((void*)&v, 4); + WRITE_KNOWN_TYPE((void*)&v, 4); } void DumpWriter::write_u8(u8 x) { u8 v; Bytes::put_Java_u8((address)&v, x); - write_raw((void*)&v, 8); + WRITE_KNOWN_TYPE((void*)&v, 8); } void DumpWriter::write_objectID(oop o) { @@ -593,7 +563,8 @@ // (in which case the segment length was already set to the correct value initially). if (!_is_huge_sub_record) { assert(position() > dump_segment_header_size, "Dump segment should have some content"); - Bytes::put_Java_u4((address) (buffer() + 5), (u4) (position() - dump_segment_header_size)); + Bytes::put_Java_u4((address) (buffer() + 5), + (u4) (position() - dump_segment_header_size)); } flush(); @@ -605,9 +576,10 @@ if (!_in_dump_segment) { if (position() > 0) { flush(); - assert(position() == 0, "Must be at the start"); } + assert(position() == 0, "Must be at the start"); + write_u1(HPROF_HEAP_DUMP_SEGMENT); write_u4(0); // timestamp // Will be fixed up later if we add more sub-records. If this is a huge sub-record, @@ -1502,7 +1474,7 @@ } // The VM operation that performs the heap dump -class VM_HeapDumper : public VM_GC_Operation { +class VM_HeapDumper : public VM_GC_Operation, public AbstractGangTask { private: static VM_HeapDumper* _global_dumper; static DumpWriter* _global_writer; @@ -1557,7 +1529,8 @@ VM_GC_Operation(0 /* total collections, dummy, ignored */, GCCause::_heap_dump /* GC Cause */, 0 /* total full collections, dummy, ignored */, - gc_before_heap_dump) { + gc_before_heap_dump), + AbstractGangTask("dump heap") { _local_writer = writer; _gc_before_heap_dump = gc_before_heap_dump; _klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true); @@ -1588,8 +1561,10 @@ VMOp_Type type() const { return VMOp_HeapDumper; } void doit(); + void work(uint worker_id); }; + VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL; DumpWriter* VM_HeapDumper::_global_writer = NULL; @@ -1818,8 +1793,26 @@ set_global_dumper(); set_global_writer(); + WorkGang* gang = ch->get_safepoint_workers(); + + if (gang == NULL) { + work(0); + } else { + gang->run_task(this, gang->active_workers(), true); + } + + // Now we clear the global variables, so that a future dumper can run. + clear_global_dumper(); + clear_global_writer(); +} + +void VM_HeapDumper::work(uint worker_id) { + if (!Thread::current()->is_VM_thread()) { + writer()->writer_loop(); + return; + } + // Write the file header - we always use 1.0.2 - size_t used = ch->used(); const char* header = "JAVA PROFILE 1.0.2"; // header is few bytes long - no chance to overflow int @@ -1875,9 +1868,8 @@ // Writes the HPROF_HEAP_DUMP_END record. DumperSupport::end_of_dump(writer()); - // Now we clear the global variables, so that a future dumper might run. - clear_global_dumper(); - clear_global_writer(); + // We are done with writing. Release the worker threads. + writer()->deactivate(); } void VM_HeapDumper::dump_stack_traces() { @@ -1893,6 +1885,7 @@ oop threadObj = thread->threadObj(); if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { // dump thread stack trace + ResourceMark rm; ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false); stack_trace->dump_stack_at_safepoint(-1); _stack_traces[_num_threads++] = stack_trace; @@ -1935,7 +1928,7 @@ } // dump the heap to given path. -int HeapDumper::dump(const char* path, outputStream* out, bool overwrite) { +int HeapDumper::dump(const char* path, outputStream* out, int compression, bool overwrite) { assert(path != NULL && strlen(path) > 0, "path missing"); // print message in interactive case @@ -1944,8 +1937,19 @@ timer()->start(); } - // create the dump writer. If the file can be opened then bail - DumpWriter writer(path, overwrite); + AbstractCompressor* compressor = NULL; + + if (compression > 0) { + compressor = new (std::nothrow) GZipCompressor(compression); + + if (compressor == NULL) { + set_error("Could not allocate gzip compressor"); + return -1; + } + } + + DumpWriter writer(new (std::nothrow) FileWriter(path, overwrite), compressor); + if (writer.error() != NULL) { set_error(writer.error()); if (out != NULL) { @@ -1964,8 +1968,7 @@ VMThread::execute(&dumper); } - // close dump file and record any error that the writer may have encountered - writer.close(); + // record any error that the writer may have encountered set_error(writer.error()); // print message in interactive case @@ -2003,7 +2006,7 @@ } // set the error string -void HeapDumper::set_error(char* error) { +void HeapDumper::set_error(char const* error) { if (_error != NULL) { os::free(_error); }
diff --git a/src/hotspot/share/services/heapDumper.hpp b/src/hotspot/share/services/heapDumper.hpp index 36e86c7..6d7b114 100644 --- a/src/hotspot/share/services/heapDumper.hpp +++ b/src/hotspot/share/services/heapDumper.hpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ // string representation of error char* error() const { return _error; } - void set_error(char* error); + void set_error(char const* error); // internal timer. elapsedTimer* timer() { return &_t; } @@ -69,8 +69,8 @@ ~HeapDumper(); // dumps the heap to the specified file, returns 0 if success. - // additional info is written to out if not NULL. - int dump(const char* path, outputStream* out = NULL, bool overwrite = false); + // compression >= 0 creates a gzipped file with the given compression level. + int dump(const char* path, outputStream* out = NULL, int compression = -1, bool overwrite = false); // returns error message (resource allocated), or NULL if no error char* error_as_C_string() const;
diff --git a/src/hotspot/share/services/heapDumperCompression.cpp b/src/hotspot/share/services/heapDumperCompression.cpp new file mode 100644 index 0000000..96cbf7e --- /dev/null +++ b/src/hotspot/share/services/heapDumperCompression.cpp
@@ -0,0 +1,473 @@ +/* + * Copyright (c) 2020 SAP SE. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "jvm.h" +#include "runtime/mutexLocker.hpp" +#include "runtime/os.inline.hpp" +#include "runtime/thread.inline.hpp" +#include "services/heapDumperCompression.hpp" + + +char const* FileWriter::open_writer() { + assert(_fd < 0, "Must not already be open"); + + _fd = os::create_binary_file(_path, _overwrite); // don't replace existing file + + if (_fd < 0) { + return os::strerror(errno); + } + + return NULL; +} + +FileWriter::~FileWriter() { + if (_fd >= 0) { + os::close(_fd); + _fd = -1; + } +} + +char const* FileWriter::write_buf(char* buf, ssize_t size) { + assert(_fd >= 0, "Must be open"); + assert(size > 0, "Must write at least one byte"); + + ssize_t n = (ssize_t) os::write(_fd, buf, (uint) size); + + if (n <= 0) { + return os::strerror(errno); + } + + return NULL; +} + + +typedef char const* (*GzipInitFunc)(size_t, size_t*, size_t*, int); +typedef size_t(*GzipCompressFunc)(char*, size_t, char*, size_t, char*, size_t, + int, char*, char const**); + +static GzipInitFunc gzip_init_func; +static GzipCompressFunc gzip_compress_func; + +void* GZipCompressor::load_gzip_func(char const* name) { + char path[JVM_MAXPATHLEN]; + char ebuf[1024]; + void* handle; + + if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), "zip")) { + handle = os::dll_load(path, ebuf, sizeof ebuf); + + if (handle != NULL) { + return os::dll_lookup(handle, name); + } + } + + return NULL; +} + +char const* GZipCompressor::init(size_t block_size, size_t* needed_out_size, + size_t* needed_tmp_size) { + _block_size = block_size; + _is_first = true; + + if (gzip_compress_func == NULL) { + gzip_compress_func = (GzipCompressFunc) load_gzip_func("ZIP_GZip_Fully"); + + if (gzip_compress_func == NULL) { + return "Cannot get ZIP_GZip_Fully function"; + } + } + + if (gzip_init_func == NULL) { + gzip_init_func = (GzipInitFunc) load_gzip_func("ZIP_GZip_InitParams"); + + if (gzip_init_func == NULL) { + return "Cannot get ZIP_GZip_InitParams function"; + } + } + + char const* result = gzip_init_func(block_size, needed_out_size, + needed_tmp_size, _level); + *needed_out_size += 1024; // Add extra space for the comment in the first chunk. + + return result; +} + +char const* GZipCompressor::compress(char* in, size_t in_size, char* out, size_t out_size, + char* tmp, size_t tmp_size, size_t* compressed_size) { + char const* msg = NULL; + + if (_is_first) { + char buf[128]; + // Write the block size used as a comment in the first gzip chunk, so the + // code used to read it later can make a good choice of the buffer sizes it uses. + jio_snprintf(buf, sizeof(buf), "HPROF BLOCKSIZE=" SIZE_FORMAT, _block_size); + *compressed_size = gzip_compress_func(in, in_size, out, out_size, tmp, tmp_size, _level, + buf, &msg); + _is_first = false; + } else { + *compressed_size = gzip_compress_func(in, in_size, out, out_size, tmp, tmp_size, _level, + NULL, &msg); + } + + return msg; +} + +WorkList::WorkList() { + _head._next = &_head; + _head._prev = &_head; +} + +void WorkList::insert(WriteWork* before, WriteWork* work) { + work->_prev = before; + work->_next = before->_next; + before->_next = work; + work->_next->_prev = work; +} + +WriteWork* WorkList::remove(WriteWork* work) { + if (work != NULL) { + assert(work->_next != work, "Invalid next"); + assert(work->_prev != work, "Invalid prev"); + work->_prev->_next = work->_next;; + work->_next->_prev = work->_prev; + work->_next = NULL; + work->_prev = NULL; + } + + return work; +} + +void WorkList::add_by_id(WriteWork* work) { + if (is_empty()) { + add_first(work); + } else { + WriteWork* last_curr = &_head; + WriteWork* curr = _head._next; + + while (curr->_id < work->_id) { + last_curr = curr; + curr = curr->_next; + + if (curr == &_head) { + add_last(work); + return; + } + } + + insert(last_curr, work); + } +} + + + +CompressionBackend::CompressionBackend(AbstractWriter* writer, + AbstractCompressor* compressor, size_t block_size, size_t max_waste) : + _active(false), + _err(NULL), + _nr_of_threads(0), + _works_created(0), + _work_creation_failed(false), + _id_to_write(0), + _next_id(0), + _in_size(block_size), + _max_waste(max_waste), + _out_size(0), + _tmp_size(0), + _written(0), + _writer(writer), + _compressor(compressor), + _lock(new (std::nothrow) PaddedMonitor(Mutex::leaf, "HProf Compression Backend", + true, Mutex::_safepoint_check_never)) { + if (_writer == NULL) { + set_error("Could not allocate writer"); + } else if (_lock == NULL) { + set_error("Could not allocate lock"); + } else { + set_error(_writer->open_writer()); + } + + if (_compressor != NULL) { + set_error(_compressor->init(_in_size, &_out_size, &_tmp_size)); + } + + _current = allocate_work(_in_size, _out_size, _tmp_size); + + if (_current == NULL) { + set_error("Could not allocate memory for buffer"); + } + + _active = (_err == NULL); +} + +CompressionBackend::~CompressionBackend() { + assert(!_active, "Must not be active by now"); + assert(_nr_of_threads == 0, "Must have no active threads"); + assert(_to_compress.is_empty() && _finished.is_empty(), "Still work to do"); + + free_work_list(&_unused); + free_work(_current); + assert(_works_created == 0, "All work must have been freed"); + + delete _compressor; + delete _writer; + delete _lock; +} + +void CompressionBackend::deactivate() { + assert(_active, "Must be active"); + + MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); + + // Make sure we write the last partially filled buffer. + if ((_current != NULL) && (_current->_in_used > 0)) { + _current->_id = _next_id++; + _to_compress.add_last(_current); + _current = NULL; + ml.notify_all(); + } + + // Wait for the threads to drain the compression work list. + while (!_to_compress.is_empty()) { + // If we have no threads, compress the current one itself. + if (_nr_of_threads == 0) { + MutexUnlockerEx mu(_lock, Mutex::_no_safepoint_check_flag); + thread_loop(true); + } else { + ml.wait(Mutex::_no_safepoint_check_flag); + } + } + + _active = false; + ml.notify_all(); +} + +void CompressionBackend::thread_loop(bool single_run) { + // Register if this is a worker thread. + if (!single_run) { + MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); + _nr_of_threads++; + } + + while (true) { + WriteWork* work = get_work(); + + if (work == NULL) { + assert(!single_run, "Should never happen for single thread"); + MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); + _nr_of_threads--; + assert(_nr_of_threads >= 0, "Too many threads finished"); + ml.notify_all(); + + return; + } else { + do_compress(work); + finish_work(work); + } + + if (single_run) { + return; + } + } +} + +void CompressionBackend::set_error(char const* new_error) { + if ((new_error != NULL) && (_err == NULL)) { + _err = new_error; + } +} + +WriteWork* CompressionBackend::allocate_work(size_t in_size, size_t out_size, + size_t tmp_size) { + WriteWork* result = (WriteWork*) os::malloc(sizeof(WriteWork), mtInternal); + + if (result == NULL) { + _work_creation_failed = true; + return NULL; + } + + _works_created++; + result->_in = (char*) os::malloc(in_size, mtInternal); + result->_in_max = in_size; + result->_in_used = 0; + result->_out = NULL; + result->_tmp = NULL; + + if (result->_in == NULL) { + goto fail; + } + + if (out_size > 0) { + result->_out = (char*) os::malloc(out_size, mtInternal); + result->_out_used = 0; + result->_out_max = out_size; + + if (result->_out == NULL) { + goto fail; + } + } + + if (tmp_size > 0) { + result->_tmp = (char*) os::malloc(tmp_size, mtInternal); + result->_tmp_max = tmp_size; + + if (result->_tmp == NULL) { + goto fail; + } + } + + return result; + +fail: + free_work(result); + _work_creation_failed = true; + return NULL; +} + +void CompressionBackend::free_work(WriteWork* work) { + if (work != NULL) { + os::free(work->_in); + os::free(work->_out); + os::free(work->_tmp); + os::free(work); + --_works_created; + } +} + +void CompressionBackend::free_work_list(WorkList* list) { + while (!list->is_empty()) { + free_work(list->remove_first()); + } +} + +WriteWork* CompressionBackend::get_work() { + MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); + + while (_active && _to_compress.is_empty()) { + ml.wait(Mutex::_no_safepoint_check_flag); + } + + return _to_compress.remove_first(); +} + +void CompressionBackend::get_new_buffer(char** buffer, size_t* used, size_t* max) { + if (_active) { + MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); + + if (*used > 0) { + _current->_in_used += *used; + + // Check if we do not waste more than _max_waste. If yes, write the buffer. + // Otherwise return the rest of the buffer as the new buffer. + if (_current->_in_max - _current->_in_used <= _max_waste) { + _current->_id = _next_id++; + _to_compress.add_last(_current); + _current = NULL; + ml.notify_all(); + } else { + *buffer = _current->_in + _current->_in_used; + *used = 0; + *max = _current->_in_max - _current->_in_used; + + return; + } + } + + while ((_current == NULL) && _unused.is_empty() && _active) { + // Add more work objects if needed. + if (!_work_creation_failed && (_works_created <= _nr_of_threads)) { + WriteWork* work = allocate_work(_in_size, _out_size, _tmp_size); + + if (work != NULL) { + _unused.add_first(work); + } + } else if (!_to_compress.is_empty() && (_nr_of_threads == 0)) { + // If we have no threads, compress the current one itself. + MutexUnlockerEx mu(_lock, Mutex::_no_safepoint_check_flag); + thread_loop(true); + } else { + ml.wait(Mutex::_no_safepoint_check_flag); + } + } + + if (_current == NULL) { + _current = _unused.remove_first(); + } + + if (_current != NULL) { + _current->_in_used = 0; + _current->_out_used = 0; + *buffer = _current->_in; + *used = 0; + *max = _current->_in_max; + + return; + } + } + + *buffer = NULL; + *used = 0; + *max = 0; + + return; +} + +void CompressionBackend::do_compress(WriteWork* work) { + if (_compressor != NULL) { + char const* msg = _compressor->compress(work->_in, work->_in_used, work->_out, + work->_out_max, + work->_tmp, _tmp_size, &work->_out_used); + + if (msg != NULL) { + MutexLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); + set_error(msg); + } + } +} + +void CompressionBackend::finish_work(WriteWork* work) { + MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); + + _finished.add_by_id(work); + + // Write all finished works as far as we can. + while (!_finished.is_empty() && (_finished.first()->_id == _id_to_write)) { + WriteWork* to_write = _finished.remove_first(); + size_t size = _compressor == NULL ? to_write->_in_used : to_write->_out_used; + char* p = _compressor == NULL ? to_write->_in : to_write->_out; + char const* msg = NULL; + + if (_err == NULL) { + _written += size; + MutexUnlockerEx mu(_lock, Mutex::_no_safepoint_check_flag); + msg = _writer->write_buf(p, (ssize_t) size); + } + + set_error(msg); + _unused.add_first(to_write); + _id_to_write++; + } + + ml.notify_all(); +}
diff --git a/src/hotspot/share/services/heapDumperCompression.hpp b/src/hotspot/share/services/heapDumperCompression.hpp new file mode 100644 index 0000000..2fd6f38 --- /dev/null +++ b/src/hotspot/share/services/heapDumperCompression.hpp
@@ -0,0 +1,233 @@ +/* + * Copyright (c) 2020 SAP SE. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_SERVICES_HEAPDUMPERCOMPRESSION_HPP +#define SHARE_SERVICES_HEAPDUMPERCOMPRESSION_HPP + +#include "memory/allocation.hpp" + + +// Interface for a compression implementation. +class AbstractCompressor : public CHeapObj<mtInternal> { +public: + virtual ~AbstractCompressor() { } + + // Initializes the compressor. Returns a static error message in case of an error. + // Otherwise initializes the needed out and tmp size for the given block size. + virtual char const* init(size_t block_size, size_t* needed_out_size, + size_t* needed_tmp_size) = 0; + + // Does the actual compression. Returns NULL on success and a static error + // message otherwise. Sets the 'compressed_size'. + virtual char const* compress(char* in, size_t in_size, char* out, size_t out_size, + char* tmp, size_t tmp_size, size_t* compressed_size) = 0; +}; + +// Interface for a writer implementation. +class AbstractWriter : public CHeapObj<mtInternal> { +public: + virtual ~AbstractWriter() { } + + // Opens the writer. Returns NULL on success and a static error message otherwise. + virtual char const* open_writer() = 0; + + // Does the write. Returns NULL on success and a static error message otherwise. + virtual char const* write_buf(char* buf, ssize_t size) = 0; +}; + + +// A writer for a file. +class FileWriter : public AbstractWriter { +private: + char const* _path; + bool _overwrite; + int _fd; + +public: + FileWriter(char const* path, bool overwrite) : _path(path), _overwrite(overwrite), _fd(-1) { } + + ~FileWriter(); + + // Opens the writer. Returns NULL on success and a static error message otherwise. + virtual char const* open_writer(); + + // Does the write. Returns NULL on success and a static error message otherwise. + virtual char const* write_buf(char* buf, ssize_t size); +}; + + +// A compressor using the gzip format. +class GZipCompressor : public AbstractCompressor { +private: + int _level; + size_t _block_size; + bool _is_first; + + void* load_gzip_func(char const* name); + +public: + GZipCompressor(int level) : _level(level), _block_size(0), _is_first(false) { + } + + virtual char const* init(size_t block_size, size_t* needed_out_size, + size_t* needed_tmp_size); + + virtual char const* compress(char* in, size_t in_size, char* out, size_t out_size, + char* tmp, size_t tmp_size, size_t* compressed_size); +}; + + +// The data needed to write a single buffer (and compress it optionally). +struct WriteWork { + // The id of the work. + int64_t _id; + + // The input buffer where the raw data is + char* _in; + size_t _in_used; + size_t _in_max; + + // The output buffer where the compressed data is. Is NULL when compression is disabled. + char* _out; + size_t _out_used; + size_t _out_max; + + // The temporary space needed for compression. Is NULL when compression is disabled. + char* _tmp; + size_t _tmp_max; + + // Used to link WriteWorks into lists. + WriteWork* _next; + WriteWork* _prev; +}; + +// A list for works. +class WorkList { +private: + WriteWork _head; + + void insert(WriteWork* before, WriteWork* work); + WriteWork* remove(WriteWork* work); + +public: + WorkList(); + + // Return true if the list is empty. + bool is_empty() { return _head._next == &_head; } + + // Adds to the beginning of the list. + void add_first(WriteWork* work) { insert(&_head, work); } + + // Adds to the end of the list. + void add_last(WriteWork* work) { insert(_head._prev, work); } + + // Adds so the ids are ordered. + void add_by_id(WriteWork* work); + + // Returns the first element. + WriteWork* first() { return is_empty() ? NULL : _head._next; } + + // Returns the last element. + WriteWork* last() { return is_empty() ? NULL : _head._prev; } + + // Removes the first element. Returns NULL if empty. + WriteWork* remove_first() { return remove(first()); } + + // Removes the last element. Returns NULL if empty. + WriteWork* remove_last() { return remove(first()); } +}; + + +class Monitor; + +// This class is used by the DumpWriter class. It supplies the DumpWriter with +// chunks of memory to write the heap dump data into. When the DumpWriter needs a +// new memory chunk, it calls get_new_buffer(), which commits the old chunk used +// and returns a new chunk. The old chunk is then added to a queue to be compressed +// and then written in the background. +class CompressionBackend : StackObj { + bool _active; + char const * _err; + + int _nr_of_threads; + int _works_created; + bool _work_creation_failed; + + int64_t _id_to_write; + int64_t _next_id; + + size_t _in_size; + size_t _max_waste; + size_t _out_size; + size_t _tmp_size; + + size_t _written; + + AbstractWriter* const _writer; + AbstractCompressor* const _compressor; + + Monitor* const _lock; + + WriteWork* _current; + WorkList _to_compress; + WorkList _unused; + WorkList _finished; + + void set_error(char const* new_error); + + WriteWork* allocate_work(size_t in_size, size_t out_size, size_t tmp_size); + void free_work(WriteWork* work); + void free_work_list(WorkList* list); + + WriteWork* get_work(); + void do_compress(WriteWork* work); + void finish_work(WriteWork* work); + +public: + // compressor can be NULL if no compression is used. + // Takes ownership of the writer and compressor. + // block_size is the buffer size of a WriteWork. + // max_waste is the maximum number of bytes to leave + // empty in the buffer when it is written. + CompressionBackend(AbstractWriter* writer, AbstractCompressor* compressor, + size_t block_size, size_t max_waste); + + ~CompressionBackend(); + + size_t get_written() const { return _written; } + + char const* error() const { return _err; } + + // Commits the old buffer (using the value in *used) and sets up a new one. + void get_new_buffer(char** buffer, size_t* used, size_t* max); + + // The entry point for a worker thread. If single_run is true, we only handle one entry. + void thread_loop(bool single_run); + + // Shuts down the backend, releasing all threads. + void deactivate(); +}; + + +#endif // SHARE_SERVICES_HEAPDUMPERCOMPRESSION_HPP
diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index 01375e3..f9b633a 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp
@@ -1990,7 +1990,7 @@ JVM_END JVM_ENTRY(void, jmm_GetDiagnosticCommandArgumentsInfo(JNIEnv *env, - jstring command, dcmdArgInfo* infoArray)) + jstring command, dcmdArgInfo* infoArray, jint count)) ResourceMark rm(THREAD); oop cmd = JNIHandles::resolve_external_guard(command); if (cmd == NULL) { @@ -2014,10 +2014,12 @@ } DCmdMark mark(dcmd); GrowableArray<DCmdArgumentInfo*>* array = dcmd->argument_info_array(); - if (array->length() == 0) { - return; + const int num_args = array->length(); + if (num_args != count) { + assert(false, "jmm_GetDiagnosticCommandArgumentsInfo count mismatch (%d vs %d)", count, num_args); + THROW_MSG(vmSymbols::java_lang_InternalError(), "jmm_GetDiagnosticCommandArgumentsInfo count mismatch"); } - for (int i = 0; i < array->length(); i++) { + for (int i = 0; i < num_args; i++) { infoArray[i].name = array->at(i)->name(); infoArray[i].description = array->at(i)->description(); infoArray[i].type = array->at(i)->type();
diff --git a/src/hotspot/share/services/memReporter.hpp b/src/hotspot/share/services/memReporter.hpp index 8642990..bc9938d 100644 --- a/src/hotspot/share/services/memReporter.hpp +++ b/src/hotspot/share/services/memReporter.hpp
@@ -39,14 +39,17 @@ */ class MemReporterBase : public StackObj { private: - size_t _scale; // report in this scale - outputStream* _output; // destination + const size_t _scale; // report in this scale + outputStream* const _output; // destination public: - MemReporterBase(outputStream* out = NULL, size_t scale = K) - : _scale(scale) { - _output = (out == NULL) ? tty : out; - } + + // Default scale to use if no scale given. + static const size_t default_scale = K; + + MemReporterBase(outputStream* out, size_t scale = default_scale) : + _scale(scale), _output(out) + {} protected: inline outputStream* output() const { @@ -74,7 +77,6 @@ size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const; size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const; - // Print summary total, malloc and virtual memory void print_total(size_t reserved, size_t committed) const; void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const; @@ -100,7 +102,7 @@ public: // This constructor is for normal reporting from a recent baseline. MemSummaryReporter(MemBaseline& baseline, outputStream* output, - size_t scale = K) : MemReporterBase(output, scale), + size_t scale = default_scale) : MemReporterBase(output, scale), _malloc_snapshot(baseline.malloc_memory_snapshot()), _vm_snapshot(baseline.virtual_memory_snapshot()), _instance_class_count(baseline.instance_class_count()), @@ -125,7 +127,7 @@ MemBaseline& _baseline; public: - MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = K) : + MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = default_scale) : MemSummaryReporter(baseline, output, scale), _baseline(baseline) { } @@ -162,7 +164,7 @@ public: MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, - outputStream* output, size_t scale = K) : MemReporterBase(output, scale), + outputStream* output, size_t scale = default_scale) : MemReporterBase(output, scale), _early_baseline(early_baseline), _current_baseline(current_baseline) { assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); @@ -201,7 +203,7 @@ class MemDetailDiffReporter : public MemSummaryDiffReporter { public: MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, - outputStream* output, size_t scale = K) : + outputStream* output, size_t scale = default_scale) : MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { } // Generate detail comparison report
diff --git a/src/hotspot/share/services/memTracker.cpp b/src/hotspot/share/services/memTracker.cpp index db09437..edf0e74 100644 --- a/src/hotspot/share/services/memTracker.cpp +++ b/src/hotspot/share/services/memTracker.cpp
@@ -183,7 +183,14 @@ return true; } +// Report during error reporting. +void MemTracker::error_report(outputStream* output) { + if (tracking_level() >= NMT_summary) { + report(true, output, MemReporterBase::default_scale); // just print summary for error case. + } +} +// Report when handling PrintNMTStatistics before VM shutdown. static volatile bool g_final_report_did_run = false; void MemTracker::final_report(outputStream* output) { // This function is called during both error reporting and normal VM exit. @@ -194,25 +201,25 @@ if (Atomic::cmpxchg(true, &g_final_report_did_run, false) == false) { NMT_TrackingLevel level = tracking_level(); if (level >= NMT_summary) { - report(level == NMT_summary, output); + report(level == NMT_summary, output, 1); } } } -void MemTracker::report(bool summary_only, outputStream* output) { +void MemTracker::report(bool summary_only, outputStream* output, size_t scale) { assert(output != NULL, "No output stream"); MemBaseline baseline; if (baseline.baseline(summary_only)) { if (summary_only) { - MemSummaryReporter rpt(baseline, output); + MemSummaryReporter rpt(baseline, output, scale); rpt.report(); } else { - MemDetailReporter rpt(baseline, output); + MemDetailReporter rpt(baseline, output, scale); rpt.report(); output->print("Metaspace:"); // The basic metaspace report avoids any locking and should be safe to // be called at any time. - MetaspaceUtils::print_basic_report(output, K); + MetaspaceUtils::print_basic_report(output, scale); } } }
diff --git a/src/hotspot/share/services/memTracker.hpp b/src/hotspot/share/services/memTracker.hpp index 4ab8655..e804da4 100644 --- a/src/hotspot/share/services/memTracker.hpp +++ b/src/hotspot/share/services/memTracker.hpp
@@ -279,13 +279,10 @@ // other tools. static inline Mutex* query_lock() { return _query_lock; } - // Make a final report or report for hs_err file. - static void error_report(outputStream* output) { - if (tracking_level() >= NMT_summary) { - report(true, output); // just print summary for error case. - } - } + // Report during error reporting. + static void error_report(outputStream* output); + // Report when handling PrintNMTStatistics before VM shutdown. static void final_report(outputStream* output); // Stored baseline @@ -301,7 +298,7 @@ private: static NMT_TrackingLevel init_tracking_level(); - static void report(bool summary_only, outputStream* output); + static void report(bool summary_only, outputStream* output, size_t scale); private: // Tracking level
diff --git a/src/hotspot/share/services/virtualMemoryTracker.cpp b/src/hotspot/share/services/virtualMemoryTracker.cpp index fd4daf3..6855056 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.cpp +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp
@@ -535,15 +535,21 @@ address committed_start; size_t committed_size; size_t stack_size = rgn->base() + rgn->size() - stack_bottom; + // Align the size to work with full pages (Alpine and AIX stack top is not page aligned) + size_t aligned_stack_size = align_up(stack_size, os::vm_page_size()); ReservedMemoryRegion* region = const_cast<ReservedMemoryRegion*>(rgn); NativeCallStack ncs; // empty stack - RegionIterator itr(stack_bottom, stack_size); + RegionIterator itr(stack_bottom, aligned_stack_size); DEBUG_ONLY(bool found_stack = false;) while (itr.next_committed(committed_start, committed_size)) { assert(committed_start != NULL, "Should not be null"); assert(committed_size > 0, "Should not be 0"); + // unaligned stack_size case: correct the region to fit the actual stack_size + if (stack_bottom + stack_size < committed_start + committed_size) { + committed_size = stack_bottom + stack_size - committed_start; + } region->add_committed_region(committed_start, committed_size, ncs); DEBUG_ONLY(found_stack = true;) }
diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 034438e..010e068 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp
@@ -66,6 +66,7 @@ JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method JVM_ACC_IS_SHARED_CLASS = 0x02000000, // True if klass is shared + JVM_ACC_IS_BEING_REDEFINED = 0x00100000, // True if the klass is being redefined. // Klass* and Method* flags JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00200000, @@ -155,6 +156,10 @@ void set_has_localvariable_table() { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } void clear_has_localvariable_table() { atomic_clear_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } + bool is_being_redefined() const { return (_flags & JVM_ACC_IS_BEING_REDEFINED) != 0; } + void set_is_being_redefined() { atomic_set_bits(JVM_ACC_IS_BEING_REDEFINED); } + void clear_is_being_redefined() { atomic_clear_bits(JVM_ACC_IS_BEING_REDEFINED); } + // field flags bool is_field_access_watched() const { return (_flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; } bool is_field_modification_watched() const
diff --git a/src/hotspot/share/utilities/compilerWarnings.hpp b/src/hotspot/share/utilities/compilerWarnings.hpp index c5c6ce8..4ca5940 100644 --- a/src/hotspot/share/utilities/compilerWarnings.hpp +++ b/src/hotspot/share/utilities/compilerWarnings.hpp
@@ -57,6 +57,7 @@ // https://gcc.gnu.org/gcc-8/changes.html #if !defined(__clang_major__) && (__GNUC__ >= 8) #define PRAGMA_STRINGOP_TRUNCATION_IGNORED PRAGMA_DISABLE_GCC_WARNING("-Wstringop-truncation") +#define PRAGMA_MAYBE_UNINITIALIZED_IGNORED PRAGMA_DISABLE_GCC_WARNING("-Wmaybe-uninitialized") #endif #if defined(__clang_major__) && \ @@ -84,6 +85,10 @@ #define PRAGMA_STRINGOP_TRUNCATION_IGNORED #endif +#ifndef PRAGMA_MAYBE_UNINITIALIZED_IGNORED +#define PRAGMA_MAYBE_UNINITIALIZED_IGNORED +#endif + #ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED #define PRAGMA_FORMAT_NONLITERAL_IGNORED #endif
diff --git a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp index add42ba..7742fb6 100644 --- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp
@@ -172,4 +172,8 @@ // Alignment #define ATTRIBUTE_ALIGNED(x) __declspec(align(x)) +#ifdef _M_ARM64 +#define USE_VECTORED_EXCEPTION_HANDLING +#endif + #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP
diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp index 2beffea..cf80253 100644 --- a/src/hotspot/share/utilities/macros.hpp +++ b/src/hotspot/share/utilities/macros.hpp
@@ -418,6 +418,14 @@ #define NOT_LINUX(code) code #endif +#ifdef __APPLE__ +#define MACOS_ONLY(code) code +#define NOT_MACOS(code) +#else +#define MACOS_ONLY(code) +#define NOT_MACOS(code) code +#endif + #ifdef AIX #define AIX_ONLY(code) code #define NOT_AIX(code) @@ -587,6 +595,8 @@ #define NOT_AARCH64(code) code #endif +#define MACOS_AARCH64_ONLY(x) MACOS_ONLY(AARCH64_ONLY(x)) + #ifdef VM_LITTLE_ENDIAN #define LITTLE_ENDIAN_ONLY(code) code #define BIG_ENDIAN_ONLY(code)
diff --git a/src/hotspot/share/utilities/nativeCallStack.cpp b/src/hotspot/share/utilities/nativeCallStack.cpp index bcecb2b..d9a2cbf 100644 --- a/src/hotspot/share/utilities/nativeCallStack.cpp +++ b/src/hotspot/share/utilities/nativeCallStack.cpp
@@ -38,7 +38,7 @@ // to call os::get_native_stack. A tail call is used if _NMT_NOINLINE_ is not defined // (which means this is not a slowdebug build), and we are on 64-bit (except Windows). // This is not necessarily a rule, but what has been obvserved to date. -#if (defined(_NMT_NOINLINE_) || defined(_WINDOWS) || !defined(_LP64)) +#if (defined(_NMT_NOINLINE_) || defined(_WINDOWS) || !defined(_LP64) || (defined(BSD) && defined (__aarch64__))) // Not a tail call. toSkip++; #if (defined(_NMT_NOINLINE_) && defined(BSD) && defined(_LP64))
diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 9ea1007..e2c9428 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp
@@ -37,6 +37,7 @@ #include "runtime/frame.inline.hpp" #include "runtime/init.hpp" #include "runtime/os.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadSMR.hpp" #include "runtime/vmThread.hpp" @@ -1340,13 +1341,14 @@ static bool log_done = false; // done saving error log static bool transmit_report_done = false; // done error reporting - if (SuppressFatalErrorMessage) { - os::abort(CreateCoredumpOnCrash); - } intptr_t mytid = os::current_thread_id(); if (first_error_tid == -1 && Atomic::cmpxchg(mytid, &first_error_tid, (intptr_t)-1) == -1) { + if (SuppressFatalErrorMessage) { + os::abort(CreateCoredumpOnCrash); + } + // Initialize time stamps to use the same base. out.time_stamp().update_to(1); log.time_stamp().update_to(1); @@ -1399,21 +1401,33 @@ // This is not the first error, see if it happened in a different thread // or in the same thread during error reporting. if (first_error_tid != mytid) { - char msgbuf[64]; - jio_snprintf(msgbuf, sizeof(msgbuf), - "[thread " INTX_FORMAT " also had an error]", - mytid); - out.print_raw_cr(msgbuf); + if (!SuppressFatalErrorMessage) { + char msgbuf[64]; + jio_snprintf(msgbuf, sizeof(msgbuf), + "[thread " INTX_FORMAT " also had an error]", + mytid); + out.print_raw_cr(msgbuf); + } - // error reporting is not MT-safe, block current thread + // Error reporting is not MT-safe, nor can we let the current thread + // proceed, so we block it. os::infinite_sleep(); } else { if (recursive_error_count++ > 30) { - out.print_raw_cr("[Too many errors, abort]"); + if (!SuppressFatalErrorMessage) { + out.print_raw_cr("[Too many errors, abort]"); + } os::die(); } + if (SuppressFatalErrorMessage) { + // If we already hit a secondary error during abort, then calling + // it again is likely to hit another one. But eventually, if we + // don't deadlock somewhere, we will call os::die() above. + os::abort(CreateCoredumpOnCrash); + } + outputStream* const st = log.is_open() ? &log : &out; st->cr(); @@ -1740,8 +1754,8 @@ // crash with sigsegv at non-null address. static void crash_with_segfault() { - char* const crash_addr = (char*) VMError::get_segfault_address(); - *crash_addr = 'X'; + int* crash_addr = reinterpret_cast<int*>(VMError::get_segfault_address()); + *crash_addr = 1; } // end: crash_with_segfault
diff --git a/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java b/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java index 0816146..1cba03e 100644 --- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java +++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java
@@ -162,12 +162,6 @@ return false; } - // user_{no}xattr options not present but we special-case ext3 as - // we know that extended attributes are not enabled by default. - if (entry().fstype().equals("ext3")) { - return false; - } - // user_xattr option not present but we special-case ext4 as we // know that extended attributes are enabled by default for // kernel version >= 2.6.39 @@ -184,7 +178,7 @@ return xattrEnabled; } - // not ext3/4 so probe mount point + // not ext4 so probe mount point if (!xattrChecked) { UnixPath dir = new UnixPath(file().getFileSystem(), entry().dir()); xattrEnabled = isExtendedAttributesEnabled(dir);
diff --git a/src/java.base/macosx/classes/apple/security/KeychainStore.java b/src/java.base/macosx/classes/apple/security/KeychainStore.java index d4409c4..74a531d 100644 --- a/src/java.base/macosx/classes/apple/security/KeychainStore.java +++ b/src/java.base/macosx/classes/apple/security/KeychainStore.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,6 +68,25 @@ Certificate cert; long certRef; // SecCertificateRef for this key + + // Each KeyStore.TrustedCertificateEntry have 2 attributes: + // 1. "trustSettings" -> trustSettings.toString() + // 2. "2.16.840.1.113894.746875.1.1" -> trustedKeyUsageValue + // The 1st one is mainly for debugging use. The 2nd one is similar + // to the attribute with the same key in a PKCS12KeyStore. + + // The SecTrustSettingsCopyTrustSettings() output for this certificate + // inside the KeyChain in its original array of CFDictionaryRef objects + // structure with values dumped as strings. For each trust, an extra + // entry "SecPolicyOid" is added whose value is the OID for this trust. + // The extra entries are used to construct trustedKeyUsageValue. + List<Map<String, String>> trustSettings; + + // One or more OIDs defined in http://oidref.com/1.2.840.113635.100.1. + // It can also be "2.5.29.37.0" for a self-signed certificate with + // an empty trust settings. This value is never empty. When there are + // multiple OID values, it takes the form of "[1.1.1, 1.1.2]". + String trustedKeyUsageValue; }; /** @@ -310,6 +329,66 @@ } } + private final class LocalAttr + implements KeyStore.Entry.Attribute { + + private String name; + private String value; + + public LocalAttr(String name, String value) { + this.name = name; + this.value = value; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + /** + * Calculates a hash code value for the object. + * Objects that are equal will also have the same hashcode. + */ + public int hashCode() { + return Objects.hash(name, value); + } + + public boolean equals(Object obj) { + if (this == obj) return true; + + if (!(obj instanceof LocalAttr)) { + return false; + } + + LocalAttr other = + (LocalAttr) obj; + return (Objects.equals(name, other.getName()) && + Objects.equals(value, other.getValue())); + } + + } + + @Override + public KeyStore.Entry engineGetEntry(String alias, KeyStore.ProtectionParameter protParam) + throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException { + if (engineIsCertificateEntry(alias)) { + Object entry = entries.get(alias.toLowerCase()); + if (entry instanceof TrustedCertEntry) { + TrustedCertEntry tEntry = (TrustedCertEntry)entry; + return new KeyStore.TrustedCertificateEntry( + tEntry.cert, Set.of( + new LocalAttr(KnownOIDs.ORACLE_TrustedKeyUsage.value(), tEntry.trustedKeyUsageValue), + new LocalAttr("trustSettings", tEntry.trustSettings.toString()))); + } + } + return super.engineGetEntry(alias, protParam); + } + /** * Returns the creation date of the entry identified by the given alias. * @@ -463,55 +542,12 @@ } /** - * Assigns the given certificate to the given alias. - * - * <p>If the given alias already exists in this keystore and identifies a - * <i>trusted certificate entry</i>, the certificate associated with it is - * overridden by the given certificate. - * - * @param alias the alias name - * @param cert the certificate - * - * @exception KeyStoreException if the given alias already exists and does - * not identify a <i>trusted certificate entry</i>, or this operation - * fails for some other reason. + * Adding trusted certificate entry is not supported. */ public void engineSetCertificateEntry(String alias, Certificate cert) - throws KeyStoreException - { - permissionCheck(); - - synchronized(entries) { - - Object entry = entries.get(alias.toLowerCase()); - if ((entry != null) && (entry instanceof KeyEntry)) { - throw new KeyStoreException - ("Cannot overwrite key entry with certificate"); - } - - // This will be slow, but necessary. Enumerate the values and then see if the cert matches the one in the trusted cert entry. - // Security framework doesn't support the same certificate twice in a keychain. - Collection<Object> allValues = entries.values(); - - for (Object value : allValues) { - if (value instanceof TrustedCertEntry) { - TrustedCertEntry tce = (TrustedCertEntry)value; - if (tce.cert.equals(cert)) { - throw new KeyStoreException("Keychain does not support mulitple copies of same certificate."); - } - } - } - - TrustedCertEntry trustedCertEntry = new TrustedCertEntry(); - trustedCertEntry.cert = cert; - trustedCertEntry.date = new Date(); - String lowerAlias = alias.toLowerCase(); - if (entries.get(lowerAlias) != null) { - deletedEntries.put(lowerAlias, entries.get(lowerAlias)); - } - entries.put(lowerAlias, trustedCertEntry); - addedEntries.put(lowerAlias, trustedCertEntry); - } + throws KeyStoreException { + throw new KeyStoreException("Cannot set trusted certificate entry." + + " Use the macOS \"security add-trusted-cert\" command instead."); } /** @@ -690,10 +726,7 @@ String alias = e.nextElement(); Object entry = addedEntries.get(alias); if (entry instanceof TrustedCertEntry) { - TrustedCertEntry tce = (TrustedCertEntry)entry; - Certificate certElem; - certElem = tce.cert; - tce.certRef = addCertificateToKeychain(alias, certElem); + // Cannot set trusted certificate entry } else { KeyEntry keyEntry = (KeyEntry)entry; @@ -788,9 +821,28 @@ private native void _scanKeychain(); /** - * Callback method from _scanKeychain. If a trusted certificate is found, this method will be called. + * Callback method from _scanKeychain. If a trusted certificate is found, + * this method will be called. + * + * inputTrust is a list of strings in groups. Each group contains key/value + * pairs for one trust setting and ends with a null. Thus the size of the + * whole list is (2 * s_1 + 1) + (2 * s_2 + 1) + ... + (2 * s_n + 1), + * where s_i is the size of mapping for the i'th trust setting, + * and n is the number of trust settings. Ex: + * + * key1 for trust1 + * value1 for trust1 + * .. + * null (end of trust1) + * key1 for trust2 + * value1 for trust2 + * ... + * null (end of trust2) + * ... + * null (end if trust_n) */ - private void createTrustedCertEntry(String alias, long keychainItemRef, long creationDate, byte[] derStream) { + private void createTrustedCertEntry(String alias, List<String> inputTrust, + long keychainItemRef, long creationDate, byte[] derStream) { TrustedCertEntry tce = new TrustedCertEntry(); try { @@ -801,6 +853,69 @@ tce.cert = cert; tce.certRef = keychainItemRef; + tce.trustSettings = new ArrayList<>(); + Map<String,String> tmpMap = new LinkedHashMap<>(); + for (int i = 0; i < inputTrust.size(); i++) { + if (inputTrust.get(i) == null) { + tce.trustSettings.add(tmpMap); + if (i < inputTrust.size() - 1) { + // Prepare an empty map for the next trust setting. + // Do not just clear(), must be a new object. + // Only create if not at end of list. + tmpMap = new LinkedHashMap<>(); + } + } else { + tmpMap.put(inputTrust.get(i), inputTrust.get(i+1)); + i++; + } + } + + boolean isSelfSigned; + try { + cert.verify(cert.getPublicKey()); + isSelfSigned = true; + } catch (Exception e) { + isSelfSigned = false; + } + if (tce.trustSettings.isEmpty()) { + if (isSelfSigned) { + // If a self-signed certificate has an empty trust settings, + // trust it for all purposes + tce.trustedKeyUsageValue = KnownOIDs.anyExtendedKeyUsage.value(); + } else { + // Otherwise, return immediately. The certificate is not + // added into entries. + return; + } + } else { + List<String> values = new ArrayList<>(); + for (var oneTrust : tce.trustSettings) { + var result = oneTrust.get("kSecTrustSettingsResult"); + // https://developer.apple.com/documentation/security/sectrustsettingsresult?language=objc + // 1 = kSecTrustSettingsResultTrustRoot, 2 = kSecTrustSettingsResultTrustAsRoot + // If missing, a default value of kSecTrustSettingsResultTrustRoot is assumed + // for self-signed certificates (see doc for SecTrustSettingsCopyTrustSettings). + // Note that the same SecPolicyOid can appear in multiple trust settings + // for different kSecTrustSettingsAllowedError and/or kSecTrustSettingsPolicyString. + if ((result == null && isSelfSigned) + || "1".equals(result) || "2".equals(result)) { + // When no kSecTrustSettingsPolicy, it means everything + String oid = oneTrust.getOrDefault("SecPolicyOid", + KnownOIDs.anyExtendedKeyUsage.value()); + if (!values.contains(oid)) { + values.add(oid); + } + } + } + if (values.isEmpty()) { + return; + } + if (values.size() == 1) { + tce.trustedKeyUsageValue = values.get(0); + } else { + tce.trustedKeyUsageValue = values.toString(); + } + } // Make a creation date. if (creationDate != 0) tce.date = new Date(creationDate);
diff --git a/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java b/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java index bcadaac..7050116 100644 --- a/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java +++ b/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,12 +26,38 @@ package java.lang; import java.io.File; +import sun.security.action.GetPropertyAction; class ClassLoaderHelper { + private static final boolean hasDynamicLoaderCache; + static { + String osVersion = GetPropertyAction.privilegedGetProperty("os.version"); + // dynamic linker cache support on os.version >= 11.x + int major = 11; + int i = osVersion.indexOf('.'); + try { + major = Integer.parseInt(i < 0 ? osVersion : osVersion.substring(0, i)); + } catch (NumberFormatException e) {} + hasDynamicLoaderCache = major >= 11; + } private ClassLoaderHelper() {} /** + * Returns true if loading a native library only if + * it's present on the file system. + * + * @implNote + * On macOS 11.x or later which supports dynamic linker cache, + * the dynamic library is not present on the filesystem. The + * library cannot determine if a dynamic library exists on a + * given path or not and so this method returns false. + */ + static boolean loadLibraryOnlyIfPresent() { + return !hasDynamicLoaderCache; + } + + /** * Indicates, whether PATH env variable is allowed to contain quoted entries. */ static final boolean allowsQuotedPathElements = false;
diff --git a/src/java.base/macosx/native/libjli/java_md_macosx.c b/src/java.base/macosx/native/libjli/java_md_macosx.c index e1451e3..b5a7017 100644 --- a/src/java.base/macosx/native/libjli/java_md_macosx.c +++ b/src/java.base/macosx/native/libjli/java_md_macosx.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -210,6 +210,8 @@ preferredJVM = "client"; #elif defined(__x86_64__) preferredJVM = "server"; +#elif defined(__aarch64__) + preferredJVM = "server"; #else #error "Unknown architecture - needs definition" #endif
diff --git a/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m b/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m index f427737..3f0c1de 100644 --- a/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m +++ b/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -368,6 +368,14 @@ } } +#define ADD(list, str) { \ + jobject localeObj = (*env)->NewStringUTF(env, [str UTF8String]); \ + (*env)->CallBooleanMethod(env, list, jm_listAdd, localeObj); \ + (*env)->DeleteLocalRef(env, localeObj); \ +} + +#define ADDNULL(list) (*env)->CallBooleanMethod(env, list, jm_listAdd, NULL) + static void addCertificatesToKeystore(JNIEnv *env, jobject keyStore) { // Search the user keychain list for all X509 certificates. @@ -379,8 +387,15 @@ jclass jc_KeychainStore = (*env)->FindClass(env, "apple/security/KeychainStore"); CHECK_NULL(jc_KeychainStore); jmethodID jm_createTrustedCertEntry = (*env)->GetMethodID( - env, jc_KeychainStore, "createTrustedCertEntry", "(Ljava/lang/String;JJ[B)V"); + env, jc_KeychainStore, "createTrustedCertEntry", "(Ljava/lang/String;Ljava/util/List;JJ[B)V"); CHECK_NULL(jm_createTrustedCertEntry); + jclass jc_arrayListClass = (*env)->FindClass(env, "java/util/ArrayList"); + CHECK_NULL(jc_arrayListClass); + jmethodID jm_arrayListCons = (*env)->GetMethodID(env, jc_arrayListClass, "<init>", "()V"); + CHECK_NULL(jm_arrayListCons); + jmethodID jm_listAdd = (*env)->GetMethodID(env, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z"); + CHECK_NULL(jm_listAdd); + do { searchResult = SecKeychainSearchCopyNext(keychainItemSearch, &theItem); @@ -401,12 +416,50 @@ goto errOut; } + // Only add certificates with trusted settings + CFArrayRef trustSettings; + if (SecTrustSettingsCopyTrustSettings(certRef, kSecTrustSettingsDomainUser, &trustSettings) + == errSecItemNotFound) { + continue; + } + + // See KeychainStore::createTrustedCertEntry for content of inputTrust + jobject inputTrust = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons); + CHECK_NULL(inputTrust); + + // Dump everything inside trustSettings into inputTrust + CFIndex count = CFArrayGetCount(trustSettings); + for (int i = 0; i < count; i++) { + CFDictionaryRef oneTrust = (CFDictionaryRef) CFArrayGetValueAtIndex(trustSettings, i); + CFIndex size = CFDictionaryGetCount(oneTrust); + const void * keys [size]; + const void * values [size]; + CFDictionaryGetKeysAndValues(oneTrust, keys, values); + for (int j = 0; j < size; j++) { + NSString* s = [NSString stringWithFormat:@"%@", keys[j]]; + ADD(inputTrust, s); + s = [NSString stringWithFormat:@"%@", values[j]]; + ADD(inputTrust, s); + } + SecPolicyRef certPolicy; + certPolicy = (SecPolicyRef)CFDictionaryGetValue(oneTrust, kSecTrustSettingsPolicy); + if (certPolicy != NULL) { + CFDictionaryRef policyDict = SecPolicyCopyProperties(certPolicy); + ADD(inputTrust, @"SecPolicyOid"); + NSString* s = [NSString stringWithFormat:@"%@", CFDictionaryGetValue(policyDict, @"SecPolicyOid")]; + ADD(inputTrust, s); + CFRelease(policyDict); + } + ADDNULL(inputTrust); + } + CFRelease(trustSettings); + // Find the creation date. jlong creationDate = getModDateFromItem(env, theItem); // Call back to the Java object to create Java objects corresponding to this security object. jlong nativeRef = ptr_to_jlong(certRef); - (*env)->CallVoidMethod(env, keyStore, jm_createTrustedCertEntry, alias, nativeRef, creationDate, certData); + (*env)->CallVoidMethod(env, keyStore, jm_createTrustedCertEntry, alias, inputTrust, nativeRef, creationDate, certData); JNU_CHECK_EXCEPTION(env); } } while (searchResult == noErr); @@ -522,8 +575,8 @@ /* * Class: apple_security_KeychainStore * Method: _addItemToKeychain - * Signature: (Ljava/lang/String;[B)I -*/ + * Signature: (Ljava/lang/String;Z[B[C)J + */ JNIEXPORT jlong JNICALL Java_apple_security_KeychainStore__1addItemToKeychain (JNIEnv *env, jobject this, jstring alias, jboolean isCertificate, jbyteArray rawDataObj, jcharArray passwordObj) {
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java index e0e1f85..6d7586d 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,7 +207,7 @@ */ @Override protected byte[] engineGetIV() { - return nonce.clone(); + return (nonce != null) ? nonce.clone() : null; } /** @@ -226,11 +226,16 @@ protected AlgorithmParameters engineGetParameters() { AlgorithmParameters params = null; if (mode == MODE_AEAD) { + // In a pre-initialized state or any state without a nonce value + // this call should cause a random nonce to be generated, but + // not attached to the object. + byte[] nonceData = (initialized || nonce != null) ? nonce : + createRandomNonce(null); try { // Place the 12-byte nonce into a DER-encoded OCTET_STRING params = AlgorithmParameters.getInstance("ChaCha20-Poly1305"); params.init((new DerValue( - DerValue.tag_OctetString, nonce).toByteArray())); + DerValue.tag_OctetString, nonceData).toByteArray())); } catch (NoSuchAlgorithmException | IOException exc) { throw new RuntimeException(exc); } @@ -504,7 +509,7 @@ * * @return a 12-byte array containing the random nonce. */ - private byte[] createRandomNonce(SecureRandom random) { + private static byte[] createRandomNonce(SecureRandom random) { byte[] newNonce = new byte[12]; SecureRandom rand = (random != null) ? random : new SecureRandom(); rand.nextBytes(newNonce);
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java index 5a819d2..ccfbb7b 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -549,7 +549,7 @@ * } * * ended by a keyed SHA1 hash (bytes only) of - * { password + whitener + preceding body } + * { password + extra data + preceding body } */ // password is mandatory when storing @@ -895,7 +895,7 @@ /** * To guard against tampering with the keystore, we append a keyed - * hash with a bit of whitener. + * hash with a bit of extra data. */ private MessageDigest getPreKeyedHash(char[] password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java index 408e445..e8a3399 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java
@@ -182,6 +182,10 @@ byte[] encodedParams = encrInfo.getAlgorithm().getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing PBE parameters"); + } + // parse the PBE parameters into the corresponding spec AlgorithmParameters pbeParams = AlgorithmParameters.getInstance("PBE");
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java index e180935..6e90f3f 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,8 +124,12 @@ if (!val.getOID().equals(OID_MGF1)) { throw new IOException("Only MGF1 mgf is supported"); } + byte[] encodedParams = val.getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing MGF1 parameters"); + } AlgorithmId params = AlgorithmId.parse( - new DerValue(val.getEncodedParams())); + new DerValue(encodedParams)); String mgfDigestName = params.getName(); if (mgfDigestName.equals("SHA-1")) { mgfSpec = MGF1ParameterSpec.SHA1; @@ -151,7 +155,12 @@ if (!val.getOID().equals(OID_PSpecified)) { throw new IOException("Wrong OID for pSpecified"); } - DerInputStream dis = new DerInputStream(val.getEncodedParams()); + byte[] encodedParams = val.getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing pSpecified label"); + } + + DerInputStream dis = new DerInputStream(encodedParams); p = dis.getOctetString(); if (dis.available() != 0) { throw new IOException("Extra data for pSpecified");
diff --git a/src/java.base/share/classes/java/io/File.java b/src/java.base/share/classes/java/io/File.java index f70c159..cdf15e0 100644 --- a/src/java.base/share/classes/java/io/File.java +++ b/src/java.base/share/classes/java/io/File.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,8 +175,9 @@ /** * Check if the file has an invalid path. Currently, the inspection of - * a file path is very limited, and it only covers Nul character check. - * Returning true means the path is definitely invalid/garbage. But + * a file path is very limited, and it only covers Nul character check + * unless further checking is explicitly enabled by a system property. + * Returning true means the path is definitely invalid/garbage, but * returning false does not guarantee that the path is valid. * * @return true if the file path is invalid. @@ -184,8 +185,7 @@ final boolean isInvalid() { PathStatus s = status; if (s == null) { - s = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED - : PathStatus.INVALID; + s = fs.isInvalid(this) ? PathStatus.INVALID : PathStatus.CHECKED; status = s; } return s == PathStatus.INVALID;
diff --git a/src/java.base/share/classes/java/io/FileSystem.java b/src/java.base/share/classes/java/io/FileSystem.java index dab7fa8..8e348b1 100644 --- a/src/java.base/share/classes/java/io/FileSystem.java +++ b/src/java.base/share/classes/java/io/FileSystem.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,6 +88,11 @@ public abstract boolean isAbsolute(File f); /** + * Tell whether the given abstract pathname is invalid. + */ + public abstract boolean isInvalid(File f); + + /** * Resolve the given abstract pathname into absolute form. Invoked by the * getAbsolutePath and getCanonicalPath methods in the File class. */
diff --git a/src/java.base/share/classes/java/io/ObjectInputFilter.java b/src/java.base/share/classes/java/io/ObjectInputFilter.java index a2d92d3..a042153 100644 --- a/src/java.base/share/classes/java/io/ObjectInputFilter.java +++ b/src/java.base/share/classes/java/io/ObjectInputFilter.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ * {@link Status#UNDECIDED UNDECIDED}. * Filters should be designed for the specific use case and expected types. * A filter designed for a particular use may be passed a class that is outside - * of the scope of the filter. If the purpose of the filter is to black-list classes + * of the scope of the filter. If the purpose of the filter is to reject classes * then it can reject a candidate class that matches and report UNDECIDED for others. * A filter may be called with class equals {@code null}, {@code arrayLength} equal -1, * the depth, number of references, and stream size and return a status
diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index b77beae..939b764 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java
@@ -1264,6 +1264,8 @@ * <li>each object reference previously deserialized from the stream * (class is {@code null}, arrayLength is -1), * <li>each regular class (class is not {@code null}, arrayLength is -1), + * <li>each interface class explicitly referenced in the stream + * (it is not called for interfaces implemented by classes in the stream), * <li>each interface of a dynamic proxy and the dynamic proxy class itself * (class is not {@code null}, arrayLength is -1), * <li>each array is filtered using the array type and length of the array @@ -2010,6 +2012,30 @@ totalObjectRefs++; depth++; desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); + + if (cl != null) { + // Check that serial filtering has been done on the local class descriptor's superclass, + // in case it does not appear in the stream. + + // Find the next super descriptor that has a local class descriptor. + // Descriptors for which there is no local class are ignored. + ObjectStreamClass superLocal = null; + for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) { + if ((superLocal = sDesc.getLocalDesc()) != null) { + break; + } + } + + // Scan local descriptor superclasses for a match with the local descriptor of the super found above. + // For each super descriptor before the match, invoke the serial filter on the class. + // The filter is invoked for each class that has not already been filtered + // but would be filtered if the instance had been serialized by this Java runtime. + for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc(); + lDesc != null && lDesc != superLocal; + lDesc = lDesc.getSuperDesc()) { + filterCheck(lDesc.forClass(), -1); + } + } } finally { depth--; } @@ -2502,6 +2528,13 @@ throw new InternalError(); } clear(); + // Check that an object follows the TC_EXCEPTION typecode + byte tc = bin.peekByte(); + if (tc != TC_OBJECT && + tc != TC_REFERENCE) { + throw new StreamCorruptedException( + String.format("invalid type code: %02X", tc)); + } return (IOException) readObject0(Object.class, false); }
diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index 82535d0..fa51f79 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -2406,6 +2406,8 @@ * @since 1.2 */ static class NativeLibrary { + private static final boolean loadLibraryOnlyIfPresent = ClassLoaderHelper.loadLibraryOnlyIfPresent(); + // the class from which the library is loaded, also indicates // the loader this native library belongs. final Class<?> fromClass; @@ -2420,7 +2422,8 @@ // the version of JNI environment the native library requires. int jniVersion; - native boolean load0(String name, boolean isBuiltin); + native boolean load0(String name, boolean isBuiltin, + boolean throwExceptionIfFail); native long findEntry(String name); @@ -2439,7 +2442,7 @@ throw new InternalError("Native library " + name + " has been loaded"); } - if (!load0(name, isBuiltin)) return false; + if (!load0(name, isBuiltin, loadLibraryOnlyIfPresent)) return false; // register the class loader for cleanup when unloaded // built class loaders are never unloaded @@ -2681,7 +2684,10 @@ new PrivilegedAction<>() { public String run() { try { - return file.exists() ? file.getCanonicalPath() : null; + if (NativeLibrary.loadLibraryOnlyIfPresent && !file.exists()) { + return null; + } + return file.getCanonicalPath(); } catch (IOException e) { return null; }
diff --git a/src/java.base/share/classes/java/lang/StringBuffer.java b/src/java.base/share/classes/java/lang/StringBuffer.java index e597a81..1104ee2 100644 --- a/src/java.base/share/classes/java/lang/StringBuffer.java +++ b/src/java.base/share/classes/java/lang/StringBuffer.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,12 @@ package java.lang; -import java.util.Arrays; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; +import java.io.Serializable; +import java.io.StreamCorruptedException; import jdk.internal.HotSpotIntrinsicCandidate; /** @@ -105,7 +110,7 @@ */ public final class StringBuffer extends AbstractStringBuilder - implements java.io.Serializable, Comparable<StringBuffer>, CharSequence + implements Serializable, Comparable<StringBuffer>, CharSequence { /** @@ -729,20 +734,20 @@ * A flag indicating whether the backing array is shared. * The value is ignored upon deserialization. */ - private static final java.io.ObjectStreamField[] serialPersistentFields = + private static final ObjectStreamField[] serialPersistentFields = { - new java.io.ObjectStreamField("value", char[].class), - new java.io.ObjectStreamField("count", Integer.TYPE), - new java.io.ObjectStreamField("shared", Boolean.TYPE), + new ObjectStreamField("value", char[].class), + new ObjectStreamField("count", Integer.TYPE), + new ObjectStreamField("shared", Boolean.TYPE), }; /** - * readObject is called to restore the state of the StringBuffer from - * a stream. + * The {@code writeObject} method is called to write the state of the + * {@code StringBuffer} to a stream. */ - private synchronized void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - java.io.ObjectOutputStream.PutField fields = s.putFields(); + private synchronized void writeObject(ObjectOutputStream s) + throws IOException { + ObjectOutputStream.PutField fields = s.putFields(); char[] val = new char[capacity()]; if (isLatin1()) { StringLatin1.getChars(value, 0, count, val, 0); @@ -756,15 +761,20 @@ } /** - * readObject is called to restore the state of the StringBuffer from - * a stream. + * The {@code readObject} method is called to restore the state of the + * {@code StringBuffer} from a stream. */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - java.io.ObjectInputStream.GetField fields = s.readFields(); + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + ObjectInputStream.GetField fields = s.readFields(); char[] val = (char[])fields.get("value", null); + int c = fields.get("count", 0); + if (c < 0 || c > val.length) { + throw new StreamCorruptedException("count value invalid"); + } initBytes(val, 0, val.length); - count = fields.get("count", 0); + count = c; + // ignore shared field } synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
diff --git a/src/java.base/share/classes/java/lang/StringBuilder.java b/src/java.base/share/classes/java/lang/StringBuilder.java index 40da208..857fc43 100644 --- a/src/java.base/share/classes/java/lang/StringBuilder.java +++ b/src/java.base/share/classes/java/lang/StringBuilder.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,10 @@ package java.lang; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.StreamCorruptedException; import jdk.internal.HotSpotIntrinsicCandidate; /** @@ -460,8 +464,7 @@ * characters currently stored in the string builder, in which * case extra characters are ignored. */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { + private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); s.writeInt(count); char[] val = new char[capacity()]; @@ -474,15 +477,19 @@ } /** - * readObject is called to restore the state of the StringBuffer from + * readObject is called to restore the state of the StringBuilder from * a stream. */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { s.defaultReadObject(); - count = s.readInt(); + int c = s.readInt(); char[] val = (char[]) s.readObject(); + if (c < 0 || c > val.length) { + throw new StreamCorruptedException("count value invalid"); + } initBytes(val, 0, val.length); + count = c; } }
diff --git a/src/java.base/share/classes/java/lang/StringCoding.java b/src/java.base/share/classes/java/lang/StringCoding.java index 569bd9c..a6f9476a 100644 --- a/src/java.base/share/classes/java/lang/StringCoding.java +++ b/src/java.base/share/classes/java/lang/StringCoding.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -921,14 +921,17 @@ int sp = 0; int sl = val.length >> 1; byte[] dst = new byte[sl * 3]; - char c; - while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') { + while (sp < sl) { // ascii fast loop; + char c = StringUTF16.getChar(val, sp); + if (c >= '\u0080') { + break; + } dst[dp++] = (byte)c; sp++; } while (sp < sl) { - c = StringUTF16.getChar(val, sp++); + char c = StringUTF16.getChar(val, sp++); if (c < 0x80) { dst[dp++] = (byte)c; } else if (c < 0x800) {
diff --git a/src/java.base/share/classes/java/math/BigInteger.java b/src/java.base/share/classes/java/math/BigInteger.java index d9bc615..8f57759 100644 --- a/src/java.base/share/classes/java/math/BigInteger.java +++ b/src/java.base/share/classes/java/math/BigInteger.java
@@ -1650,8 +1650,8 @@ // are only considering the magnitudes as non-negative. The // Toom-Cook multiplication algorithm determines the sign // at its end from the two signum values. - if (bitLength(mag, mag.length) + - bitLength(val.mag, val.mag.length) > + if ((long)bitLength(mag, mag.length) + + (long)bitLength(val.mag, val.mag.length) > 32L*MAX_MAG_LENGTH) { reportOverflow(); }
diff --git a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java index 2a7f5ea..33cb4c7 100644 --- a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java +++ b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
@@ -31,6 +31,7 @@ import java.util.Set; import sun.net.ResourceManager; +import sun.net.util.IPAddressUtil; import sun.security.action.GetPropertyAction; /** @@ -128,6 +129,9 @@ */ protected synchronized void bind(int lport, InetAddress laddr) throws SocketException { + if (laddr.isLinkLocalAddress()) { + laddr = IPAddressUtil.toScopedAddress(laddr); + } bind0(lport, laddr); } @@ -139,7 +143,19 @@ * destination address to send the packet to. * @param p the packet to be sent. */ - protected abstract void send(DatagramPacket p) throws IOException; + protected void send(DatagramPacket p) throws IOException { + InetAddress orig = p.getAddress(); + if (orig.isLinkLocalAddress()) { + InetAddress scoped = IPAddressUtil.toScopedAddress(orig); + if (orig != scoped) { + p = new DatagramPacket(p.getData(), p.getOffset(), + p.getLength(), scoped, p.getPort()); + } + } + send0(p); + } + + protected abstract void send0(DatagramPacket p) throws IOException; /** * Connects a datagram socket to a remote destination. This associates the remote @@ -149,6 +165,9 @@ * @param port the remote port number */ protected void connect(InetAddress address, int port) throws SocketException { + if (address.isLinkLocalAddress()) { + address = IPAddressUtil.toScopedAddress(address); + } connect0(address, port); connectedAddress = address; connectedPort = port;
diff --git a/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java b/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java index c56601e..30b8ea3 100644 --- a/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java
@@ -37,6 +37,7 @@ import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.ResourceManager; +import sun.net.util.IPAddressUtil; import sun.net.util.SocketExceptions; /** @@ -162,8 +163,12 @@ boolean connected = false; try { InetAddress address = InetAddress.getByName(host); - this.port = port; + // recording this.address as supplied by caller before calling connect this.address = address; + this.port = port; + if (address.isLinkLocalAddress()) { + address = IPAddressUtil.toScopedAddress(address); + } connectToAddress(address, port, timeout); connected = true; @@ -186,8 +191,12 @@ * @param port the specified port */ protected void connect(InetAddress address, int port) throws IOException { - this.port = port; + // recording this.address as supplied by caller before calling connect this.address = address; + this.port = port; + if (address.isLinkLocalAddress()) { + address = IPAddressUtil.toScopedAddress(address); + } try { connectToAddress(address, port, timeout); @@ -218,10 +227,14 @@ InetSocketAddress addr = (InetSocketAddress) address; if (addr.isUnresolved()) throw new UnknownHostException(addr.getHostName()); + // recording this.address as supplied by caller before calling connect + InetAddress ia = addr.getAddress(); + this.address = ia; this.port = addr.getPort(); - this.address = addr.getAddress(); - - connectToAddress(this.address, port, timeout); + if (ia.isLinkLocalAddress()) { + ia = IPAddressUtil.toScopedAddress(ia); + } + connectToAddress(ia, port, timeout); connected = true; } finally { if (!connected) { @@ -433,6 +446,9 @@ NetHooks.beforeTcpBind(fd, address, lport); } } + if (address.isLinkLocalAddress()) { + address = IPAddressUtil.toScopedAddress(address); + } socketBind(address, lport); if (socket != null) socket.setBound();
diff --git a/src/java.base/share/classes/java/net/Inet6Address.java b/src/java.base/share/classes/java/net/Inet6Address.java index 8376d8b..ca9a2cb 100644 --- a/src/java.base/share/classes/java/net/Inet6Address.java +++ b/src/java.base/share/classes/java/net/Inet6Address.java
@@ -176,11 +176,6 @@ class Inet6Address extends InetAddress { static final int INADDRSZ = 16; - /* - * cached scope_id - for link-local address use only. - */ - private transient int cached_scope_id; // 0 - private class Inet6AddressHolder { private Inet6AddressHolder() {
diff --git a/src/java.base/share/classes/java/text/SimpleDateFormat.java b/src/java.base/share/classes/java/text/SimpleDateFormat.java index 4c41a82..7a8ccc3 100644 --- a/src/java.base/share/classes/java/text/SimpleDateFormat.java +++ b/src/java.base/share/classes/java/text/SimpleDateFormat.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1189,7 +1189,7 @@ } break; - case PATTERN_MONTH: // 'M' (context seinsive) + case PATTERN_MONTH: // 'M' (context sensitive) if (useDateFormatSymbols) { String[] months; if (count >= 4) { @@ -2033,7 +2033,7 @@ return index; } } else { - Map<String, Integer> map = getDisplayNamesMap(field, locale); + Map<String, Integer> map = getDisplayContextNamesMap(field, locale); if ((index = matchString(text, start, field, map, calb)) > 0) { return index; } @@ -2450,6 +2450,22 @@ } /** + * Obtains display names map, taking the context into account. Currently only + * the month name pattern 'M' is context dependent. + */ + private Map<String, Integer> getDisplayContextNamesMap(int field, Locale locale) { + Map<String, Integer> map = calendar.getDisplayNames(field, + forceStandaloneForm ? Calendar.SHORT_STANDALONE : Calendar.SHORT_FORMAT, locale); + // Get the LONG style + Map<String, Integer> m = calendar.getDisplayNames(field, + forceStandaloneForm ? Calendar.LONG_STANDALONE : Calendar.LONG_FORMAT, locale); + if (m != null) { + map.putAll(m); + } + return map; + } + + /** * After reading an object from the input stream, the format * pattern in the object is verified. *
diff --git a/src/java.base/share/classes/java/time/format/Parsed.java b/src/java.base/share/classes/java/time/format/Parsed.java index a2a75fa..c11f7a5 100644 --- a/src/java.base/share/classes/java/time/format/Parsed.java +++ b/src/java.base/share/classes/java/time/format/Parsed.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -349,10 +349,11 @@ } private void resolveInstantFields0(ZoneId selectedZone) { - Instant instant = Instant.ofEpochSecond(fieldValues.remove(INSTANT_SECONDS)); + Instant instant = Instant.ofEpochSecond(fieldValues.get(INSTANT_SECONDS)); ChronoZonedDateTime<?> zdt = chrono.zonedDateTime(instant, selectedZone); updateCheckConflict(zdt.toLocalDate()); updateCheckConflict(INSTANT_SECONDS, SECOND_OF_DAY, (long) zdt.toLocalTime().toSecondOfDay()); + updateCheckConflict(INSTANT_SECONDS, OFFSET_SECONDS, (long) zdt.getOffset().getTotalSeconds()); } //----------------------------------------------------------------------- @@ -593,9 +594,9 @@ } private void resolveInstant() { - // add instant seconds if we have date, time and zone + // add instant seconds (if not present) if we have date, time and zone // Offset (if present) will be given priority over the zone. - if (date != null && time != null) { + if (!fieldValues.containsKey(INSTANT_SECONDS) && date != null && time != null) { Long offsetSecs = fieldValues.get(OFFSET_SECONDS); if (offsetSecs != null) { ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSecs.intValue());
diff --git a/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java b/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java index 192a5bc..c73a5a4 100644 --- a/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java +++ b/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java
@@ -154,7 +154,9 @@ count += other.count; simpleSum += other.simpleSum; sumWithCompensation(other.sum); - sumWithCompensation(other.sumCompensation); + + // Subtract compensation bits + sumWithCompensation(-other.sumCompensation); min = Math.min(min, other.min); max = Math.max(max, other.max); } @@ -239,7 +241,7 @@ */ public final double getSum() { // Better error bounds to add both terms as the final sum - double tmp = sum + sumCompensation; + double tmp = sum - sumCompensation; if (Double.isNaN(tmp) && Double.isInfinite(simpleSum)) // If the compensated sum is spuriously NaN from // accumulating one or more same-signed infinite values,
diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index 4123718..67cfab4 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1254,7 +1254,7 @@ /** * Reconstitute the Hashtable from a stream (i.e., deserialize it). */ - private void readObject(java.io.ObjectInputStream s) + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { readHashtable(s); } @@ -1263,14 +1263,16 @@ * Perform deserialization of the Hashtable from an ObjectInputStream. * The Properties class overrides this method. */ - void readHashtable(java.io.ObjectInputStream s) + void readHashtable(ObjectInputStream s) throws IOException, ClassNotFoundException { - // Read in the threshold and loadFactor - s.defaultReadObject(); - // Validate loadFactor (ignore threshold - it will be re-computed) - if (loadFactor <= 0 || Float.isNaN(loadFactor)) - throw new StreamCorruptedException("Illegal Load: " + loadFactor); + ObjectInputStream.GetField fields = s.readFields(); + + // Read and validate loadFactor (ignore threshold - it will be re-computed) + float lf = fields.get("loadFactor", 0.75f); + if (lf <= 0 || Float.isNaN(lf)) + throw new StreamCorruptedException("Illegal load factor: " + lf); + lf = Math.min(Math.max(0.25f, lf), 4.0f); // Read the original length of the array and number of elements int origlength = s.readInt(); @@ -1282,13 +1284,13 @@ // Clamp original length to be more than elements / loadFactor // (this is the invariant enforced with auto-growth) - origlength = Math.max(origlength, (int)(elements / loadFactor) + 1); + origlength = Math.max(origlength, (int)(elements / lf) + 1); // Compute new length with a bit of room 5% + 3 to grow but // no larger than the clamped original length. Make the length // odd if it's large enough, this helps distribute the entries. // Guard against the length ending up zero, that's not valid. - int length = (int)((elements + elements / 20) / loadFactor) + 3; + int length = (int)((elements + elements / 20) / lf) + 3; if (length > elements && (length & 1) == 0) length--; length = Math.min(length, origlength); @@ -1300,8 +1302,9 @@ // Check Map.Entry[].class since it's the nearest public type to // what we're actually creating. SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length); + Hashtable.UnsafeHolder.putLoadFactor(this, lf); table = new Entry<?,?>[length]; - threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); + threshold = (int)Math.min(length * lf, MAX_ARRAY_SIZE + 1); count = 0; // Read the number of elements and then all the key/value objects @@ -1315,6 +1318,18 @@ } } + // Support for resetting final field during deserializing + private static final class UnsafeHolder { + private UnsafeHolder() { throw new InternalError(); } + private static final jdk.internal.misc.Unsafe unsafe + = jdk.internal.misc.Unsafe.getUnsafe(); + private static final long LF_OFFSET + = unsafe.objectFieldOffset(Hashtable.class, "loadFactor"); + static void putLoadFactor(Hashtable<?, ?> table, float lf) { + unsafe.putFloat(table, LF_OFFSET, lf); + } + } + /** * The put method used by readObject. This is provided because put * is overridable and should not be called in readObject since the
diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index b958539..bec1d6e 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package java.util; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.lang.reflect.Array; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -1272,12 +1274,12 @@ * IdentityHashMap. The key-value mappings are emitted in no * particular order. */ - private void writeObject(java.io.ObjectOutputStream s) + private void writeObject(ObjectOutputStream s) throws java.io.IOException { - // Write out and any hidden stuff + // Write out size (number of mappings) and any hidden stuff s.defaultWriteObject(); - // Write out size (number of Mappings) + // Write out size again (maintained for backward compatibility) s.writeInt(size); // Write out keys and values (alternating) @@ -1295,18 +1297,20 @@ * Reconstitutes the {@code IdentityHashMap} instance from a stream (i.e., * deserializes it). */ - private void readObject(java.io.ObjectInputStream s) + private void readObject(ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { - // Read in any hidden stuff - s.defaultReadObject(); + // Size (number of mappings) is written to the stream twice + // Read first size value and ignore it + s.readFields(); - // Read in size (number of Mappings) + // Read second size value, validate and assign to size field int size = s.readInt(); if (size < 0) throw new java.io.StreamCorruptedException ("Illegal mappings count: " + size); int cap = capacity(size); - SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap); + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap*2); + this.size = size; init(cap); // Read the keys and values, and put the mappings in the table
diff --git a/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java b/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java index 4a5d714..f84ea55 100644 --- a/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java +++ b/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -885,7 +885,7 @@ } else if (nfd >= (month1 + monthLength)) { nfd = month1 + monthLength - 1; } - set(DAY_OF_MONTH, (int)(nfd - month1) + 1); + set(DAY_OF_MONTH, getCalendarDate(nfd).getDayOfMonth()); return; } @@ -1457,7 +1457,7 @@ CalendarDate d = gcal.newCalendarDate(TimeZone.NO_TIMEZONE); d.setDate(date.getNormalizedYear(), date.getMonth(), 1); int dayOfWeek = gcal.getDayOfWeek(d); - int monthLength = gcal.getMonthLength(d); + int monthLength = actualMonthLength(); dayOfWeek -= getFirstDayOfWeek(); if (dayOfWeek < 0) { dayOfWeek += 7; @@ -2238,7 +2238,7 @@ private int actualMonthLength() { int length = jcal.getMonthLength(jdate); int eraIndex = getTransitionEraIndex(jdate); - if (eraIndex == -1) { + if (eraIndex != -1) { long transitionFixedDate = sinceFixedDates[eraIndex]; CalendarDate d = eras[eraIndex].getSinceDate(); if (transitionFixedDate <= cachedFixedDate) {
diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index f36066f..e540489 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java
@@ -1610,18 +1610,19 @@ * </pre></ul> * * <p>This implements the 'Language-Tag' production of BCP47, and - * so supports grandfathered (regular and irregular) as well as + * so supports legacy (regular and irregular, referred to as + * "Type: grandfathered" in BCP47) as well as * private use language tags. Stand alone private use tags are * represented as empty language and extension 'x-whatever', - * and grandfathered tags are converted to their canonical replacements + * and legacy tags are converted to their canonical replacements * where they exist. * - * <p>Grandfathered tags with canonical replacements are as follows: + * <p>Legacy tags with canonical replacements are as follows: * * <table class="striped"> - * <caption style="display:none">Grandfathered tags with canonical replacements</caption> + * <caption style="display:none">Legacy tags with canonical replacements</caption> * <thead style="text-align:center"> - * <tr><th scope="col" style="padding: 0 2px">grandfathered tag</th><th scope="col" style="padding: 0 2px">modern replacement</th></tr> + * <tr><th scope="col" style="padding: 0 2px">legacy tag</th><th scope="col" style="padding: 0 2px">modern replacement</th></tr> * </thead> * <tbody style="text-align:center"> * <tr><th scope="row">art-lojban</th><td>jbo</td></tr> @@ -1647,13 +1648,13 @@ * </tbody> * </table> * - * <p>Grandfathered tags with no modern replacement will be + * <p>Legacy tags with no modern replacement will be * converted as follows: * * <table class="striped"> - * <caption style="display:none">Grandfathered tags with no modern replacement</caption> + * <caption style="display:none">Legacy tags with no modern replacement</caption> * <thead style="text-align:center"> - * <tr><th scope="col" style="padding: 0 2px">grandfathered tag</th><th scope="col" style="padding: 0 2px">converts to</th></tr> + * <tr><th scope="col" style="padding: 0 2px">legacy tag</th><th scope="col" style="padding: 0 2px">converts to</th></tr> * </thead> * <tbody style="text-align:center"> * <tr><th scope="row">cel-gaulish</th><td>xtg-x-cel-gaulish</td></tr> @@ -1665,7 +1666,7 @@ * </tbody> * </table> * - * <p>For a list of all grandfathered tags, see the + * <p>For a list of all legacy tags, see the * IANA Language Subtag Registry (search for "Type: grandfathered"). * * <p><b>Note</b>: there is no guarantee that <code>toLanguageTag</code> @@ -2542,7 +2543,7 @@ * Resets the Builder to match the provided IETF BCP 47 * language tag. Discards the existing state. Null and the * empty string cause the builder to be reset, like {@link - * #clear}. Grandfathered tags (see {@link + * #clear}. Legacy tags (see {@link * Locale#forLanguageTag}) are converted to their canonical * form before being processed. Otherwise, the language tag * must be well-formed (see {@link Locale}) or an exception is @@ -2794,7 +2795,7 @@ * on this builder. * * <p>This applies the conversions listed in {@link Locale#forLanguageTag} - * when constructing a Locale. (Grandfathered tags are handled in + * when constructing a Locale. (Legacy tags are handled in * {@link #setLanguageTag}.) * * @return A Locale.
diff --git a/src/java.base/share/classes/java/util/jar/Attributes.java b/src/java.base/share/classes/java/util/jar/Attributes.java index c0eb7e2..bf3504e 100644 --- a/src/java.base/share/classes/java/util/jar/Attributes.java +++ b/src/java.base/share/classes/java/util/jar/Attributes.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package java.util.jar; +import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Collection; @@ -374,7 +375,7 @@ @SuppressWarnings("deprecation") void read(Manifest.FastInputStream is, byte[] lbuf) throws IOException { String name = null, value; - byte[] lastline = null; + ByteArrayOutputStream fullLine = new ByteArrayOutputStream(); int len; while ((len = is.readLine(lbuf)) != -1) { @@ -396,15 +397,12 @@ throw new IOException("misplaced continuation line"); } lineContinued = true; - byte[] buf = new byte[lastline.length + len - 1]; - System.arraycopy(lastline, 0, buf, 0, lastline.length); - System.arraycopy(lbuf, 1, buf, lastline.length, len - 1); + fullLine.write(lbuf, 1, len - 1); if (is.peek() == ' ') { - lastline = buf; continue; } - value = new String(buf, 0, buf.length, UTF_8.INSTANCE); - lastline = null; + value = fullLine.toString(UTF_8.INSTANCE); + fullLine.reset(); } else { while (lbuf[i++] != ':') { if (i >= len) { @@ -416,8 +414,8 @@ } name = new String(lbuf, 0, 0, i - 2); if (is.peek() == ' ') { - lastline = new byte[len - i]; - System.arraycopy(lbuf, i, lastline, 0, len - i); + fullLine.reset(); + fullLine.write(lbuf, i, len - i); continue; } value = new String(lbuf, i, len - i, UTF_8.INSTANCE);
diff --git a/src/java.base/share/classes/java/util/jar/JarFile.java b/src/java.base/share/classes/java/util/jar/JarFile.java index 03b7b43..c902a53 100644 --- a/src/java.base/share/classes/java/util/jar/JarFile.java +++ b/src/java.base/share/classes/java/util/jar/JarFile.java
@@ -758,7 +758,7 @@ } if (mev == null) { mev = new ManifestEntryVerifier - (getManifestFromReference()); + (getManifestFromReference(), jv.manifestName); } byte[] b = getBytes(e); if (b != null && b.length > 0) {
diff --git a/src/java.base/share/classes/java/util/jar/JarInputStream.java b/src/java.base/share/classes/java/util/jar/JarInputStream.java index 54ab0ae..e55704a 100644 --- a/src/java.base/share/classes/java/util/jar/JarInputStream.java +++ b/src/java.base/share/classes/java/util/jar/JarInputStream.java
@@ -96,7 +96,7 @@ closeEntry(); if (doVerify) { jv = new JarVerifier(e.getName(), bytes); - mev = new ManifestEntryVerifier(man); + mev = new ManifestEntryVerifier(man, jv.manifestName); } return (JarEntry)super.getNextEntry(); }
diff --git a/src/java.base/share/classes/java/util/jar/JarVerifier.java b/src/java.base/share/classes/java/util/jar/JarVerifier.java index 578d7ab..5eff048 100644 --- a/src/java.base/share/classes/java/util/jar/JarVerifier.java +++ b/src/java.base/share/classes/java/util/jar/JarVerifier.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,7 +93,7 @@ /** makes code source singleton instances unique to us */ private Object csdomain = new Object(); - /** collect -DIGEST-MANIFEST values for blacklist */ + /** collect -DIGEST-MANIFEST values for deny list */ private List<Object> manifestDigests; public JarVerifier(String name, byte rawBytes[]) { @@ -444,7 +444,7 @@ { this.is = is; this.jv = jv; - this.mev = new ManifestEntryVerifier(man); + this.mev = new ManifestEntryVerifier(man, jv.manifestName); this.jv.beginEntry(je, mev); this.numLeft = je.getSize(); if (this.numLeft == 0)
diff --git a/src/java.base/share/classes/java/util/regex/Pattern.java b/src/java.base/share/classes/java/util/regex/Pattern.java index 37232f1..ffffbb9 100644 --- a/src/java.base/share/classes/java/util/regex/Pattern.java +++ b/src/java.base/share/classes/java/util/regex/Pattern.java
@@ -3439,14 +3439,14 @@ private static final int countChars(CharSequence seq, int index, int lengthInCodePoints) { // optimization - if (lengthInCodePoints == 1 && !Character.isHighSurrogate(seq.charAt(index))) { - assert (index >= 0 && index < seq.length()); + if (lengthInCodePoints == 1 && index >= 0 && index < seq.length() && + !Character.isHighSurrogate(seq.charAt(index))) { return 1; } int length = seq.length(); int x = index; if (lengthInCodePoints >= 0) { - assert (index >= 0 && index < length); + assert ((length == 0 && index == 0) || index >= 0 && index < length); for (int i = 0; x < length && i < lengthInCodePoints; i++) { if (Character.isHighSurrogate(seq.charAt(x++))) { if (x < length && Character.isLowSurrogate(seq.charAt(x))) {
diff --git a/src/java.base/share/classes/java/util/stream/Collectors.java b/src/java.base/share/classes/java/util/stream/Collectors.java index 26d98bf..8906674 100644 --- a/src/java.base/share/classes/java/util/stream/Collectors.java +++ b/src/java.base/share/classes/java/util/stream/Collectors.java
@@ -726,7 +726,8 @@ a[2] += val;}, (a, b) -> { sumWithCompensation(a, b[0]); a[2] += b[2]; - return sumWithCompensation(a, b[1]); }, + // Subtract compensation bits + return sumWithCompensation(a, -b[1]); }, a -> computeFinalSum(a), CH_NOID); } @@ -757,8 +758,8 @@ * correctly-signed infinity stored in the simple sum. */ static double computeFinalSum(double[] summands) { - // Better error bounds to add both terms as the final sum - double tmp = summands[0] + summands[1]; + // Final sum with better error bounds subtract second summand as it is negated + double tmp = summands[0] - summands[1]; double simpleSum = summands[summands.length - 1]; if (Double.isNaN(tmp) && Double.isInfinite(simpleSum)) return simpleSum; @@ -832,13 +833,19 @@ /* * In the arrays allocated for the collect operation, index 0 * holds the high-order bits of the running sum, index 1 holds - * the low-order bits of the sum computed via compensated + * the negated low-order bits of the sum computed via compensated * summation, and index 2 holds the number of values seen. */ return new CollectorImpl<>( () -> new double[4], (a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3]+= val;}, - (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; }, + (a, b) -> { + sumWithCompensation(a, b[0]); + // Subtract compensation bits + sumWithCompensation(a, -b[1]); + a[2] += b[2]; a[3] += b[3]; + return a; + }, a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]), CH_NOID); }
diff --git a/src/java.base/share/classes/java/util/stream/DoublePipeline.java b/src/java.base/share/classes/java/util/stream/DoublePipeline.java index 29f80a6..bb234c9 100644 --- a/src/java.base/share/classes/java/util/stream/DoublePipeline.java +++ b/src/java.base/share/classes/java/util/stream/DoublePipeline.java
@@ -417,7 +417,7 @@ /* * In the arrays allocated for the collect operation, index 0 * holds the high-order bits of the running sum, index 1 holds - * the low-order bits of the sum computed via compensated + * the negated low-order bits of the sum computed via compensated * summation, and index 2 holds the simple sum used to compute * the proper result if the stream contains infinite values of * the same sign. @@ -429,7 +429,8 @@ }, (ll, rr) -> { Collectors.sumWithCompensation(ll, rr[0]); - Collectors.sumWithCompensation(ll, rr[1]); + // Subtract compensation bits + Collectors.sumWithCompensation(ll, -rr[1]); ll[2] += rr[2]; }); @@ -472,7 +473,8 @@ }, (ll, rr) -> { Collectors.sumWithCompensation(ll, rr[0]); - Collectors.sumWithCompensation(ll, rr[1]); + // Subtract compensation bits + Collectors.sumWithCompensation(ll, -rr[1]); ll[2] += rr[2]; ll[3] += rr[3]; });
diff --git a/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java b/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java index 59b4a07..90b38d9 100644 --- a/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java +++ b/src/java.base/share/classes/javax/crypto/EncryptedPrivateKeyInfo.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,14 +77,17 @@ * @exception NullPointerException if the <code>encoded</code> is null. * @exception IOException if error occurs when parsing the ASN.1 encoding. */ - public EncryptedPrivateKeyInfo(byte[] encoded) - throws IOException { + public EncryptedPrivateKeyInfo(byte[] encoded) throws IOException { if (encoded == null) { throw new NullPointerException("the encoded parameter " + - "must be non-null"); + "must be non-null"); } + this.encoded = encoded.clone(); - DerValue val = new DerValue(this.encoded); + DerValue val = DerValue.wrap(this.encoded); + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("DER header error: no SEQ tag"); + } DerValue[] seq = new DerValue[2];
diff --git a/src/java.base/share/classes/javax/security/auth/login/LoginContext.java b/src/java.base/share/classes/javax/security/auth/login/LoginContext.java index 820cb15..002e51c 100644 --- a/src/java.base/share/classes/javax/security/auth/login/LoginContext.java +++ b/src/java.base/share/classes/javax/security/auth/login/LoginContext.java
@@ -40,6 +40,10 @@ import sun.security.util.PendingException; import sun.security.util.ResourcesMgr; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.stream.*; +import java.util.ServiceLoader.Provider; /** * <p> The {@code LoginContext} class describes the basic methods used * to authenticate Subjects and provides a way to develop an @@ -221,6 +225,8 @@ private static final sun.security.util.Debug debug = sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]"); + private static final WeakHashMap<ClassLoader, Set<Provider<LoginModule>>> providersCache = + new WeakHashMap<>(); private void init(String name) throws LoginException { @@ -286,6 +292,7 @@ return loader; } }); + } private void loadDefaultCallbackHandler() throws LoginException { @@ -684,20 +691,34 @@ // locate and instantiate the LoginModule // String name = moduleStack[i].entry.getLoginModuleName(); - ServiceLoader<LoginModule> sc = AccessController.doPrivileged( - (PrivilegedAction<ServiceLoader<LoginModule>>) - () -> ServiceLoader.load( - LoginModule.class, contextClassLoader)); - for (LoginModule m: sc) { - if (m.getClass().getName().equals(name)) { - moduleStack[i].module = m; + Set<Provider<LoginModule>> lmProviders; + synchronized(providersCache){ + lmProviders = providersCache.get(contextClassLoader); + if (lmProviders == null){ + if (debug != null){ + debug.println("Build ServiceProviders cache for ClassLoader: " + contextClassLoader.getName()); + } + ServiceLoader<LoginModule> sc = AccessController.doPrivileged( + (PrivilegedAction<ServiceLoader<LoginModule>>) + () -> java.util.ServiceLoader.load( + LoginModule.class, contextClassLoader)); + lmProviders = sc.stream().collect(Collectors.toSet()); + if (debug != null){ + debug.println("Discovered ServiceProviders for ClassLoader: " + contextClassLoader.getName()); + lmProviders.forEach(System.err::println); + } + providersCache.put(contextClassLoader,lmProviders); + } + } + for (Provider<LoginModule> lm: lmProviders){ + if (lm.type().getName().equals(name)){ + moduleStack[i].module = lm.get(); if (debug != null) { debug.println(name + " loaded as a service"); } break; } } - if (moduleStack[i].module == null) { try { @SuppressWarnings("deprecation")
diff --git a/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java b/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java index ee98b92..f5702f2 100644 --- a/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java +++ b/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java
@@ -849,7 +849,7 @@ else return VM.isBooted(); } - // A bit of black magic. We try to find out the nature of the logging + // A bit of magic. We try to find out the nature of the logging // backend without actually loading it. private static enum LoggingBackend { // There is no LoggerFinder and JUL is not present
diff --git a/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java b/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java index e62a032..a697dff 100644 --- a/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java +++ b/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ } /** - * Returns a new InnocuousThread with an auto-generated thread name + * Returns a new InnocuousThread with an auto-generated thread name, * and its context class loader is set to the system class loader. */ public static Thread newThread(Runnable target) { @@ -62,14 +62,22 @@ * set to the system class loader. */ public static Thread newThread(String name, Runnable target) { + return newThread(name, target, -1); + } + /** + * Returns a new InnocuousThread with its context class loader + * set to the system class loader. The thread priority will be + * set to the given priority. + */ + public static Thread newThread(String name, Runnable target, int priority) { + if (System.getSecurityManager() == null) { + return createThread(name, target, ClassLoader.getSystemClassLoader(), priority); + } return AccessController.doPrivileged( new PrivilegedAction<Thread>() { @Override public Thread run() { - return new InnocuousThread(INNOCUOUSTHREADGROUP, - target, - name, - ClassLoader.getSystemClassLoader()); + return createThread(name, target, ClassLoader.getSystemClassLoader(), priority); } }); } @@ -86,16 +94,35 @@ * Returns a new InnocuousThread with null context class loader. */ public static Thread newSystemThread(String name, Runnable target) { + return newSystemThread(name, target, -1); + } + + /** + * Returns a new InnocuousThread with null context class loader. + * Thread priority is set to the given priority. + */ + public static Thread newSystemThread(String name, Runnable target, int priority) { + if (System.getSecurityManager() == null) { + return createThread(name, target, null, priority); + } return AccessController.doPrivileged( new PrivilegedAction<Thread>() { @Override public Thread run() { - return new InnocuousThread(INNOCUOUSTHREADGROUP, - target, name, null); + return createThread(name, target, null, priority); } }); } + private static Thread createThread(String name, Runnable target, ClassLoader loader, int priority) { + Thread t = new InnocuousThread(INNOCUOUSTHREADGROUP, + target, name, loader); + if (priority >= 0) { + t.setPriority(priority); + } + return t; + } + private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) { super(group, target, name, 0L, false); UNSAFE.putObjectRelease(this, INHERITEDACCESSCONTROLCONTEXT, ACC); @@ -167,13 +194,17 @@ group = parent; } final ThreadGroup root = group; - INNOCUOUSTHREADGROUP = AccessController.doPrivileged( - new PrivilegedAction<ThreadGroup>() { - @Override - public ThreadGroup run() { - return new ThreadGroup(root, "InnocuousThreadGroup"); - } - }); + if (System.getSecurityManager() == null) { + INNOCUOUSTHREADGROUP = new ThreadGroup(root, "InnocuousThreadGroup"); + } else { + INNOCUOUSTHREADGROUP = AccessController.doPrivileged( + new PrivilegedAction<ThreadGroup>() { + @Override + public ThreadGroup run() { + return new ThreadGroup(root, "InnocuousThreadGroup"); + } + }); + } } catch (Exception e) { throw new Error(e); }
diff --git a/src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java b/src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java index e55e9d6..ab5f042 100644 --- a/src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java +++ b/src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import jdk.internal.misc.InnocuousThread; import java.lang.ref.Cleaner; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.concurrent.ThreadFactory; /** @@ -42,14 +40,8 @@ private final static Cleaner commonCleaner = Cleaner.create(new ThreadFactory() { @Override public Thread newThread(Runnable r) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Thread run() { - Thread t = InnocuousThread.newSystemThread("Common-Cleaner", r); - t.setPriority(Thread.MAX_PRIORITY - 2); - return t; - } - }); + return InnocuousThread.newSystemThread("Common-Cleaner", + r, Thread.MAX_PRIORITY - 2); } });
diff --git a/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java b/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java index 5e5c4e7..f141efa 100644 --- a/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java +++ b/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java
@@ -324,15 +324,8 @@ final AtomicInteger cleanerThreadNumber = new AtomicInteger(); public Thread newThread(Runnable r) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Thread run() { - Thread t = InnocuousThread.newThread(r); - t.setPriority(Thread.MAX_PRIORITY - 2); - t.setName("Cleaner-" + cleanerThreadNumber.getAndIncrement()); - return t; - } - }); + return InnocuousThread.newThread("Cleaner-" + cleanerThreadNumber.getAndIncrement(), + r, Thread.MAX_PRIORITY - 2); } }
diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 0cf6173..5460efc 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java
@@ -186,6 +186,7 @@ jdk.attach, jdk.charsets, jdk.compiler, + jdk.crypto.cryptoki, java.net.http, jdk.jfr, jdk.jlink,
diff --git a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java index 696efcb..52cc634 100644 --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java
@@ -28,6 +28,20 @@ import java.net.URL; import java.util.Arrays; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; +import java.security.PrivilegedActionException; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + public class IPAddressUtil { private static final int INADDR4SZ = 4; private static final int INADDR16SZ = 16; @@ -468,4 +482,75 @@ return null; } + /** + * Mapping from unscoped local Inet(6)Address to the same address + * including the correct scope-id, determined from NetworkInterface. + */ + private final static ConcurrentHashMap<InetAddress,InetAddress> + cache = new ConcurrentHashMap<>(); + + /** + * Returns a scoped version of the supplied local, link-local ipv6 address + * if that scope-id can be determined from local NetworkInterfaces. + * If the address already has a scope-id or if the address is not local, ipv6 + * or link local, then the original address is returned. + * + * @param addr + * @exception SocketException if the given ipv6 link local address is found + * on more than one local interface + * @return + */ + public static InetAddress toScopedAddress(InetAddress address) + throws SocketException { + + if (address instanceof Inet6Address && address.isLinkLocalAddress() + && ((Inet6Address) address).getScopeId() == 0) { + + InetAddress cached = null; + try { + cached = cache.computeIfAbsent(address, k -> findScopedAddress(k)); + } catch (UncheckedIOException e) { + throw (SocketException)e.getCause(); + } + return cached != null ? cached : address; + } else { + return address; + } + } + + /** + * Same as above for InetSocketAddress + */ + public static InetSocketAddress toScopedAddress(InetSocketAddress address) + throws SocketException { + InetAddress addr; + InetAddress orig = address.getAddress(); + if ((addr = toScopedAddress(orig)) == orig) { + return address; + } else { + return new InetSocketAddress(addr, address.getPort()); + } + } + + private static InetAddress findScopedAddress(InetAddress address) { + PrivilegedExceptionAction<List<InetAddress>> pa = () -> NetworkInterface.networkInterfaces() + .flatMap(NetworkInterface::inetAddresses) + .filter(a -> (a instanceof Inet6Address) + && address.equals(a) + && ((Inet6Address) a).getScopeId() != 0) + .collect(Collectors.toList()); + List<InetAddress> result; + try { + result = AccessController.doPrivileged(pa); + var sz = result.size(); + if (sz == 0) + return null; + if (sz > 1) + throw new UncheckedIOException(new SocketException( + "Duplicate link local addresses: must specify scope-id")); + return result.get(0); + } catch (PrivilegedActionException pae) { + return null; + } + } }
diff --git a/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/src/java.base/share/classes/sun/net/www/http/HttpClient.java index f456908..43237bf 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java
@@ -303,7 +303,7 @@ ret = kac.get(url, null); if (ret != null && httpuc != null && httpuc.streaming() && - httpuc.getRequestMethod() == "POST") { + "POST".equals(httpuc.getRequestMethod())) { if (!ret.available()) { ret.inCache = false; ret.closeServer();
diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index e641947..96d0f53 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
@@ -2857,7 +2857,7 @@ /* must save before calling close */ reuseClient = http; InputStream is = http.getInputStream(); - if (!method.equals("HEAD")) { + if (!method.equals("HEAD") || tunnelState == TunnelState.SETUP) { try { /* we want to read the rest of the response without using the * hurry mechanism, because that would close the connection
diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java index 95820b0..7efeb15 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java
@@ -331,7 +331,7 @@ ret = (HttpsClient) kac.get(url, sf); if (ret != null && httpuc != null && httpuc.streaming() && - httpuc.getRequestMethod() == "POST") { + "POST".equals(httpuc.getRequestMethod())) { if (!ret.available()) ret = null; }
diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index 770d29c..fd594c4 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -58,6 +58,7 @@ import sun.net.ResourceManager; import sun.net.ext.ExtendedSocketOptions; import static sun.net.ext.ExtendedSocketOptions.SOCK_DGRAM; +import sun.net.util.IPAddressUtil; /** * An implementation of DatagramChannels. @@ -517,14 +518,16 @@ } else { // not connected SecurityManager sm = System.getSecurityManager(); + InetAddress ia = isa.getAddress(); if (sm != null) { - InetAddress ia = isa.getAddress(); if (ia.isMulticastAddress()) { sm.checkMulticast(ia); } else { sm.checkConnect(ia.getHostAddress(), isa.getPort()); } } + if (ia.isLinkLocalAddress()) + isa = IPAddressUtil.toScopedAddress(isa); do { n = send(fd, src, isa); } while ((n == IOStatus.INTERRUPTED) && isOpen());
diff --git a/src/java.base/share/classes/sun/nio/ch/Net.java b/src/java.base/share/classes/sun/nio/ch/Net.java index fe8b126..97675b0 100644 --- a/src/java.base/share/classes/sun/nio/ch/Net.java +++ b/src/java.base/share/classes/sun/nio/ch/Net.java
@@ -50,6 +50,7 @@ import java.util.Enumeration; import sun.net.ext.ExtendedSocketOptions; +import sun.net.util.IPAddressUtil; import sun.security.action.GetPropertyAction; public class Net { @@ -452,6 +453,9 @@ { boolean preferIPv6 = isIPv6Available() && (family != StandardProtocolFamily.INET); + if (addr.isLinkLocalAddress()) { + addr = IPAddressUtil.toScopedAddress(addr); + } bind0(fd, preferIPv6, exclusiveBind, addr, port); } @@ -471,6 +475,9 @@ static int connect(ProtocolFamily family, FileDescriptor fd, InetAddress remote, int remotePort) throws IOException { + if (remote.isLinkLocalAddress()) { + remote = IPAddressUtil.toScopedAddress(remote); + } boolean preferIPv6 = isIPv6Available() && (family != StandardProtocolFamily.INET); return connect0(preferIPv6, fd, remote, remotePort);
diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index d2a8d43..2d6a2ea 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
@@ -603,8 +603,8 @@ if (!(memberType.isInstance(value) || value instanceof ExceptionProxy)) { value = new AnnotationTypeMismatchExceptionProxy( - value.getClass() + "[" + value + "]").setMember( - annotationType.members().get(name)); + objectToString(value)) + .setMember(annotationType.members().get(name)); } } mv.put(name, value); @@ -614,6 +614,15 @@ UnsafeAccessor.setMemberValues(this, mv); } + /* + * Create a textual representation of the argument without calling + * any overridable methods of the argument. + */ + private static String objectToString(Object value) { + return value.getClass().getName() + "@" + + Integer.toHexString(System.identityHashCode(value)); + } + private static class UnsafeAccessor { private static final jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
diff --git a/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java b/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java index 1da1cbd..d3cdf3a 100644 --- a/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java +++ b/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,7 +141,9 @@ if (oldStyle) { // JDK1.1.x-style encoding - content = typeAndContent[1]; + if (typeAndContent.length > 1) { // content is OPTIONAL + content = typeAndContent[1]; + } } else { // This is the correct, standards-compliant encoding. // Parse the content (OPTIONAL field).
diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java index 9de6a9f..042dfd1 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java
@@ -819,7 +819,7 @@ unauthAttrs = new PKCS9Attributes(new PKCS9Attribute[]{ new PKCS9Attribute( - PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_STR, + PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID, tsToken)}); }
diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java index 463fbd7..c6a1bc1 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java
@@ -32,13 +32,7 @@ import java.util.Date; import java.util.Hashtable; import sun.security.x509.CertificateExtensions; -import sun.security.util.Debug; -import sun.security.util.DerEncoder; -import sun.security.util.DerValue; -import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; -import sun.security.util.ObjectIdentifier; -import sun.security.util.HexDumpEncoder; +import sun.security.util.*; /** * Class supporting any PKCS9 attributes. @@ -188,18 +182,11 @@ private static final Class<?> BYTE_ARRAY_CLASS; - static { // static initializer for PKCS9_OIDS - for (int i = 1; i < PKCS9_OIDS.length - 2; i++) { - PKCS9_OIDS[i] = - ObjectIdentifier.newInternal(new int[]{1,2,840,113549,1,9,i}); - } - // Initialize SigningCertificate and SignatureTimestampToken - // separately (because their values are out of sequence) - PKCS9_OIDS[PKCS9_OIDS.length - 2] = - ObjectIdentifier.newInternal(new int[]{1,2,840,113549,1,9,16,2,12}); - PKCS9_OIDS[PKCS9_OIDS.length - 1] = - ObjectIdentifier.newInternal(new int[]{1,2,840,113549,1,9,16,2,14}); - + static { + // set unused PKCS9_OIDS entries to null + // rest are initialized with public constants + PKCS9_OIDS[0] = PKCS9_OIDS[11] = PKCS9_OIDS[12] = PKCS9_OIDS[13] = + PKCS9_OIDS[15] = null; try { BYTE_ARRAY_CLASS = Class.forName("[B"); } catch (ClassNotFoundException e) { @@ -207,99 +194,37 @@ } } - // first element [0] not used - public static final ObjectIdentifier EMAIL_ADDRESS_OID = PKCS9_OIDS[1]; - public static final ObjectIdentifier UNSTRUCTURED_NAME_OID = PKCS9_OIDS[2]; - public static final ObjectIdentifier CONTENT_TYPE_OID = PKCS9_OIDS[3]; - public static final ObjectIdentifier MESSAGE_DIGEST_OID = PKCS9_OIDS[4]; - public static final ObjectIdentifier SIGNING_TIME_OID = PKCS9_OIDS[5]; - public static final ObjectIdentifier COUNTERSIGNATURE_OID = PKCS9_OIDS[6]; - public static final ObjectIdentifier CHALLENGE_PASSWORD_OID = PKCS9_OIDS[7]; - public static final ObjectIdentifier UNSTRUCTURED_ADDRESS_OID = PKCS9_OIDS[8]; - public static final ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID - = PKCS9_OIDS[9]; - public static final ObjectIdentifier ISSUER_SERIALNUMBER_OID = PKCS9_OIDS[10]; + public static final ObjectIdentifier EMAIL_ADDRESS_OID = PKCS9_OIDS[1] = + ObjectIdentifier.of(KnownOIDs.EmailAddress); + public static final ObjectIdentifier UNSTRUCTURED_NAME_OID = PKCS9_OIDS[2] = + ObjectIdentifier.of(KnownOIDs.UnstructuredName); + public static final ObjectIdentifier CONTENT_TYPE_OID = PKCS9_OIDS[3] = + ObjectIdentifier.of(KnownOIDs.ContentType); + public static final ObjectIdentifier MESSAGE_DIGEST_OID = PKCS9_OIDS[4] = + ObjectIdentifier.of(KnownOIDs.MessageDigest); + public static final ObjectIdentifier SIGNING_TIME_OID = PKCS9_OIDS[5] = + ObjectIdentifier.of(KnownOIDs.SigningTime); + public static final ObjectIdentifier COUNTERSIGNATURE_OID = PKCS9_OIDS[6] = + ObjectIdentifier.of(KnownOIDs.CounterSignature); + public static final ObjectIdentifier CHALLENGE_PASSWORD_OID = + PKCS9_OIDS[7] = ObjectIdentifier.of(KnownOIDs.ChallengePassword); + public static final ObjectIdentifier UNSTRUCTURED_ADDRESS_OID = + PKCS9_OIDS[8] = ObjectIdentifier.of(KnownOIDs.UnstructuredAddress); + public static final ObjectIdentifier EXTENDED_CERTIFICATE_ATTRIBUTES_OID = + PKCS9_OIDS[9] = + ObjectIdentifier.of(KnownOIDs.ExtendedCertificateAttributes); + public static final ObjectIdentifier ISSUER_SERIALNUMBER_OID = + PKCS9_OIDS[10] = + ObjectIdentifier.of(KnownOIDs.IssuerAndSerialNumber); // [11], [12] are RSA DSI proprietary // [13] ==> signingDescription, S/MIME, not used anymore - public static final ObjectIdentifier EXTENSION_REQUEST_OID = PKCS9_OIDS[14]; - public static final ObjectIdentifier SMIME_CAPABILITY_OID = PKCS9_OIDS[15]; - public static final ObjectIdentifier SIGNING_CERTIFICATE_OID = PKCS9_OIDS[16]; + public static final ObjectIdentifier EXTENSION_REQUEST_OID = + PKCS9_OIDS[14] = ObjectIdentifier.of(KnownOIDs.ExtensionRequest); + public static final ObjectIdentifier SIGNING_CERTIFICATE_OID = + PKCS9_OIDS[16] = ObjectIdentifier.of(KnownOIDs.SigningCertificate); public static final ObjectIdentifier SIGNATURE_TIMESTAMP_TOKEN_OID = - PKCS9_OIDS[17]; - public static final String EMAIL_ADDRESS_STR = "EmailAddress"; - public static final String UNSTRUCTURED_NAME_STR = "UnstructuredName"; - public static final String CONTENT_TYPE_STR = "ContentType"; - public static final String MESSAGE_DIGEST_STR = "MessageDigest"; - public static final String SIGNING_TIME_STR = "SigningTime"; - public static final String COUNTERSIGNATURE_STR = "Countersignature"; - public static final String CHALLENGE_PASSWORD_STR = "ChallengePassword"; - public static final String UNSTRUCTURED_ADDRESS_STR = "UnstructuredAddress"; - public static final String EXTENDED_CERTIFICATE_ATTRIBUTES_STR = - "ExtendedCertificateAttributes"; - public static final String ISSUER_SERIALNUMBER_STR = "IssuerAndSerialNumber"; - // [11], [12] are RSA DSI proprietary - private static final String RSA_PROPRIETARY_STR = "RSAProprietary"; - // [13] ==> signingDescription, S/MIME, not used anymore - private static final String SMIME_SIGNING_DESC_STR = "SMIMESigningDesc"; - public static final String EXTENSION_REQUEST_STR = "ExtensionRequest"; - public static final String SMIME_CAPABILITY_STR = "SMIMECapability"; - public static final String SIGNING_CERTIFICATE_STR = "SigningCertificate"; - public static final String SIGNATURE_TIMESTAMP_TOKEN_STR = - "SignatureTimestampToken"; - - /** - * Hashtable mapping names and variant names of supported - * attributes to their OIDs. This table contains all name forms - * that occur in PKCS9, in lower case. - */ - private static final Hashtable<String, ObjectIdentifier> NAME_OID_TABLE = - new Hashtable<String, ObjectIdentifier>(18); - - static { // static initializer for PCKS9_NAMES - NAME_OID_TABLE.put("emailaddress", PKCS9_OIDS[1]); - NAME_OID_TABLE.put("unstructuredname", PKCS9_OIDS[2]); - NAME_OID_TABLE.put("contenttype", PKCS9_OIDS[3]); - NAME_OID_TABLE.put("messagedigest", PKCS9_OIDS[4]); - NAME_OID_TABLE.put("signingtime", PKCS9_OIDS[5]); - NAME_OID_TABLE.put("countersignature", PKCS9_OIDS[6]); - NAME_OID_TABLE.put("challengepassword", PKCS9_OIDS[7]); - NAME_OID_TABLE.put("unstructuredaddress", PKCS9_OIDS[8]); - NAME_OID_TABLE.put("extendedcertificateattributes", PKCS9_OIDS[9]); - NAME_OID_TABLE.put("issuerandserialnumber", PKCS9_OIDS[10]); - NAME_OID_TABLE.put("rsaproprietary", PKCS9_OIDS[11]); - NAME_OID_TABLE.put("rsaproprietary", PKCS9_OIDS[12]); - NAME_OID_TABLE.put("signingdescription", PKCS9_OIDS[13]); - NAME_OID_TABLE.put("extensionrequest", PKCS9_OIDS[14]); - NAME_OID_TABLE.put("smimecapability", PKCS9_OIDS[15]); - NAME_OID_TABLE.put("signingcertificate", PKCS9_OIDS[16]); - NAME_OID_TABLE.put("signaturetimestamptoken", PKCS9_OIDS[17]); - }; - - /** - * Hashtable mapping attribute OIDs defined in PKCS9 to the - * corresponding attribute value type. - */ - private static final Hashtable<ObjectIdentifier, String> OID_NAME_TABLE = - new Hashtable<ObjectIdentifier, String>(16); - static { - OID_NAME_TABLE.put(PKCS9_OIDS[1], EMAIL_ADDRESS_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[2], UNSTRUCTURED_NAME_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[3], CONTENT_TYPE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[4], MESSAGE_DIGEST_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[5], SIGNING_TIME_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[6], COUNTERSIGNATURE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[7], CHALLENGE_PASSWORD_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[8], UNSTRUCTURED_ADDRESS_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[9], EXTENDED_CERTIFICATE_ATTRIBUTES_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[10], ISSUER_SERIALNUMBER_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[11], RSA_PROPRIETARY_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[12], RSA_PROPRIETARY_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[13], SMIME_SIGNING_DESC_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[14], EXTENSION_REQUEST_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[15], SMIME_CAPABILITY_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[16], SIGNING_CERTIFICATE_STR); - OID_NAME_TABLE.put(PKCS9_OIDS[17], SIGNATURE_TIMESTAMP_TOKEN_STR); - } + PKCS9_OIDS[17] = + ObjectIdentifier.of(KnownOIDs.SignatureTimestampToken); /** * Acceptable ASN.1 tags for DER encodings of values of PKCS9 @@ -425,34 +350,6 @@ init(oid, value); } - /** - * Construct an attribute object from the attribute's name and - * value. If the attribute is single-valued, provide only one - * value. If the attribute is multi-valued, provide an array - * containing all the values. - * Arrays of length zero are accepted, though probably useless. - * - * <P> The - * <a href=#classTable>table</a> gives the class that <code>value</code> - * must have for a given attribute. Reasonable variants of these - * attributes are accepted; in particular, case does not matter. - * - * @exception IllegalArgumentException - * if the <code>name</code> is not recognized or the - * <code>value</code> has the wrong type. - */ - public PKCS9Attribute(String name, Object value) - throws IllegalArgumentException { - ObjectIdentifier oid = getOID(name); - - if (oid == null) - throw new IllegalArgumentException( - "Unrecognized attribute name " + name + - " constructing PKCS9Attribute."); - - init(oid, value); - } - private void init(ObjectIdentifier oid, Object value) throws IllegalArgumentException { @@ -764,9 +661,9 @@ * Return the name of this attribute. */ public String getName() { - return index == -1 ? - oid.toString() : - OID_NAME_TABLE.get(PKCS9_OIDS[index]); + String n = oid.toString(); + KnownOIDs os = KnownOIDs.findMatch(n); + return (os == null? n : os.stdName()); } /** @@ -774,7 +671,12 @@ * the name. */ public static ObjectIdentifier getOID(String name) { - return NAME_OID_TABLE.get(name.toLowerCase(Locale.ENGLISH)); + KnownOIDs o = KnownOIDs.findMatch(name); + if (o != null) { + return ObjectIdentifier.of(o); + } else { + return null; + } } /** @@ -782,7 +684,7 @@ * the oid. */ public static String getName(ObjectIdentifier oid) { - return OID_NAME_TABLE.get(oid); + return KnownOIDs.findMatch(oid.toString()).stdName(); } /** @@ -796,7 +698,7 @@ if (index == -1) { sb.append(oid.toString()); } else { - sb.append(OID_NAME_TABLE.get(PKCS9_OIDS[index])); + sb.append(getName(oid)); } sb.append(": ");
diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attributes.java b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attributes.java index d8a7ba7..4016ea8 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS9Attributes.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS9Attributes.java
@@ -277,11 +277,13 @@ */ public PKCS9Attribute[] getAttributes() { PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()]; - ObjectIdentifier oid; int j = 0; for (int i=1; i < PKCS9Attribute.PKCS9_OIDS.length && j < attribs.length; i++) { + if (PKCS9Attribute.PKCS9_OIDS[i] == null) { + continue; + } attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); if (attribs[j] != null) @@ -325,11 +327,13 @@ StringBuilder sb = new StringBuilder(200); sb.append("PKCS9 Attributes: [\n\t"); - ObjectIdentifier oid; PKCS9Attribute value; boolean first = true; for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) { + if (PKCS9Attribute.PKCS9_OIDS[i] == null) { + continue; + } value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]); if (value == null) continue; @@ -340,7 +344,7 @@ else sb.append(";\n\t"); - sb.append(value.toString()); + sb.append(value); } sb.append("\n\t] (end PKCS9 Attributes)");
diff --git a/src/java.base/share/classes/sun/security/provider/JavaKeyStore.java b/src/java.base/share/classes/sun/security/provider/JavaKeyStore.java index 20b7b64..c4ed0dc 100644 --- a/src/java.base/share/classes/sun/security/provider/JavaKeyStore.java +++ b/src/java.base/share/classes/sun/security/provider/JavaKeyStore.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -536,7 +536,7 @@ * } * * ended by a keyed SHA1 hash (bytes only) of - * { password + whitener + preceding body } + * { password + extra data + preceding body } */ // password is mandatory when storing @@ -802,7 +802,7 @@ /** * To guard against tampering with the keystore, we append a keyed - * hash with a bit of whitener. + * hash with a bit of extra data. */ private MessageDigest getPreKeyedHash(char[] password) throws NoSuchAlgorithmException, UnsupportedEncodingException
diff --git a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java index 25625a8..22da230 100644 --- a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java +++ b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,8 +102,13 @@ if (!val.getOID().equals(AlgorithmId.mgf1_oid)) { throw new IOException("Only MGF1 mgf is supported"); } + + byte[] encodedParams = val.getEncodedParams(); + if (encodedParams == null) { + throw new IOException("Missing MGF1 parameters"); + } AlgorithmId params = AlgorithmId.parse( - new DerValue(val.getEncodedParams())); + new DerValue(encodedParams)); String mgfDigestName = params.getName(); switch (mgfDigestName) { case "SHA-1":
diff --git a/src/java.base/share/classes/sun/security/ssl/CipherSuite.java b/src/java.base/share/classes/sun/security/ssl/CipherSuite.java index d9dd826..4fcea5f 100644 --- a/src/java.base/share/classes/sun/security/ssl/CipherSuite.java +++ b/src/java.base/share/classes/sun/security/ssl/CipherSuite.java
@@ -25,12 +25,8 @@ package sun.security.ssl; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; + import static sun.security.ssl.CipherSuite.HashAlg.*; import static sun.security.ssl.CipherSuite.KeyExchange.*; import static sun.security.ssl.CipherSuite.MacAlg.*; @@ -861,6 +857,39 @@ final boolean exportable; + private static final Map<Integer, CipherSuite> cipherSuiteIds; + private static final Map<String, CipherSuite> cipherSuiteNames; + private static final List<CipherSuite> allowedCipherSuites; + private static final List<CipherSuite> defaultCipherSuites; + + static { + Map<Integer, CipherSuite> ids = new HashMap<>(); + Map<String, CipherSuite> names = new HashMap<>(); + List<CipherSuite> allowedCS = new ArrayList<>(); + List<CipherSuite> defaultCS = new ArrayList<>(); + + for(CipherSuite cs : CipherSuite.values()) { + ids.put(cs.id, cs); + names.put(cs.name, cs); + for (String alias : cs.aliases) { + names.put(alias, cs); + } + + if (!cs.supportedProtocols.isEmpty()) { + allowedCS.add(cs); + } + + if (cs.isDefaultEnabled) { + defaultCS.add(cs); + } + } + + cipherSuiteIds = Map.copyOf(ids); + cipherSuiteNames = Map.copyOf(names); + allowedCipherSuites = List.copyOf(allowedCS); + defaultCipherSuites = List.copyOf(defaultCS); + } + // known but unsupported cipher suite private CipherSuite(String name, int id) { this(id, false, name, "", @@ -898,62 +927,29 @@ } static CipherSuite nameOf(String ciperSuiteName) { - for (CipherSuite cs : CipherSuite.values()) { - if (cs.name.equals(ciperSuiteName) || - cs.aliases.contains(ciperSuiteName)) { - return cs; - } - } - - return null; + return cipherSuiteNames.get(ciperSuiteName); } static CipherSuite valueOf(int id) { - for (CipherSuite cs : CipherSuite.values()) { - if (cs.id == id) { - return cs; - } - } - - return null; + return cipherSuiteIds.get(id); } static String nameOf(int id) { - for (CipherSuite cs : CipherSuite.values()) { - if (cs.id == id) { - return cs.name; - } + CipherSuite cs = cipherSuiteIds.get(id); + + if (cs != null) { + return cs.name; } return "UNKNOWN-CIPHER-SUITE(" + Utilities.byte16HexString(id) + ")"; } static Collection<CipherSuite> allowedCipherSuites() { - Collection<CipherSuite> cipherSuites = new LinkedList<>(); - for (CipherSuite cs : CipherSuite.values()) { - if (!cs.supportedProtocols.isEmpty()) { - cipherSuites.add(cs); - } else { - // values() is ordered, remaining cipher suites are - // not supported. - break; - } - } - return cipherSuites; + return allowedCipherSuites; } static Collection<CipherSuite> defaultCipherSuites() { - Collection<CipherSuite> cipherSuites = new LinkedList<>(); - for (CipherSuite cs : CipherSuite.values()) { - if (cs.isDefaultEnabled) { - cipherSuites.add(cs); - } else { - // values() is ordered, remaining cipher suites are - // not enabled. - break; - } - } - return cipherSuites; + return defaultCipherSuites; } /** @@ -976,19 +972,11 @@ } boolean found = false; - for (CipherSuite cs : CipherSuite.values()) { - if (!cs.supportedProtocols.isEmpty()) { - if (cs.name.equals(name) || - cs.aliases.contains(name)) { - cipherSuites.add(cs); - found = true; - break; - } - } else { - // values() is ordered, remaining cipher suites are - // not supported. - break; - } + CipherSuite cs; + if ((cs = cipherSuiteNames.get(name)) != null + && !cs.supportedProtocols.isEmpty()) { + cipherSuites.add(cs); + found = true; } if (!found) { throw new IllegalArgumentException(
diff --git a/src/java.base/share/classes/sun/security/ssl/ClientHello.java b/src/java.base/share/classes/sun/security/ssl/ClientHello.java index 1bdc821..6910104 100644 --- a/src/java.base/share/classes/sun/security/ssl/ClientHello.java +++ b/src/java.base/share/classes/sun/security/ssl/ClientHello.java
@@ -403,9 +403,6 @@ // clean up this producer chc.handshakeProducers.remove(SSLHandshake.CLIENT_HELLO.id); - // the max protocol version this client is supporting. - ProtocolVersion maxProtocolVersion = chc.maximumActiveProtocol; - // session ID of the ClientHello message SessionId sessionId = new SessionId(new byte[0]); @@ -539,14 +536,6 @@ if (!session.getProtocolVersion().useTLS13PlusSpec()) { sessionId = session.getSessionId(); } - if (!maxProtocolVersion.equals(sessionVersion)) { - maxProtocolVersion = sessionVersion; - - // Update protocol version number in underlying socket and - // handshake output stream, so that the output records - // (at the record layer) have the correct version - chc.setVersion(sessionVersion); - } // If no new session is allowed, force use of the previous // session ciphersuite, and add the renegotiation SCSV if @@ -581,7 +570,7 @@ "no existing session can be resumed"); } - if (maxProtocolVersion.useTLS13PlusSpec() && + if (chc.maximumActiveProtocol.useTLS13PlusSpec() && SSLConfiguration.useCompatibilityMode) { // In compatibility mode, the TLS 1.3 legacy_session_id // field MUST be non-empty, so a client not offering a @@ -624,7 +613,7 @@ } // Create the handshake message. - ProtocolVersion clientHelloVersion = maxProtocolVersion; + ProtocolVersion clientHelloVersion = chc.maximumActiveProtocol; if (clientHelloVersion.useTLS13PlusSpec()) { // In (D)TLS 1.3, the client indicates its version preferences // in the "supported_versions" extension and the client_version
diff --git a/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java b/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java index 5ed3ee7..0aee1f4 100644 --- a/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java +++ b/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java
@@ -18,7 +18,7 @@ * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 9406+5 USA + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ @@ -59,7 +59,7 @@ } @Override - public synchronized void close() throws IOException { + public void close() throws IOException { if (!isClosed) { super.close(); }
diff --git a/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java b/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java index 2a90bc6..6c06dd2 100644 --- a/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java +++ b/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,13 +58,18 @@ } @Override - public synchronized void close() throws IOException { - if (!isClosed) { - if (fragmenter != null && fragmenter.hasAlert()) { - isCloseWaiting = true; - } else { - super.close(); + public void close() throws IOException { + recordLock.lock(); + try { + if (!isClosed) { + if (fragmenter != null && fragmenter.hasAlert()) { + isCloseWaiting = true; + } else { + super.close(); + } } + } finally { + recordLock.unlock(); } } @@ -266,7 +271,7 @@ if (SSLLogger.isOn && SSLLogger.isOn("record")) { SSLLogger.fine( - "WRITE: " + protocolVersion + " " + + "WRITE: " + protocolVersion.name + " " + ContentType.APPLICATION_DATA.name + ", length = " + destination.remaining()); } @@ -494,7 +499,7 @@ if (SSLLogger.isOn && SSLLogger.isOn("record")) { SSLLogger.fine( - "WRITE: " + protocolVersion + " " + + "WRITE: " + protocolVersion.name + " " + ContentType.nameOf(memo.contentType) + ", length = " + dstBuf.remaining()); }
diff --git a/src/java.base/share/classes/sun/security/ssl/HandshakeContext.java b/src/java.base/share/classes/sun/security/ssl/HandshakeContext.java index 5fa9941..d872ac2 100644 --- a/src/java.base/share/classes/sun/security/ssl/HandshakeContext.java +++ b/src/java.base/share/classes/sun/security/ssl/HandshakeContext.java
@@ -295,13 +295,13 @@ } else if (SSLLogger.isOn && SSLLogger.isOn("verbose")) { SSLLogger.fine( "Ignore unsupported cipher suite: " + suite + - " for " + protocol); + " for " + protocol.name); } } if (!found && (SSLLogger.isOn) && SSLLogger.isOn("handshake")) { SSLLogger.fine( - "No available cipher suite for " + protocol); + "No available cipher suite for " + protocol.name); } } @@ -497,15 +497,6 @@ return activeProtocols.contains(protocolVersion); } - /** - * Set the active protocol version and propagate it to the SSLSocket - * and our handshake streams. Called from ClientHandshaker - * and ServerHandshaker with the negotiated protocol version. - */ - void setVersion(ProtocolVersion protocolVersion) { - this.conContext.protocolVersion = protocolVersion; - } - private static boolean isActivatable(CipherSuite suite, AlgorithmConstraints algorithmConstraints, Map<NamedGroupSpec, Boolean> cachedStatus) {
diff --git a/src/java.base/share/classes/sun/security/ssl/InputRecord.java b/src/java.base/share/classes/sun/security/ssl/InputRecord.java index f033ad2..de860fd 100644 --- a/src/java.base/share/classes/sun/security/ssl/InputRecord.java +++ b/src/java.base/share/classes/sun/security/ssl/InputRecord.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import java.io.OutputStream; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; +import java.util.concurrent.locks.ReentrantLock; import javax.crypto.BadPaddingException; import sun.security.ssl.SSLCipher.SSLReadCipher; @@ -43,10 +44,10 @@ abstract class InputRecord implements Record, Closeable { SSLReadCipher readCipher; // Needed for KeyUpdate, used after Handshake.Finished - TransportContext tc; + TransportContext tc; final HandshakeHash handshakeHash; - boolean isClosed; + volatile boolean isClosed; // The ClientHello version to accept. If set to ProtocolVersion.SSL20Hello // and the first message we read is a ClientHello in V2 format, we convert @@ -56,6 +57,8 @@ // fragment size int fragmentSize; + final ReentrantLock recordLock = new ReentrantLock(); + InputRecord(HandshakeHash handshakeHash, SSLReadCipher readCipher) { this.readCipher = readCipher; this.helloVersion = ProtocolVersion.TLS10; @@ -92,14 +95,19 @@ * and flag the record as holding no data. */ @Override - public synchronized void close() throws IOException { - if (!isClosed) { - isClosed = true; - readCipher.dispose(); + public void close() throws IOException { + recordLock.lock(); + try { + if (!isClosed) { + isClosed = true; + readCipher.dispose(); + } + } finally { + recordLock.unlock(); } } - synchronized boolean isClosed() { + boolean isClosed() { return isClosed; } @@ -114,7 +122,7 @@ * Since MAC's doFinal() is called for every SSL/TLS packet, it's * not necessary to do the same with MAC's. */ - readCipher.dispose(); + this.readCipher.dispose(); this.readCipher = readCipher; }
diff --git a/src/java.base/share/classes/sun/security/ssl/OutputRecord.java b/src/java.base/share/classes/sun/security/ssl/OutputRecord.java index e0f0120..79a234c 100644 --- a/src/java.base/share/classes/sun/security/ssl/OutputRecord.java +++ b/src/java.base/share/classes/sun/security/ssl/OutputRecord.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; +import java.util.concurrent.locks.ReentrantLock; import sun.security.ssl.SSLCipher.SSLWriteCipher; /** @@ -68,6 +69,8 @@ // closed or not? volatile boolean isClosed; + final ReentrantLock recordLock = new ReentrantLock(); + /* * Mappings from V3 cipher suite encodings to their pure V2 equivalents. * This is taken from the SSL V3 specification, Appendix E. @@ -89,15 +92,25 @@ // Please set packetSize and protocolVersion in the implementation. } - synchronized void setVersion(ProtocolVersion protocolVersion) { - this.protocolVersion = protocolVersion; + void setVersion(ProtocolVersion protocolVersion) { + recordLock.lock(); + try { + this.protocolVersion = protocolVersion; + } finally { + recordLock.unlock(); + } } /* * Updates helloVersion of this record. */ - synchronized void setHelloVersion(ProtocolVersion helloVersion) { - this.helloVersion = helloVersion; + void setHelloVersion(ProtocolVersion helloVersion) { + recordLock.lock(); + try { + this.helloVersion = helloVersion; + } finally { + recordLock.unlock(); + } } /* @@ -108,9 +121,14 @@ return false; } - synchronized boolean seqNumIsHuge() { - return (writeCipher.authenticator != null) && + boolean seqNumIsHuge() { + recordLock.lock(); + try { + return (writeCipher.authenticator != null) && writeCipher.authenticator.seqNumIsHuge(); + } finally { + recordLock.unlock(); + } } // SSLEngine and SSLSocket @@ -123,6 +141,11 @@ // SSLEngine and SSLSocket abstract void encodeChangeCipherSpec() throws IOException; + // SSLEngine and SSLSocket + void disposeWriteCipher() { + throw new UnsupportedOperationException(); + } + // apply to SSLEngine only Ciphertext encode( ByteBuffer[] srcs, int srcsOffset, int srcsLength, @@ -148,68 +171,93 @@ } // Change write ciphers, may use change_cipher_spec record. - synchronized void changeWriteCiphers(SSLWriteCipher writeCipher, + void changeWriteCiphers(SSLWriteCipher writeCipher, boolean useChangeCipherSpec) throws IOException { - if (isClosed()) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.warning("outbound has closed, ignore outbound " + - "change_cipher_spec message"); + recordLock.lock(); + try { + if (isClosed()) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning("outbound has closed, ignore outbound " + + "change_cipher_spec message"); + } + return; } - return; + + if (useChangeCipherSpec) { + encodeChangeCipherSpec(); + } + + /* + * Dispose of any intermediate state in the underlying cipher. + * For PKCS11 ciphers, this will release any attached sessions, + * and thus make finalization faster. + * + * Since MAC's doFinal() is called for every SSL/TLS packet, it's + * not necessary to do the same with MAC's. + */ + disposeWriteCipher(); + + this.writeCipher = writeCipher; + this.isFirstAppOutputRecord = true; + } finally { + recordLock.unlock(); } - - if (useChangeCipherSpec) { - encodeChangeCipherSpec(); - } - - /* - * Dispose of any intermediate state in the underlying cipher. - * For PKCS11 ciphers, this will release any attached sessions, - * and thus make finalization faster. - * - * Since MAC's doFinal() is called for every SSL/TLS packet, it's - * not necessary to do the same with MAC's. - */ - writeCipher.dispose(); - - this.writeCipher = writeCipher; - this.isFirstAppOutputRecord = true; } // Change write ciphers using key_update handshake message. - synchronized void changeWriteCiphers(SSLWriteCipher writeCipher, + void changeWriteCiphers(SSLWriteCipher writeCipher, byte keyUpdateRequest) throws IOException { - if (isClosed()) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.warning("outbound has closed, ignore outbound " + - "key_update handshake message"); + recordLock.lock(); + try { + if (isClosed()) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning("outbound has closed, ignore outbound " + + "key_update handshake message"); + } + return; } - return; + + // encode the handshake message, KeyUpdate + byte[] hm = HANDSHAKE_MESSAGE_KEY_UPDATE.clone(); + hm[hm.length - 1] = keyUpdateRequest; + encodeHandshake(hm, 0, hm.length); + flush(); + + // Dispose of any intermediate state in the underlying cipher. + disposeWriteCipher(); + + this.writeCipher = writeCipher; + this.isFirstAppOutputRecord = true; + } finally { + recordLock.unlock(); } - - // encode the handshake message, KeyUpdate - byte[] hm = HANDSHAKE_MESSAGE_KEY_UPDATE.clone(); - hm[hm.length - 1] = keyUpdateRequest; - encodeHandshake(hm, 0, hm.length); - flush(); - - // Dispose of any intermediate state in the underlying cipher. - writeCipher.dispose(); - - this.writeCipher = writeCipher; - this.isFirstAppOutputRecord = true; } - synchronized void changePacketSize(int packetSize) { - this.packetSize = packetSize; + void changePacketSize(int packetSize) { + recordLock.lock(); + try { + this.packetSize = packetSize; + } finally { + recordLock.unlock(); + } } - synchronized void changeFragmentSize(int fragmentSize) { - this.fragmentSize = fragmentSize; + void changeFragmentSize(int fragmentSize) { + recordLock.lock(); + try { + this.fragmentSize = fragmentSize; + } finally { + recordLock.unlock(); + } } - synchronized int getMaxPacketSize() { - return packetSize; + int getMaxPacketSize() { + recordLock.lock(); + try { + return packetSize; + } finally { + recordLock.unlock(); + } } // apply to DTLS SSLEngine @@ -228,13 +276,18 @@ } @Override - public synchronized void close() throws IOException { - if (isClosed) { - return; - } + public void close() throws IOException { + recordLock.lock(); + try { + if (isClosed) { + return; + } - isClosed = true; - writeCipher.dispose(); + isClosed = true; + writeCipher.dispose(); + } finally { + recordLock.unlock(); + } } boolean isClosed() {
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLEngineOutputRecord.java b/src/java.base/share/classes/sun/security/ssl/SSLEngineOutputRecord.java index ee82d27..231b902 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLEngineOutputRecord.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLEngineOutputRecord.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,13 +51,18 @@ } @Override - public synchronized void close() throws IOException { - if (!isClosed) { - if (fragmenter != null && fragmenter.hasAlert()) { - isCloseWaiting = true; - } else { - super.close(); + public void close() throws IOException { + recordLock.lock(); + try { + if (!isClosed) { + if (fragmenter != null && !fragmenter.isEmpty()) { + isCloseWaiting = true; + } else { + super.close(); + } } + } finally { + recordLock.unlock(); } } @@ -147,6 +152,15 @@ } @Override + void disposeWriteCipher() { + if (fragmenter == null) { + writeCipher.dispose(); + } else { + fragmenter.queueUpCipherDispose(); + } + } + + @Override void encodeV2NoCipher() throws IOException { isTalkingToV2 = true; } @@ -264,7 +278,7 @@ if (SSLLogger.isOn && SSLLogger.isOn("record")) { SSLLogger.fine( - "WRITE: " + protocolVersion + " " + + "WRITE: " + protocolVersion.name + " " + ContentType.APPLICATION_DATA.name + ", length = " + destination.remaining()); } @@ -356,6 +370,7 @@ byte majorVersion; byte minorVersion; SSLWriteCipher encodeCipher; + boolean disposeCipher; byte[] fragment; } @@ -416,6 +431,15 @@ handshakeMemos.add(memo); } + void queueUpCipherDispose() { + RecordMemo lastMemo = handshakeMemos.peekLast(); + if (lastMemo != null) { + lastMemo.disposeCipher = true; + } else { + writeCipher.dispose(); + } + } + Ciphertext acquireCiphertext(ByteBuffer dstBuf) throws IOException { if (isEmpty()) { return null; @@ -503,7 +527,7 @@ if (SSLLogger.isOn && SSLLogger.isOn("record")) { SSLLogger.fine( - "WRITE: " + protocolVersion + " " + + "WRITE: " + protocolVersion.name + " " + ContentType.nameOf(memo.contentType) + ", length = " + dstBuf.remaining()); } @@ -515,6 +539,9 @@ dstPos, dstLim, headerSize, ProtocolVersion.valueOf(memo.majorVersion, memo.minorVersion)); + if (memo.disposeCipher) { + memo.encodeCipher.dispose(); + } if (SSLLogger.isOn && SSLLogger.isOn("packet")) { ByteBuffer temporary = dstBuf.duplicate();
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java index c1a90a0..239f802 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java
@@ -28,10 +28,9 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.text.MessageFormat; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.Locale; +import java.util.*; + +import sun.security.action.GetPropertyAction; import sun.security.ssl.SSLHandshake.HandshakeMessage; import sun.security.util.HexDumpEncoder; @@ -628,8 +627,8 @@ } public boolean isAvailable(ProtocolVersion protocolVersion) { - for (int i = 0; i < supportedProtocols.length; i++) { - if (supportedProtocols[i] == protocolVersion) { + for (ProtocolVersion supportedProtocol : supportedProtocols) { + if (supportedProtocol == protocolVersion) { return true; } } @@ -693,18 +692,23 @@ static final Collection<SSLExtension> defaults; static { + Collection<String> clientDisabledExtensions = + getDisabledExtensions("jdk.tls.client.disableExtensions"); Collection<SSLExtension> extensions = new LinkedList<>(); for (SSLExtension extension : SSLExtension.values()) { - if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) { + if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE && + !clientDisabledExtensions.contains(extension.name)) { extensions.add(extension); } } - // Switch off SNI extention? - boolean enableExtension = - Utilities.getBooleanProperty("jsse.enableSNIExtension", true); - if (!enableExtension) { - extensions.remove(CH_SERVER_NAME); + // Switch off SNI extension? + if (extensions.contains(CH_SERVER_NAME)) { + boolean enableExtension = Utilities.getBooleanProperty( + "jsse.enableSNIExtension", true); + if (!enableExtension) { + extensions.remove(CH_SERVER_NAME); + } } // To switch off the max_fragment_length extension. @@ -715,13 +719,15 @@ // the two properties set to true, the extension is switch on. // We may remove the "jsse.enableMFLExtension" property in the // future. Please don't continue to use the misspelling property. - enableExtension = - Utilities.getBooleanProperty( - "jsse.enableMFLNExtension", false) || - Utilities.getBooleanProperty( - "jsse.enableMFLExtension", false); - if (!enableExtension) { - extensions.remove(CH_MAX_FRAGMENT_LENGTH); + if (extensions.contains(CH_MAX_FRAGMENT_LENGTH)) { + boolean enableExtension = + Utilities.getBooleanProperty( + "jsse.enableMFLNExtension", false) || + Utilities.getBooleanProperty( + "jsse.enableMFLExtension", false); + if (!enableExtension) { + extensions.remove(CH_MAX_FRAGMENT_LENGTH); + } } // To switch on certificate_authorities extension in ClientHello. @@ -762,10 +768,12 @@ // lot in practice. When there is a need to use this extension // in ClientHello handshake message, please take care of the // potential compatibility and interoperability issues above. - enableExtension = Utilities.getBooleanProperty( - "jdk.tls.client.enableCAExtension", false); - if (!enableExtension) { - extensions.remove(CH_CERTIFICATE_AUTHORITIES); + if (extensions.contains(CH_CERTIFICATE_AUTHORITIES)) { + boolean enableExtension = Utilities.getBooleanProperty( + "jdk.tls.client.enableCAExtension", false); + if (!enableExtension) { + extensions.remove(CH_CERTIFICATE_AUTHORITIES); + } } defaults = Collections.unmodifiableCollection(extensions); @@ -777,9 +785,12 @@ static final Collection<SSLExtension> defaults; static { + Collection<String> serverDisabledExtensions = + getDisabledExtensions("jdk.tls.server.disableExtensions"); Collection<SSLExtension> extensions = new LinkedList<>(); for (SSLExtension extension : SSLExtension.values()) { - if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) { + if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE && + !serverDisabledExtensions.contains(extension.name)) { extensions.add(extension); } } @@ -787,4 +798,38 @@ defaults = Collections.unmodifiableCollection(extensions); } } + + // Get disabled extensions, which could be customized with System Properties. + private static Collection<String> getDisabledExtensions( + String propertyName) { + String property = GetPropertyAction.privilegedGetProperty(propertyName); + if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { + SSLLogger.fine( + "System property " + propertyName + " is set to '" + + property + "'"); + } + if (property != null && !property.isEmpty()) { + // remove double quote marks from beginning/end of the property + if (property.length() > 1 && property.charAt(0) == '"' && + property.charAt(property.length() - 1) == '"') { + property = property.substring(1, property.length() - 1); + } + } + + if (property != null && !property.isEmpty()) { + String[] extensionNames = property.split(","); + Collection<String> extensions = + new ArrayList<>(extensionNames.length); + for (String extension : extensionNames) { + extension = extension.trim(); + if (!extension.isEmpty()) { + extensions.add(extension); + } + } + + return extensions; + } + + return Collections.emptyList(); + } }
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java b/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java index 6d181e0..24aecaf 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java index a5ff954..fa85e20 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -38,6 +38,7 @@ import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiFunction; import javax.net.ssl.HandshakeCompletedListener; @@ -107,6 +108,11 @@ private static final boolean trustNameService = Utilities.getBooleanProperty("jdk.tls.trustNameService", false); + /* + * Default timeout to skip bytes from the open socket + */ + private static final int DEFAULT_SKIP_TIMEOUT = 1; + /** * Package-private constructor used to instantiate an unconnected * socket. @@ -659,22 +665,96 @@ void closeNotify(boolean useUserCanceled) throws IOException { // Need a lock here so that the user_canceled alert and the // close_notify alert can be delivered together. - try { - synchronized (conContext.outputRecord) { - // send a user_canceled alert if needed. - if (useUserCanceled) { - conContext.warning(Alert.USER_CANCELED); - } + int linger = getSoLinger(); + if (linger >= 0) { + // don't wait more than SO_LINGER for obtaining the + // the lock. + // + // keep and clear the current thread interruption status. + boolean interrupted = Thread.interrupted(); + try { + if (conContext.outputRecord.recordLock.tryLock() || + conContext.outputRecord.recordLock.tryLock( + linger, TimeUnit.SECONDS)) { + try { + handleClosedNotifyAlert(useUserCanceled); + } finally { + conContext.outputRecord.recordLock.unlock(); + } + } else { + // For layered, non-autoclose sockets, we are not + // able to bring them into a usable state, so we + // treat it as fatal error. + if (!super.isOutputShutdown()) { + if (isLayered() && !autoClose) { + throw new SSLException( + "SO_LINGER timeout, " + + "close_notify message cannot be sent."); + } else { + super.shutdownOutput(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning( + "SSLSocket output duplex close failed: " + + "SO_LINGER timeout, " + + "close_notify message cannot be sent."); + } + } + } - // send a close_notify alert - conContext.warning(Alert.CLOSE_NOTIFY); + // RFC2246 requires that the session becomes + // unresumable if any connection is terminated + // without proper close_notify messages with + // level equal to warning. + // + // RFC4346 no longer requires that a session not be + // resumed if failure to properly close a connection. + // + // We choose to make the session unresumable if + // failed to send the close_notify message. + // + conContext.conSession.invalidate(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning( + "Invalidate the session: SO_LINGER timeout, " + + "close_notify message cannot be sent."); + } + } + } catch (InterruptedException ex) { + // keep interrupted status + interrupted = true; } + + // restore the interrupted status + if (interrupted) { + Thread.currentThread().interrupt(); + } + } else { + conContext.outputRecord.recordLock.lock(); + try { + handleClosedNotifyAlert(useUserCanceled); + } finally { + conContext.outputRecord.recordLock.unlock(); + } + } + } + + private void handleClosedNotifyAlert( + boolean useUserCanceled) throws IOException { + try { + // send a user_canceled alert if needed. + if (useUserCanceled) { + conContext.warning(Alert.USER_CANCELED); + } + + // send a close_notify alert + conContext.warning(Alert.CLOSE_NOTIFY); } finally { if (!conContext.isOutboundClosed()) { conContext.outputRecord.close(); } - if ((autoClose || !isLayered()) && !super.isOutputShutdown()) { + if (!super.isOutputShutdown() && + (autoClose || !isLayered())) { super.shutdownOutput(); } } @@ -1681,9 +1761,23 @@ if (conContext.inputRecord instanceof SSLSocketInputRecord && isConnected) { if (appInput.readLock.tryLock()) { + int soTimeout = getSoTimeout(); try { + // deplete could hang on the skip operation + // in case of infinite socket read timeout. + // Change read timeout to avoid deadlock. + // This workaround could be replaced later + // with the right synchronization + if (soTimeout == 0) { + setSoTimeout(DEFAULT_SKIP_TIMEOUT); + } ((SSLSocketInputRecord) (conContext.inputRecord)).deplete(false); + } catch (java.net.SocketTimeoutException stEx) { + // skip timeout exception during deplete } finally { + if (soTimeout == 0) { + setSoTimeout(soTimeout); + } appInput.readLock.unlock(); } }
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSocketOutputRecord.java b/src/java.base/share/classes/sun/security/ssl/SSLSocketOutputRecord.java index 2320506..1c48e16 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSocketOutputRecord.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketOutputRecord.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,129 +51,215 @@ } @Override - synchronized void encodeAlert( - byte level, byte description) throws IOException { - if (isClosed()) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.warning("outbound has closed, ignore outbound " + - "alert message: " + Alert.nameOf(description)); + void encodeAlert(byte level, byte description) throws IOException { + recordLock.lock(); + try { + if (isClosed()) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning("outbound has closed, ignore outbound " + + "alert message: " + Alert.nameOf(description)); + } + return; } - return; + + // use the buf of ByteArrayOutputStream + count = headerSize + writeCipher.getExplicitNonceSize(); + + write(level); + write(description); + if (SSLLogger.isOn && SSLLogger.isOn("record")) { + SSLLogger.fine("WRITE: " + protocolVersion.name + + " " + ContentType.ALERT.name + + "(" + Alert.nameOf(description) + ")" + + ", length = " + (count - headerSize)); + } + + // Encrypt the fragment and wrap up a record. + encrypt(writeCipher, ContentType.ALERT.id, headerSize); + + // deliver this message + deliverStream.write(buf, 0, count); // may throw IOException + deliverStream.flush(); // may throw IOException + + if (SSLLogger.isOn && SSLLogger.isOn("packet")) { + SSLLogger.fine("Raw write", + (new ByteArrayInputStream(buf, 0, count))); + } + + // reset the internal buffer + count = 0; + } finally { + recordLock.unlock(); } - - // use the buf of ByteArrayOutputStream - int position = headerSize + writeCipher.getExplicitNonceSize(); - count = position; - - write(level); - write(description); - if (SSLLogger.isOn && SSLLogger.isOn("record")) { - SSLLogger.fine("WRITE: " + protocolVersion + - " " + ContentType.ALERT.name + - "(" + Alert.nameOf(description) + ")" + - ", length = " + (count - headerSize)); - } - - // Encrypt the fragment and wrap up a record. - encrypt(writeCipher, ContentType.ALERT.id, headerSize); - - // deliver this message - deliverStream.write(buf, 0, count); // may throw IOException - deliverStream.flush(); // may throw IOException - - if (SSLLogger.isOn && SSLLogger.isOn("packet")) { - SSLLogger.fine("Raw write", - (new ByteArrayInputStream(buf, 0, count))); - } - - // reset the internal buffer - count = 0; } @Override - synchronized void encodeHandshake(byte[] source, + void encodeHandshake(byte[] source, int offset, int length) throws IOException { - if (isClosed()) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.warning("outbound has closed, ignore outbound " + - "handshake message", - ByteBuffer.wrap(source, offset, length)); + recordLock.lock(); + try { + if (isClosed()) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning("outbound has closed, ignore outbound " + + "handshake message", + ByteBuffer.wrap(source, offset, length)); + } + return; } - return; - } - if (firstMessage) { - firstMessage = false; + if (firstMessage) { + firstMessage = false; - if ((helloVersion == ProtocolVersion.SSL20Hello) && - (source[offset] == SSLHandshake.CLIENT_HELLO.id) && + if ((helloVersion == ProtocolVersion.SSL20Hello) && + (source[offset] == SSLHandshake.CLIENT_HELLO.id) && // 5: recode header size - (source[offset + 4 + 2 + 32] == 0)) { + (source[offset + 4 + 2 + 32] == 0)) { // V3 session ID is empty // 4: handshake header size // 2: client_version in ClientHello // 32: random in ClientHello - ByteBuffer v2ClientHello = encodeV2ClientHello( - source, (offset + 4), (length - 4)); + ByteBuffer v2ClientHello = encodeV2ClientHello( + source, (offset + 4), (length - 4)); - byte[] record = v2ClientHello.array(); // array offset is zero - int limit = v2ClientHello.limit(); - handshakeHash.deliver(record, 2, (limit - 2)); + // array offset is zero + byte[] record = v2ClientHello.array(); + int limit = v2ClientHello.limit(); + handshakeHash.deliver(record, 2, (limit - 2)); + + if (SSLLogger.isOn && SSLLogger.isOn("record")) { + SSLLogger.fine( + "WRITE: SSLv2 ClientHello message" + + ", length = " + limit); + } + + // deliver this message + // + // Version 2 ClientHello message should be plaintext. + // + // No max fragment length negotiation. + deliverStream.write(record, 0, limit); + deliverStream.flush(); + + if (SSLLogger.isOn && SSLLogger.isOn("packet")) { + SSLLogger.fine("Raw write", + (new ByteArrayInputStream(record, 0, limit))); + } + + return; + } + } + + byte handshakeType = source[0]; + if (handshakeHash.isHashable(handshakeType)) { + handshakeHash.deliver(source, offset, length); + } + + int fragLimit = getFragLimit(); + int position = headerSize + writeCipher.getExplicitNonceSize(); + if (count == 0) { + count = position; + } + + if ((count - position) < (fragLimit - length)) { + write(source, offset, length); + return; + } + + for (int limit = (offset + length); offset < limit;) { + + int remains = (limit - offset) + (count - position); + int fragLen = Math.min(fragLimit, remains); + + // use the buf of ByteArrayOutputStream + write(source, offset, fragLen); + if (remains < fragLimit) { + return; + } if (SSLLogger.isOn && SSLLogger.isOn("record")) { SSLLogger.fine( - "WRITE: SSLv2 ClientHello message" + - ", length = " + limit); + "WRITE: " + protocolVersion.name + + " " + ContentType.HANDSHAKE.name + + ", length = " + (count - headerSize)); } + // Encrypt the fragment and wrap up a record. + encrypt(writeCipher, ContentType.HANDSHAKE.id, headerSize); + // deliver this message - // - // Version 2 ClientHello message should be plaintext. - // - // No max fragment length negotiation. - deliverStream.write(record, 0, limit); - deliverStream.flush(); + deliverStream.write(buf, 0, count); // may throw IOException + deliverStream.flush(); // may throw IOException if (SSLLogger.isOn && SSLLogger.isOn("packet")) { SSLLogger.fine("Raw write", - (new ByteArrayInputStream(record, 0, limit))); + (new ByteArrayInputStream(buf, 0, count))); } + // reset the offset + offset += fragLen; + + // reset the internal buffer + count = position; + } + } finally { + recordLock.unlock(); + } + } + + @Override + void encodeChangeCipherSpec() throws IOException { + recordLock.lock(); + try { + if (isClosed()) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning("outbound has closed, ignore outbound " + + "change_cipher_spec message"); + } return; } - } - - byte handshakeType = source[0]; - if (handshakeHash.isHashable(handshakeType)) { - handshakeHash.deliver(source, offset, length); - } - - int fragLimit = getFragLimit(); - int position = headerSize + writeCipher.getExplicitNonceSize(); - if (count == 0) { - count = position; - } - - if ((count - position) < (fragLimit - length)) { - write(source, offset, length); - return; - } - - for (int limit = (offset + length); offset < limit;) { - - int remains = (limit - offset) + (count - position); - int fragLen = Math.min(fragLimit, remains); // use the buf of ByteArrayOutputStream - write(source, offset, fragLen); - if (remains < fragLimit) { + count = headerSize + writeCipher.getExplicitNonceSize(); + + write((byte)1); // byte 1: change_cipher_spec( + + // Encrypt the fragment and wrap up a record. + encrypt(writeCipher, ContentType.CHANGE_CIPHER_SPEC.id, headerSize); + + // deliver this message + deliverStream.write(buf, 0, count); // may throw IOException + // deliverStream.flush(); // flush in Finished + + if (SSLLogger.isOn && SSLLogger.isOn("packet")) { + SSLLogger.fine("Raw write", + (new ByteArrayInputStream(buf, 0, count))); + } + + // reset the internal buffer + count = 0; + } finally { + recordLock.unlock(); + } + } + + @Override + void disposeWriteCipher() { + writeCipher.dispose(); + } + + @Override + public void flush() throws IOException { + recordLock.lock(); + try { + int position = headerSize + writeCipher.getExplicitNonceSize(); + if (count <= position) { return; } if (SSLLogger.isOn && SSLLogger.isOn("record")) { SSLLogger.fine( - "WRITE: " + protocolVersion + + "WRITE: " + protocolVersion.name + " " + ContentType.HANDSHAKE.name + ", length = " + (count - headerSize)); } @@ -190,154 +276,102 @@ (new ByteArrayInputStream(buf, 0, count))); } - // reset the offset - offset += fragLen; - // reset the internal buffer - count = position; + count = 0; // DON'T use position + } finally { + recordLock.unlock(); } } @Override - synchronized void encodeChangeCipherSpec() throws IOException { - if (isClosed()) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.warning("outbound has closed, ignore outbound " + - "change_cipher_spec message"); - } - return; - } - - // use the buf of ByteArrayOutputStream - int position = headerSize + writeCipher.getExplicitNonceSize(); - count = position; - - write((byte)1); // byte 1: change_cipher_spec( - - // Encrypt the fragment and wrap up a record. - encrypt(writeCipher, ContentType.CHANGE_CIPHER_SPEC.id, headerSize); - - // deliver this message - deliverStream.write(buf, 0, count); // may throw IOException - // deliverStream.flush(); // flush in Finished - - if (SSLLogger.isOn && SSLLogger.isOn("packet")) { - SSLLogger.fine("Raw write", - (new ByteArrayInputStream(buf, 0, count))); - } - - // reset the internal buffer - count = 0; - } - - @Override - public synchronized void flush() throws IOException { - int position = headerSize + writeCipher.getExplicitNonceSize(); - if (count <= position) { - return; - } - - if (SSLLogger.isOn && SSLLogger.isOn("record")) { - SSLLogger.fine( - "WRITE: " + protocolVersion + - " " + ContentType.HANDSHAKE.name + - ", length = " + (count - headerSize)); - } - - // Encrypt the fragment and wrap up a record. - encrypt(writeCipher, ContentType.HANDSHAKE.id, headerSize); - - // deliver this message - deliverStream.write(buf, 0, count); // may throw IOException - deliverStream.flush(); // may throw IOException - - if (SSLLogger.isOn && SSLLogger.isOn("packet")) { - SSLLogger.fine("Raw write", - (new ByteArrayInputStream(buf, 0, count))); - } - - // reset the internal buffer - count = 0; // DON'T use position - } - - @Override - synchronized void deliver( - byte[] source, int offset, int length) throws IOException { - if (isClosed()) { - throw new SocketException("Connection or outbound has been closed"); - } - - if (writeCipher.authenticator.seqNumOverflow()) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { - SSLLogger.fine( - "sequence number extremely close to overflow " + - "(2^64-1 packets). Closing connection."); + void deliver(byte[] source, int offset, int length) throws IOException { + recordLock.lock(); + try { + if (isClosed()) { + throw new SocketException( + "Connection or outbound has been closed"); } - throw new SSLHandshakeException("sequence number overflow"); - } + if (writeCipher.authenticator.seqNumOverflow()) { + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.fine( + "sequence number extremely close to overflow " + + "(2^64-1 packets). Closing connection."); + } - boolean isFirstRecordOfThePayload = true; - for (int limit = (offset + length); offset < limit;) { - int fragLen; - if (packetSize > 0) { - fragLen = Math.min(maxRecordSize, packetSize); - fragLen = - writeCipher.calculateFragmentSize(fragLen, headerSize); - - fragLen = Math.min(fragLen, Record.maxDataSize); - } else { - fragLen = Record.maxDataSize; + throw new SSLHandshakeException("sequence number overflow"); } - // Calculate more impact, for example TLS 1.3 padding. - fragLen = calculateFragmentSize(fragLen); + boolean isFirstRecordOfThePayload = true; + for (int limit = (offset + length); offset < limit;) { + int fragLen; + if (packetSize > 0) { + fragLen = Math.min(maxRecordSize, packetSize); + fragLen = writeCipher.calculateFragmentSize( + fragLen, headerSize); - if (isFirstRecordOfThePayload && needToSplitPayload()) { - fragLen = 1; - isFirstRecordOfThePayload = false; - } else { - fragLen = Math.min(fragLen, (limit - offset)); + fragLen = Math.min(fragLen, Record.maxDataSize); + } else { + fragLen = Record.maxDataSize; + } + + // Calculate more impact, for example TLS 1.3 padding. + fragLen = calculateFragmentSize(fragLen); + + if (isFirstRecordOfThePayload && needToSplitPayload()) { + fragLen = 1; + isFirstRecordOfThePayload = false; + } else { + fragLen = Math.min(fragLen, (limit - offset)); + } + + // use the buf of ByteArrayOutputStream + int position = headerSize + writeCipher.getExplicitNonceSize(); + count = position; + write(source, offset, fragLen); + + if (SSLLogger.isOn && SSLLogger.isOn("record")) { + SSLLogger.fine( + "WRITE: " + protocolVersion.name + + " " + ContentType.APPLICATION_DATA.name + + ", length = " + (count - position)); + } + + // Encrypt the fragment and wrap up a record. + encrypt(writeCipher, + ContentType.APPLICATION_DATA.id, headerSize); + + // deliver this message + deliverStream.write(buf, 0, count); // may throw IOException + deliverStream.flush(); // may throw IOException + + if (SSLLogger.isOn && SSLLogger.isOn("packet")) { + SSLLogger.fine("Raw write", + (new ByteArrayInputStream(buf, 0, count))); + } + + // reset the internal buffer + count = 0; + + if (isFirstAppOutputRecord) { + isFirstAppOutputRecord = false; + } + + offset += fragLen; } - - // use the buf of ByteArrayOutputStream - int position = headerSize + writeCipher.getExplicitNonceSize(); - count = position; - write(source, offset, fragLen); - - if (SSLLogger.isOn && SSLLogger.isOn("record")) { - SSLLogger.fine( - "WRITE: " + protocolVersion + - " " + ContentType.APPLICATION_DATA.name + - ", length = " + (count - position)); - } - - // Encrypt the fragment and wrap up a record. - encrypt(writeCipher, ContentType.APPLICATION_DATA.id, headerSize); - - // deliver this message - deliverStream.write(buf, 0, count); // may throw IOException - deliverStream.flush(); // may throw IOException - - if (SSLLogger.isOn && SSLLogger.isOn("packet")) { - SSLLogger.fine("Raw write", - (new ByteArrayInputStream(buf, 0, count))); - } - - // reset the internal buffer - count = 0; - - if (isFirstAppOutputRecord) { - isFirstAppOutputRecord = false; - } - - offset += fragLen; + } finally { + recordLock.unlock(); } } @Override - synchronized void setDeliverStream(OutputStream outputStream) { - this.deliverStream = outputStream; + void setDeliverStream(OutputStream outputStream) { + recordLock.lock(); + try { + this.deliverStream = outputStream; + } finally { + recordLock.unlock(); + } } /*
diff --git a/src/java.base/share/classes/sun/security/ssl/TransportContext.java b/src/java.base/share/classes/sun/security/ssl/TransportContext.java index 200429e..91266db 100644 --- a/src/java.base/share/classes/sun/security/ssl/TransportContext.java +++ b/src/java.base/share/classes/sun/security/ssl/TransportContext.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package sun.security.ssl; import java.io.IOException; +import java.net.SocketException; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; @@ -262,7 +263,8 @@ } else { // Need a lock here so that the user_canceled alert and the // close_notify alert can be delivered together. - synchronized (outputRecord) { + outputRecord.recordLock.lock(); + try { try { // send a user_canceled alert if needed. if (isUserCanceled) { @@ -274,6 +276,8 @@ } finally { outputRecord.close(); } + } finally { + outputRecord.recordLock.unlock(); } } } @@ -362,7 +366,12 @@ // invalidate the session if (conSession != null) { - conSession.invalidate(); + // In the case of a low-layer transport error, we want to prevent + // the session from being invalidated since this is not a TLS-level + // error event. + if (!(cause instanceof SocketException)) { + conSession.invalidate(); + } } if (handshakeContext != null &&
diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 4499d90..3582ca5 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2150,6 +2150,9 @@ out.println(mf); dumpCert(cert, out); } else if (debug) { + for (var attr : keyStore.getEntry(alias, null).getAttributes()) { + System.out.println("Attribute " + attr.getName() + ": " + attr.getValue()); + } out.println(cert.toString()); } else { out.println("trustedCertEntry, ");
diff --git a/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java b/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java index b33adc9..6bdbd65 100644 --- a/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java +++ b/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java
@@ -144,15 +144,14 @@ * then skip the tag and its 1 byte length of zero. */ private void writeTag() { - if (dataPos == dataSize) { - return; - } - assert dataPos + 1 < dataSize; - if (isEOC(data, dataPos)) { - dataPos += 2; // skip tag and length - writeTag(); - } else { - newData[newDataPos++] = data[dataPos++]; + while (dataPos < dataSize) { + assert dataPos + 1 < dataSize; + if (isEOC(data, dataPos)) { + dataPos += 2; // skip tag and length + } else { + newData[newDataPos++] = data[dataPos++]; + break; + } } }
diff --git a/src/java.base/share/classes/sun/security/util/DerValue.java b/src/java.base/share/classes/sun/security/util/DerValue.java index 4756da5..64dcf2c 100644 --- a/src/java.base/share/classes/sun/security/util/DerValue.java +++ b/src/java.base/share/classes/sun/security/util/DerValue.java
@@ -306,6 +306,34 @@ } /** + * Wraps a byte array as a single DerValue. + * + * Attention: no cloning is made. + * + * @param buf the byte array containing the DER-encoded datum + * @returns a new DerValue + */ + public static DerValue wrap(byte[] buf) + throws IOException { + return wrap(buf, 0, buf.length); + } + + /** + * Wraps a byte array as a single DerValue. + * + * Attention: no cloning is made. + * + * @param buf the byte array containing the DER-encoded datum + * @param offset where the encoded datum starts inside {@code buf} + * @param len length of bytes to parse inside {@code buf} + * @returns a new DerValue + */ + public static DerValue wrap(byte[] buf, int offset, int len) + throws IOException { + return new DerValue(buf, offset, len); + } + + /** * Get an ASN.1/DER encoded datum from part of a buffer. * That part of the buffer must hold exactly one datum, including * its tag and length.
diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java new file mode 100644 index 0000000..92ecb9a --- /dev/null +++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java
@@ -0,0 +1,499 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.util; + +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +/** + * This utility class maps algorithm name to the corresponding oid strings. + * NOTE: for 100% backward compatibility, the standard name for the enum + * is determined by existing usage and may be in lowercase/uppercase in + * order to match existing output. + */ +public enum KnownOIDs { + + // X.500 Attributes 2.5.4.* + CommonName("2.5.4.3"), + Surname("2.5.4.4"), + SerialNumber("2.5.4.5"), + CountryName("2.5.4.6"), + LocalityName("2.5.4.7"), + StateName("2.5.4.8"), + StreetAddress("2.5.4.9"), + OrgName("2.5.4.10"), + OrgUnitName("2.5.4.11"), + Title("2.5.4.12"), + GivenName("2.5.4.42"), + Initials("2.5.4.43"), + GenerationQualifier("2.5.4.44"), + DNQualifier("2.5.4.46"), + + // Certificate Extension 2.5.29.* + SubjectDirectoryAttributes("2.5.29.9"), + SubjectKeyID("2.5.29.14"), + KeyUsage("2.5.29.15"), + PrivateKeyUsage("2.5.29.16"), + SubjectAlternativeName("2.5.29.17"), + IssuerAlternativeName("2.5.29.18"), + BasicConstraints("2.5.29.19"), + CRLNumber("2.5.29.20"), + ReasonCode("2.5.29.21"), + HoldInstructionCode("2.5.29.23"), + InvalidityDate("2.5.29.24"), + DeltaCRLIndicator("2.5.29.27"), + IssuingDistributionPoint("2.5.29.28"), + CertificateIssuer("2.5.29.29"), + NameConstraints("2.5.29.30"), + CRLDistributionPoints("2.5.29.31"), + CertificatePolicies("2.5.29.32"), + CE_CERT_POLICIES_ANY("2.5.29.32.0"), + PolicyMappings("2.5.29.33"), + AuthorityKeyID("2.5.29.35"), + PolicyConstraints("2.5.29.36"), + extendedKeyUsage("2.5.29.37"), + anyExtendedKeyUsage("2.5.29.37.0"), + FreshestCRL("2.5.29.46"), + InhibitAnyPolicy("2.5.29.54"), + + // PKIX 1.3.6.1.5.5.7. + AuthInfoAccess("1.3.6.1.5.5.7.1.1"), + SubjectInfoAccess("1.3.6.1.5.5.7.1.11"), + // key usage purposes - PKIX.3.* + serverAuth("1.3.6.1.5.5.7.3.1"), + clientAuth("1.3.6.1.5.5.7.3.2"), + codeSigning("1.3.6.1.5.5.7.3.3"), + emailProtection("1.3.6.1.5.5.7.3.4"), + ipsecEndSystem("1.3.6.1.5.5.7.3.5"), + ipsecTunnel("1.3.6.1.5.5.7.3.6"), + ipsecUser("1.3.6.1.5.5.7.3.7"), + KP_TimeStamping("1.3.6.1.5.5.7.3.8", "timeStamping") { + @Override + boolean registerNames() { return false; } + }, + OCSPSigning("1.3.6.1.5.5.7.3.9"), + // access descriptors - PKIX.48.* + OCSP("1.3.6.1.5.5.7.48.1"), + OCSPBasicResponse("1.3.6.1.5.5.7.48.1.1"), + OCSPNonceExt("1.3.6.1.5.5.7.48.1.2"), + OCSPNoCheck("1.3.6.1.5.5.7.48.1.5"), + caIssuers("1.3.6.1.5.5.7.48.2"), + AD_TimeStamping("1.3.6.1.5.5.7.48.3", "timeStamping") { + @Override + boolean registerNames() { return false; } + }, + caRepository("1.3.6.1.5.5.7.48.5", "caRepository"), + + // NIST -- + // AES 2.16.840.1.101.3.4.1.* + AES("2.16.840.1.101.3.4.1"), + AES_128$ECB$NoPadding("2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding"), + AES_128$CBC$NoPadding("2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding"), + AES_128$OFB$NoPadding("2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding"), + AES_128$CFB$NoPadding("2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding"), + AESWRAP_128("2.16.840.1.101.3.4.1.5"), + AES_128$GCM$NoPadding("2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding"), + AES_192$ECB$NoPadding("2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding"), + AES_192$CBC$NoPadding("2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding"), + AES_192$OFB$NoPadding("2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding"), + AES_192$CFB$NoPadding("2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding"), + AESWRAP_192("2.16.840.1.101.3.4.1.25"), + AES_192$GCM$NoPadding("2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding"), + AES_256$ECB$NoPadding("2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding"), + AES_256$CBC$NoPadding("2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding"), + AES_256$OFB$NoPadding("2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding"), + AES_256$CFB$NoPadding("2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding"), + AESWRAP_256("2.16.840.1.101.3.4.1.45"), + AES_256$GCM$NoPadding("2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding"), + + // hashAlgs 2.16.840.1.101.3.4.2.* + SHA_256("2.16.840.1.101.3.4.2.1", "SHA-256", "SHA256"), + SHA_384("2.16.840.1.101.3.4.2.2", "SHA-384", "SHA384"), + SHA_512("2.16.840.1.101.3.4.2.3", "SHA-512", "SHA512"), + SHA_224("2.16.840.1.101.3.4.2.4", "SHA-224", "SHA224"), + SHA_512$224("2.16.840.1.101.3.4.2.5", "SHA-512/224", "SHA512/224"), + SHA_512$256("2.16.840.1.101.3.4.2.6", "SHA-512/256", "SHA512/256"), + SHA3_224("2.16.840.1.101.3.4.2.7", "SHA3-224"), + SHA3_256("2.16.840.1.101.3.4.2.8", "SHA3-256"), + SHA3_384("2.16.840.1.101.3.4.2.9", "SHA3-384"), + SHA3_512("2.16.840.1.101.3.4.2.10", "SHA3-512"), + SHAKE128("2.16.840.1.101.3.4.2.11"), + SHAKE256("2.16.840.1.101.3.4.2.12"), + HmacSHA3_224("2.16.840.1.101.3.4.2.13", "HmacSHA3-224"), + HmacSHA3_256("2.16.840.1.101.3.4.2.14", "HmacSHA3-256"), + HmacSHA3_384("2.16.840.1.101.3.4.2.15", "HmacSHA3-384"), + HmacSHA3_512("2.16.840.1.101.3.4.2.16", "HmacSHA3-512"), + + // sigAlgs 2.16.840.1.101.3.4.3.* + SHA224withDSA("2.16.840.1.101.3.4.3.1"), + SHA256withDSA("2.16.840.1.101.3.4.3.2"), + SHA384withDSA("2.16.840.1.101.3.4.3.3"), + SHA512withDSA("2.16.840.1.101.3.4.3.4"), + SHA3_224withRSA("2.16.840.1.101.3.4.3.13", "SHA3-224withRSA"), + SHA3_256withRSA("2.16.840.1.101.3.4.3.14", "SHA3-256withRSA"), + SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"), + SHA3_512withRSA("2.16.840.1.101.3.4.3.16", "SHA3-512withRSA"), + + // RSASecurity + // PKCS1 1.2.840.113549.1.1.* + PKCS1("1.2.840.113549.1.1", "RSA") { // RSA KeyPairGenerator and KeyFactory + @Override + boolean registerNames() { return false; } + }, + RSA("1.2.840.113549.1.1.1"), // RSA encryption + + MD2withRSA("1.2.840.113549.1.1.2"), + MD5withRSA("1.2.840.113549.1.1.4"), + SHA1withRSA("1.2.840.113549.1.1.5"), + OAEP("1.2.840.113549.1.1.7"), + MGF1("1.2.840.113549.1.1.8"), + PSpecified("1.2.840.113549.1.1.9"), + RSASSA_PSS("1.2.840.113549.1.1.10", "RSASSA-PSS"), + SHA256withRSA("1.2.840.113549.1.1.11"), + SHA384withRSA("1.2.840.113549.1.1.12"), + SHA512withRSA("1.2.840.113549.1.1.13"), + SHA224withRSA("1.2.840.113549.1.1.14"), + SHA512$224withRSA("1.2.840.113549.1.1.15", "SHA512/224withRSA"), + SHA512$256withRSA("1.2.840.113549.1.1.16", "SHA512/256withRSA"), + + // PKCS3 1.2.840.113549.1.3.* + DiffieHellman("1.2.840.113549.1.3.1", "DiffieHellman", "DH"), + + // PKCS5 1.2.840.113549.1.5.* + PBEWithMD5AndDES("1.2.840.113549.1.5.3"), + PBEWithMD5AndRC2("1.2.840.113549.1.5.6"), + PBEWithSHA1AndDES("1.2.840.113549.1.5.10"), + PBEWithSHA1AndRC2("1.2.840.113549.1.5.11"), + PBKDF2WithHmacSHA1("1.2.840.113549.1.5.12"), + PBES2("1.2.840.113549.1.5.13"), + + // PKCS7 1.2.840.113549.1.7.* + PKCS7("1.2.840.113549.1.7"), + Data("1.2.840.113549.1.7.1"), + SignedData("1.2.840.113549.1.7.2"), + JDK_OLD_Data("1.2.840.1113549.1.7.1"), // extra 1 in 4th component + JDK_OLD_SignedData("1.2.840.1113549.1.7.2"), + EnvelopedData("1.2.840.113549.1.7.3"), + SignedAndEnvelopedData("1.2.840.113549.1.7.4"), + DigestedData("1.2.840.113549.1.7.5"), + EncryptedData("1.2.840.113549.1.7.6"), + + // PKCS9 1.2.840.113549.1.9.* + EmailAddress("1.2.840.113549.1.9.1"), + UnstructuredName("1.2.840.113549.1.9.2"), + ContentType("1.2.840.113549.1.9.3"), + MessageDigest("1.2.840.113549.1.9.4"), + SigningTime("1.2.840.113549.1.9.5"), + CounterSignature("1.2.840.113549.1.9.6"), + ChallengePassword("1.2.840.113549.1.9.7"), + UnstructuredAddress("1.2.840.113549.1.9.8"), + ExtendedCertificateAttributes("1.2.840.113549.1.9.9"), + IssuerAndSerialNumber("1.2.840.113549.1.9.10"), + ExtensionRequest("1.2.840.113549.1.9.14"), + SMIMECapability("1.2.840.113549.1.9.15"), + TimeStampTokenInfo("1.2.840.113549.1.9.16.1.4"), + SigningCertificate("1.2.840.113549.1.9.16.2.12"), + SignatureTimestampToken("1.2.840.113549.1.9.16.2.14"), + CHACHA20_POLY1305("1.2.840.113549.1.9.16.3.18", "CHACHA20-POLY1305"), + FriendlyName("1.2.840.113549.1.9.20"), + LocalKeyID("1.2.840.113549.1.9.21"), + CertTypeX509("1.2.840.113549.1.9.22.1"), + + // PKCS12 1.2.840.113549.1.12.* + PBEWithSHA1AndRC4_128("1.2.840.113549.1.12.1.1"), + PBEWithSHA1AndRC4_40("1.2.840.113549.1.12.1.2"), + PBEWithSHA1AndDESede("1.2.840.113549.1.12.1.3"), + PBEWithSHA1AndRC2_128("1.2.840.113549.1.12.1.5"), + PBEWithSHA1AndRC2_40("1.2.840.113549.1.12.1.6"), + PKCS8ShroudedKeyBag("1.2.840.113549.1.12.10.1.2"), + CertBag("1.2.840.113549.1.12.10.1.3"), + SecretBag("1.2.840.113549.1.12.10.1.5"), + + // digestAlgs 1.2.840.113549.2.* + MD2("1.2.840.113549.2.2"), + MD5("1.2.840.113549.2.5"), + HmacSHA1("1.2.840.113549.2.7"), + HmacSHA224("1.2.840.113549.2.8"), + HmacSHA256("1.2.840.113549.2.9"), + HmacSHA384("1.2.840.113549.2.10"), + HmacSHA512("1.2.840.113549.2.11"), + HmacSHA512$224("1.2.840.113549.2.12", "HmacSHA512/224"), + HmacSHA512$256("1.2.840.113549.2.13", "HmacSHA512/256"), + + // encryptionAlgs 1.2.840.113549.3.* + RC2$CBC$PKCS5Padding("1.2.840.113549.3.2", "RC2/CBC/PKCS5Padding"), + ARCFOUR("1.2.840.113549.3.4", "ARCFOUR", "RC4"), + DESede$CBC$NoPadding("1.2.840.113549.3.7", "DESede/CBC/NoPadding"), + RC5$CBC$PKCS5Padding("1.2.840.113549.3.9", "RC5/CBC/PKCS5Padding"), + + // ANSI -- + // X9 1.2.840.10040.4.* + DSA("1.2.840.10040.4.1"), + SHA1withDSA("1.2.840.10040.4.3", "SHA1withDSA", "DSS"), + // X9.62 1.2.840.10045.* + EC("1.2.840.10045.2.1"), + + //c2pnb163v1("1.2.840.10045.3.0.1", "X9.62 c2pnb163v1"), + //c2pnb163v2("1.2.840.10045.3.0.2", "X9.62 c2pnb163v2"), + //c2pnb163v3("1.2.840.10045.3.0.3", "X9.62 c2pnb163v3"), + //c2pnb176w1("1.2.840.10045.3.0.4", "X9.62 c2pnb176w1"), + c2tnb191v1("1.2.840.10045.3.0.5", "X9.62 c2tnb191v1"), + c2tnb191v2("1.2.840.10045.3.0.6", "X9.62 c2tnb191v2"), + c2tnb191v3("1.2.840.10045.3.0.7", "X9.62 c2tnb191v3"), + //c2pnb208w1("1.2.840.10045.3.0.10", "X9.62 c2pnb208w1"), + c2tnb239v1("1.2.840.10045.3.0.11", "X9.62 c2tnb239v1"), + c2tnb239v2("1.2.840.10045.3.0.12", "X9.62 c2tnb239v2"), + c2tnb239v3("1.2.840.10045.3.0.13", "X9.62 c2tnb239v3"), + //c2pnb272w1("1.2.840.10045.3.0.16", "X9.62 c2pnb272w1"), + //c2pnb304w1("1.2.840.10045.3.0.17", "X9.62 c2pnb304w1"), + c2tnb359v1("1.2.840.10045.3.0.18", "X9.62 c2tnb359v1"), + //c2pnb368w1("1.2.840.10045.3.0.19", "X9.62 c2pnb368w1"), + c2tnb431r1("1.2.840.10045.3.0.20", "X9.62 c2tnb431r1"), + + secp192r1("1.2.840.10045.3.1.1", + "secp192r1", "NIST P-192", "X9.62 prime192v1"), + prime192v2("1.2.840.10045.3.1.2", "X9.62 prime192v2"), + prime192v3("1.2.840.10045.3.1.3", "X9.62 prime192v3"), + prime239v1("1.2.840.10045.3.1.4", "X9.62 prime239v1"), + prime239v2("1.2.840.10045.3.1.5", "X9.62 prime239v2"), + prime239v3("1.2.840.10045.3.1.6", "X9.62 prime239v3"), + secp256r1("1.2.840.10045.3.1.7", + "secp256r1", "NIST P-256", "X9.62 prime256v1"), + SHA1withECDSA("1.2.840.10045.4.1"), + SHA224withECDSA("1.2.840.10045.4.3.1"), + SHA256withECDSA("1.2.840.10045.4.3.2"), + SHA384withECDSA("1.2.840.10045.4.3.3"), + SHA512withECDSA("1.2.840.10045.4.3.4"), + SpecifiedSHA2withECDSA("1.2.840.10045.4.3"), + + // X9.42 1.2.840.10046.2.* + X942_DH("1.2.840.10046.2.1", "DiffieHellman") { // unused by JDK providers + @Override + boolean registerNames() { return false; } + }, + + // Teletrust 1.3.36.* + brainpoolP160r1("1.3.36.3.3.2.8.1.1.1"), + brainpoolP192r1("1.3.36.3.3.2.8.1.1.3"), + brainpoolP224r1("1.3.36.3.3.2.8.1.1.5"), + brainpoolP256r1("1.3.36.3.3.2.8.1.1.7"), + brainpoolP320r1("1.3.36.3.3.2.8.1.1.9"), + brainpoolP384r1("1.3.36.3.3.2.8.1.1.11"), + brainpoolP512r1("1.3.36.3.3.2.8.1.1.13"), + + // Certicom 1.3.132.* + sect163k1("1.3.132.0.1", "sect163k1", "NIST K-163"), + sect163r1("1.3.132.0.2"), + sect239k1("1.3.132.0.3"), + sect113r1("1.3.132.0.4"), + sect113r2("1.3.132.0.5"), + secp112r1("1.3.132.0.6"), + secp112r2("1.3.132.0.7"), + secp160r1("1.3.132.0.8"), + secp160k1("1.3.132.0.9"), + secp256k1("1.3.132.0.10"), + sect163r2("1.3.132.0.15", "sect163r2", "NIST B-163"), + sect283k1("1.3.132.0.16", "sect283k1", "NIST K-283"), + sect283r1("1.3.132.0.17", "sect283r1", "NIST B-283"), + + sect131r1("1.3.132.0.22"), + sect131r2("1.3.132.0.23"), + sect193r1("1.3.132.0.24"), + sect193r2("1.3.132.0.25"), + sect233k1("1.3.132.0.26", "sect233k1", "NIST K-233"), + sect233r1("1.3.132.0.27", "sect233r1", "NIST B-233"), + secp128r1("1.3.132.0.28"), + secp128r2("1.3.132.0.29"), + secp160r2("1.3.132.0.30"), + secp192k1("1.3.132.0.31"), + secp224k1("1.3.132.0.32"), + secp224r1("1.3.132.0.33", "secp224r1", "NIST P-224"), + secp384r1("1.3.132.0.34", "secp384r1", "NIST P-384"), + secp521r1("1.3.132.0.35", "secp521r1", "NIST P-521"), + sect409k1("1.3.132.0.36", "sect409k1", "NIST K-409"), + sect409r1("1.3.132.0.37", "sect409r1", "NIST B-409"), + sect571k1("1.3.132.0.38", "sect571k1", "NIST K-571"), + sect571r1("1.3.132.0.39", "sect571r1", "NIST B-571"), + + ECDH("1.3.132.1.12"), + + // OIW secsig 1.3.14.3.* + OIW_DES_CBC("1.3.14.3.2.7", "DES/CBC"), + + OIW_DSA("1.3.14.3.2.12", "DSA") { + @Override + boolean registerNames() { return false; } + }, + + OIW_JDK_SHA1withDSA("1.3.14.3.2.13", "SHA1withDSA") { + @Override + boolean registerNames() { return false; } + }, + + SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"), + + OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") { + @Override + boolean registerNames() { return false; } + }, + + OIW_SHA1withRSA("1.3.14.3.2.29", "SHA1withRSA") { + @Override + boolean registerNames() { return false; } + }, + + // Thawte 1.3.101.* + X25519("1.3.101.110"), + X448("1.3.101.111"), + Ed25519("1.3.101.112"), + Ed448("1.3.101.113"), + + // University College London (UCL) 0.9.2342.19200300.* + UCL_UserID("0.9.2342.19200300.100.1.1"), + UCL_DomainComponent("0.9.2342.19200300.100.1.25"), + + // Netscape 2.16.840.1.113730.* + NETSCAPE_CertType("2.16.840.1.113730.1.1"), + NETSCAPE_CertSequence("2.16.840.1.113730.2.5"), + NETSCAPE_ExportApproved("2.16.840.1.113730.4.1"), + + // Oracle 2.16.840.1.113894.* + ORACLE_TrustedKeyUsage("2.16.840.1.113894.746875.1.1"), + + // Miscellaneous oids below which are legacy, and not well known + // Consider removing them in future releases when their usage + // have died out + + ITUX509_RSA("2.5.8.1.1", "RSA") { // unused by JDK providers + // defined in X.509 for RSA keys + @Override // with modulus length as its parameter + boolean registerNames() { return false; } + }, + + SkipIPAddress("1.3.6.1.4.1.42.2.11.2.1"), + JAVASOFT_JDKKeyProtector("1.3.6.1.4.1.42.2.17.1.1"), + JAVASOFT_JCEKeyProtector("1.3.6.1.4.1.42.2.19.1"), + MICROSOFT_ExportApproved("1.3.6.1.4.1.311.10.3.3"); + + private String stdName; + private String oid; + private String[] aliases; + + // find the matching enum using either name or oid string + // return null if no match found + public static KnownOIDs findMatch(String s) { + s = s.toUpperCase(Locale.ENGLISH); + KnownOIDs res = name2enum.get(s); + if (res == null && debug != null) { + debug.println("No KnownOIDs enum found for " + s); + } + return res; + } + + private static final Debug debug = Debug.getInstance("jca"); + //private static final java.io.PrintStream debug = System.out; + private static final ConcurrentHashMap<String, KnownOIDs> name2enum = + new ConcurrentHashMap<>(); + + static { + if (debug != null) { + debug.println("Setting up name2enum:"); + } + List.of(KnownOIDs.values()).forEach(new Consumer<KnownOIDs>() { + @Override + public void accept(KnownOIDs o) { + register(o); + } + }); + } + + private static void register(KnownOIDs o) { + KnownOIDs ov = name2enum.put(o.oid, o); + if (ov != null) { + throw new RuntimeException("ERROR: Duplicate " + o.oid + + " between " + o + " and " + ov); + } else if (debug != null) { + debug.println(o.oid + " => " + o.name()); + } + // only register the stdName and aliases if o.registerNames() + // returns true + if (o.registerNames()) { + String stdNameUpper = o.stdName.toUpperCase(Locale.ENGLISH); + if (Objects.nonNull(name2enum.put(stdNameUpper, o))) { + throw new RuntimeException("ERROR: Duplicate " + + stdNameUpper + " exists already"); + } + if (debug != null) { + debug.println(stdNameUpper + " => " + o.name()); + } + + for (String a : o.aliases) { + String aliasUpper = a.toUpperCase(Locale.ENGLISH); + if (Objects.nonNull(name2enum.put(aliasUpper, o))) { + throw new RuntimeException("ERROR: Duplicate " + + aliasUpper + " exists already"); + } + if (debug != null) { + debug.println(aliasUpper + " => " + o.name()); + } + } + } + } + + private KnownOIDs(String oid) { + this.oid = oid; + this.stdName = name(); // defaults to enum name + this.aliases = new String[0]; + } + + private KnownOIDs(String oid, String stdName, String ... aliases) { + this.oid = oid; + this.stdName = stdName; + this.aliases = aliases; + } + + // returns the oid string associated with this enum + public String value() { + return oid; + } + + // returns the user-friendly standard algorithm name + public String stdName() { + return stdName; + } + + // return the internal aliases + public String[] aliases() { + return aliases; + } + + boolean registerNames() { + return true; + } +}
diff --git a/src/java.base/share/classes/sun/security/util/ManifestDigester.java b/src/java.base/share/classes/sun/security/util/ManifestDigester.java index aeff45b..3920d8a 100644 --- a/src/java.base/share/classes/sun/security/util/ManifestDigester.java +++ b/src/java.base/share/classes/sun/security/util/ManifestDigester.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,12 @@ package sun.security.util; -import java.security.*; +import java.security.MessageDigest; import java.util.ArrayList; import java.util.HashMap; import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.IOException; import java.util.List; import static java.nio.charset.StandardCharsets.UTF_8; @@ -40,13 +42,27 @@ */ public class ManifestDigester { + /** + * The part "{@code Manifest-Main-Attributes}" of the main attributes + * digest header name in a signature file as described in the jar + * specification: + * <blockquote>{@code x-Digest-Manifest-Main-Attributes} + * (where x is the standard name of a {@link MessageDigest} algorithm): + * The value of this attribute is the digest value of the main attributes + * of the manifest.</blockquote> + * @see <a href="{@docRoot}/../specs/jar/jar.html#signature-file"> + * JAR File Specification, section Signature File</a> + * @see #getMainAttsEntry + */ public static final String MF_MAIN_ATTRS = "Manifest-Main-Attributes"; /** the raw bytes of the manifest */ - private byte[] rawBytes; + private final byte[] rawBytes; - /** the entries grouped by names */ - private HashMap<String, Entry> entries; // key is a UTF-8 string + private final Entry mainAttsEntry; + + /** individual sections by their names */ + private final HashMap<String, Entry> entries = new HashMap<>(); /** state returned by findSection */ static class Position { @@ -72,29 +88,31 @@ private boolean findSection(int offset, Position pos) { int i = offset, len = rawBytes.length; - int last = offset; + int last = offset - 1; int next; boolean allBlank = true; - pos.endOfFirstLine = -1; + /* denotes that a position is not yet assigned. + * As a primitive type int it cannot be null + * and -1 would be confused with (i - 1) when i == 0 */ + final int UNASSIGNED = Integer.MIN_VALUE; + + pos.endOfFirstLine = UNASSIGNED; while (i < len) { byte b = rawBytes[i]; switch(b) { case '\r': - if (pos.endOfFirstLine == -1) + if (pos.endOfFirstLine == UNASSIGNED) pos.endOfFirstLine = i-1; - if ((i < len) && (rawBytes[i+1] == '\n')) + if (i < len - 1 && rawBytes[i + 1] == '\n') i++; /* fall through */ case '\n': - if (pos.endOfFirstLine == -1) + if (pos.endOfFirstLine == UNASSIGNED) pos.endOfFirstLine = i-1; if (allBlank || (i == len-1)) { - if (i == len-1) - pos.endOfSection = i; - else - pos.endOfSection = last; + pos.endOfSection = allBlank ? last : i; pos.startOfNext = i+1; return true; } @@ -116,16 +134,17 @@ public ManifestDigester(byte[] bytes) { rawBytes = bytes; - entries = new HashMap<>(); Position pos = new Position(); - if (!findSection(0, pos)) + if (!findSection(0, pos)) { + mainAttsEntry = null; return; // XXX: exception? + } // create an entry for main attributes - entries.put(MF_MAIN_ATTRS, new Entry().addSection( - new Section(0, pos.endOfSection + 1, pos.startOfNext, rawBytes))); + mainAttsEntry = new Entry().addSection(new Section( + 0, pos.endOfSection + 1, pos.startOfNext, rawBytes)); int start = pos.startOfNext; while(findSection(start, pos)) { @@ -133,14 +152,16 @@ int sectionLen = pos.endOfSection-start+1; int sectionLenWithBlank = pos.startOfNext-start; - if (len > 6) { + if (len >= 6) { // 6 == "Name: ".length() if (isNameAttr(bytes, start)) { ByteArrayOutputStream nameBuf = new ByteArrayOutputStream(); nameBuf.write(bytes, start+6, len-6); int i = start + len; if ((i-start) < sectionLen) { - if (bytes[i] == '\r') { + if (bytes[i] == '\r' + && i + 1 - start < sectionLen + && bytes[i + 1] == '\n') { i += 2; } else { i += 1; @@ -152,14 +173,16 @@ // name is wrapped int wrapStart = i; while (((i-start) < sectionLen) - && (bytes[i++] != '\n')); - if (bytes[i-1] != '\n') - return; // XXX: exception? - int wrapLen; - if (bytes[i-2] == '\r') - wrapLen = i-wrapStart-2; - else - wrapLen = i-wrapStart-1; + && (bytes[i] != '\r') + && (bytes[i] != '\n')) i++; + int wrapLen = i - wrapStart; + if (i - start < sectionLen) { + i++; + if (bytes[i - 1] == '\r' + && i - start < sectionLen + && bytes[i] == '\n') + i++; + } nameBuf.write(bytes, wrapStart, wrapLen); } else { @@ -167,7 +190,7 @@ } } - entries.computeIfAbsent(new String(nameBuf.toByteArray(), UTF_8), + entries.computeIfAbsent(nameBuf.toString(UTF_8), dummy -> new Entry()) .addSection(new Section(start, sectionLen, sectionLenWithBlank, rawBytes)); @@ -202,6 +225,26 @@ return this; } + /** + * Check if the sections (particularly the last one of usually only one) + * are properly delimited with a trailing blank line so that another + * section can be correctly appended and return {@code true} or return + * {@code false} to indicate that reproduction is not advised and should + * be carried out with a clean "normalized" newly-written manifest. + * + * @see #reproduceRaw + */ + public boolean isProperlyDelimited() { + return sections.stream().allMatch( + Section::isProperlySectionDelimited); + } + + public void reproduceRaw(OutputStream out) throws IOException { + for (Section sec : sections) { + out.write(sec.rawBytes, sec.offset, sec.lengthWithBlankLine); + } + } + public byte[] digest(MessageDigest md) { md.reset(); @@ -242,6 +285,15 @@ this.rawBytes = rawBytes; } + /** + * Returns {@code true} if the raw section is terminated with a blank + * line so that another section can possibly be appended resulting in a + * valid manifest and {@code false} otherwise. + */ + private boolean isProperlySectionDelimited() { + return lengthWithBlankLine > length; + } + private static void doOldStyle(MessageDigest md, byte[] bytes, int offset, @@ -268,10 +320,33 @@ } } + /** + * @see #MF_MAIN_ATTRS + */ + public Entry getMainAttsEntry() { + return mainAttsEntry; + } + + /** + * @see #MF_MAIN_ATTRS + */ + public Entry getMainAttsEntry(boolean oldStyle) { + mainAttsEntry.oldStyle = oldStyle; + return mainAttsEntry; + } + + public Entry get(String name) { + return entries.get(name); + } + public Entry get(String name, boolean oldStyle) { - Entry e = entries.get(name); - if (e != null) + Entry e = get(name); + if (e == null && MF_MAIN_ATTRS.equals(name)) { + e = getMainAttsEntry(); + } + if (e != null) { e.oldStyle = oldStyle; + } return e; }
diff --git a/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java b/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java index ba59ff1..ad8d3e7 100644 --- a/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java +++ b/src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java
@@ -63,7 +63,9 @@ ArrayList<byte[]> manifestHashes; private String name = null; - private Manifest man; + + private final String manifestFileName; // never null + private final Manifest man; private boolean skip = true; @@ -74,11 +76,12 @@ /** * Create a new ManifestEntryVerifier object. */ - public ManifestEntryVerifier(Manifest man) + public ManifestEntryVerifier(Manifest man, String manifestFileName) { createdDigests = new HashMap<>(11); digests = new ArrayList<>(); manifestHashes = new ArrayList<>(); + this.manifestFileName = manifestFileName; this.man = man; } @@ -187,7 +190,6 @@ * the first time we have verified this object, remove its * code signers from sigFileSigners and place in verifiedSigners. * - * */ public CodeSigner[] verify(Hashtable<String, CodeSigner[]> verifiedSigners, Hashtable<String, CodeSigner[]> sigFileSigners) @@ -209,7 +211,6 @@ getParams(verifiedSigners, sigFileSigners); for (int i=0; i < digests.size(); i++) { - MessageDigest digest = digests.get(i); if (params != null) { try { @@ -251,7 +252,8 @@ /** * Get constraints parameters for JAR. The constraints should be * checked against all code signers. Returns the parameters, - * or null if the signers for this entry have already been checked. + * or null if the signers for this entry have already been checked + * or there are no signers for this entry. */ private JarConstraintsParameters getParams( Map<String, CodeSigner[]> verifiedSigners, @@ -262,17 +264,20 @@ // the signers of the JAR. But if it doesn't then we need to fallback // and check verifiedSigners to see if the signers of this entry have // been checked already. - if (verifiedSigners.containsKey(JarFile.MANIFEST_NAME)) { + if (verifiedSigners.containsKey(manifestFileName)) { if (verifiedSigners.size() > 1) { // this means we already checked it previously return null; } else { return new JarConstraintsParameters( - verifiedSigners.get(JarFile.MANIFEST_NAME)); + verifiedSigners.get(manifestFileName)); } } else { + if (debug != null) { + debug.println(manifestFileName + " not present in verifiedSigners"); + } CodeSigner[] signers = sigFileSigners.get(name); - if (verifiedSigners.containsValue(signers)) { + if (signers == null || verifiedSigners.containsValue(signers)) { return null; } else { return new JarConstraintsParameters(signers);
diff --git a/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java b/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java index 00ab476..b74d84e 100644 --- a/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java +++ b/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.io.*; import java.math.BigInteger; import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; /** * Represent an ISO Object Identifier. @@ -356,6 +357,39 @@ } } + // oid cache index'ed by the oid string + private static ConcurrentHashMap<String,ObjectIdentifier> oidTable = + new ConcurrentHashMap<>(); + + public static ObjectIdentifier of(String oidStr) throws IOException { + // check cache first + ObjectIdentifier oid = oidTable.get(oidStr); + if (oid == null) { + oid = new ObjectIdentifier(oidStr); + oidTable.put(oidStr, oid); + } + return oid; + } + + /** + * Returns an ObjectIdentifier instance for the specific KnownOIDs. + */ + public static ObjectIdentifier of(KnownOIDs o) { + // check cache first + String oidStr = o.value(); + ObjectIdentifier oid = oidTable.get(oidStr); + if (oid == null) { + try { + oid = new ObjectIdentifier(oidStr); + } catch (IOException ioe) { + // should not happen as oid string for KnownOIDs is internal + throw new RuntimeException(ioe); + } + oidTable.put(oidStr, oid); + } + return oid; + } + /* * n.b. the only public interface is DerOutputStream.putOID() */ @@ -401,7 +435,7 @@ if ((encoding[i] & 0x80) == 0) { // one section [fromPos..i] if (i - fromPos + 1 > 4) { - BigInteger big = new BigInteger(pack(encoding, fromPos, i-fromPos+1, 7, 8)); + BigInteger big = new BigInteger(1, pack(encoding, fromPos, i-fromPos+1, 7, 8)); if (fromPos == 0) { result[which++] = 2; BigInteger second = big.subtract(BigInteger.valueOf(80)); @@ -466,7 +500,7 @@ sb.append('.'); } if (i - fromPos + 1 > 4) { // maybe big integer - BigInteger big = new BigInteger(pack(encoding, fromPos, i-fromPos+1, 7, 8)); + BigInteger big = new BigInteger(1, pack(encoding, fromPos, i-fromPos+1, 7, 8)); if (fromPos == 0) { // first section encoded with more than 4 bytes, // must be 2.something @@ -698,6 +732,11 @@ } private static void checkOidSize(int oidLength) throws IOException { + if (oidLength < 0) { + throw new IOException("ObjectIdentifier encoded length was " + + "negative: " + oidLength); + } + if (oidLength > MAXIMUM_OID_SIZE) { throw new IOException( "ObjectIdentifier encoded length exceeds " +
diff --git a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java index e3ad488..524c03f 100644 --- a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java +++ b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java
@@ -62,8 +62,7 @@ private ArrayList<CodeSigner[]> signerCache; private static final String ATTR_DIGEST = - ("-DIGEST-" + ManifestDigester.MF_MAIN_ATTRS).toUpperCase - (Locale.ENGLISH); + "-DIGEST-" + ManifestDigester.MF_MAIN_ATTRS.toUpperCase(Locale.ENGLISH); /** the PKCS7 block for this .DSA/.RSA/.EC file */ private PKCS7 block; @@ -519,8 +518,7 @@ MessageDigest digest = getDigest(algorithm); if (digest != null) { - ManifestDigester.Entry mde = - md.get(ManifestDigester.MF_MAIN_ATTRS, false); + ManifestDigester.Entry mde = md.getMainAttsEntry(false); if (mde == null) { throw new SignatureException("Manifest Main Attribute check " + "failed due to missing main attributes entry");
diff --git a/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java b/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java index bc59a92..1e975e5 100644 --- a/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java +++ b/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,12 +55,12 @@ @Override public Void run() { File f = new File(StaticProperty.javaHome(), - "lib/security/blacklisted.certs"); + "lib/security/blocked.certs"); try (FileInputStream fin = new FileInputStream(f)) { props.load(fin); } catch (IOException fnfe) { if (debug != null) { - debug.println("Error parsing blacklisted.certs"); + debug.println("Error parsing blocked.certs"); } } return null;
diff --git a/src/java.base/share/classes/sun/util/calendar/BaseCalendar.java b/src/java.base/share/classes/sun/util/calendar/BaseCalendar.java index 3c07431..8a7ffc6 100644 --- a/src/java.base/share/classes/sun/util/calendar/BaseCalendar.java +++ b/src/java.base/share/classes/sun/util/calendar/BaseCalendar.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -277,6 +277,10 @@ long xm = 1L - month; year -= (int)((xm / 12) + 1); month = 13 - (xm % 12); + if (month == 13) { + year++; + month = 1; + } bdate.setNormalizedYear(year); bdate.setMonth((int) month); } else if (month > DECEMBER) {
diff --git a/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java b/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java index 71c7212..91a689f 100644 --- a/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java +++ b/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,9 @@ } } - private static final Gregorian GREGORIAN_INSTANCE = new Gregorian(); + private static final class GregorianHolder { + private static final Gregorian GREGORIAN_INSTANCE = new Gregorian(); + } /** * Returns the singleton instance of the <code>Gregorian</code> @@ -120,7 +122,7 @@ * @return the <code>Gregorian</code> instance */ public static Gregorian getGregorianCalendar() { - return GREGORIAN_INSTANCE; + return GregorianHolder.GREGORIAN_INSTANCE; } /** @@ -135,7 +137,7 @@ */ public static CalendarSystem forName(String calendarName) { if ("gregorian".equals(calendarName)) { - return GREGORIAN_INSTANCE; + return GregorianHolder.GREGORIAN_INSTANCE; } if (!initialized) {
diff --git a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java index 505024b..bfe0dd3 100644 --- a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java +++ b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java
@@ -569,7 +569,7 @@ // ZoneRulesBuilder adjusts < 0 case (-1, for last, don't have // "<=" case yet) to positive value if not February (it appears // we don't have February cutoff in tzdata table yet) - // Ideally, if JSR310 can just pass in the nagative and + // Ideally, if JSR310 can just pass in the negative and // we can then pass in the dom = -1, dow > 0 into ZoneInfo // // hacking, assume the >=24 is the result of ZRB optimization for @@ -600,9 +600,8 @@ params[7] = 0; } else { // hacking: see comment above - if (dom < 0 || dom >= 24 && - !(zoneId.equals("Asia/Gaza") || - zoneId.equals("Asia/Hebron"))) { + // No need of hacking for Asia/Gaza and Asia/Hebron from tz2021e + if (dom < 0 || dom >= 24) { params[6] = -1; params[7] = toCalendarDOW[dow]; } else { @@ -889,12 +888,12 @@ } // A simple/raw version of j.t.ZoneOffsetTransitionRule + // timeEndOfDay is included in secondOfDay as "86,400" secs. private static class ZoneOffsetTransitionRule { private final int month; private final byte dom; private final int dow; private final int secondOfDay; - private final boolean timeEndOfDay; private final int timeDefinition; private final int standardOffset; private final int offsetBefore; @@ -912,7 +911,6 @@ this.dom = (byte)(((data & (63 << 22)) >>> 22) - 32); this.dow = dowByte == 0 ? -1 : dowByte; this.secondOfDay = timeByte == 31 ? in.readInt() : timeByte * 3600; - this.timeEndOfDay = timeByte == 24; this.timeDefinition = (data & (3 << 12)) >>> 12; this.standardOffset = stdByte == 255 ? in.readInt() : (stdByte - 128) * 900; @@ -933,9 +931,6 @@ epochDay = nextOrSame(epochDay, dow); } } - if (timeEndOfDay) { - epochDay += 1; - } int difference = 0; switch (timeDefinition) { case 0: // UTC
diff --git a/src/java.base/share/classes/sun/util/locale/LanguageTag.java b/src/java.base/share/classes/sun/util/locale/LanguageTag.java index a2d7457..1ba11d9 100644 --- a/src/java.base/share/classes/sun/util/locale/LanguageTag.java +++ b/src/java.base/share/classes/sun/util/locale/LanguageTag.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,10 +60,10 @@ private List<String> variants = Collections.emptyList(); // variant subtags private List<String> extensions = Collections.emptyList(); // extensions - // Map contains grandfathered tags and its preferred mappings from + // Map contains legacy language tags and its preferred mappings from // http://www.ietf.org/rfc/rfc5646.txt // Keys are lower-case strings. - private static final Map<String, String[]> GRANDFATHERED = new HashMap<>(); + private static final Map<String, String[]> LEGACY = new HashMap<>(); static { // grandfathered = irregular ; non-redundant tags registered @@ -127,7 +127,7 @@ {"zh-xiang", "hsn"}, }; for (String[] e : entries) { - GRANDFATHERED.put(LocaleUtils.toLowerString(e[0]), e); + LEGACY.put(LocaleUtils.toLowerString(e[0]), e); } } @@ -188,8 +188,8 @@ StringTokenIterator itr; - // Check if the tag is grandfathered - String[] gfmap = GRANDFATHERED.get(LocaleUtils.toLowerString(languageTag)); + // Check if the tag is a legacy language tag + String[] gfmap = LEGACY.get(LocaleUtils.toLowerString(languageTag)); if (gfmap != null) { // use preferred mapping itr = new StringTokenIterator(gfmap[1], SEP);
diff --git a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties index 238186b..9f1867d 100644 --- a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties +++ b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties
@@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -251,6 +251,7 @@ UYU=UYU UZS=UZS VEB=VEB +VED=VED VEF=VEF VES=VES VND=VND @@ -474,6 +475,7 @@ uyu=Uruguayan Peso uzs=Uzbekistan Som veb=Venezuelan Bol\u00edvar (1871-2008) +ved=Venezuelan Bol\u00edvar Soberano vef=Venezuelan Bol\u00edvar ves=Venezuelan Bol\u00edvar Soberano vnd=Vietnamese Dong
diff --git a/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java b/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java index ca635af..8759aab 100644 --- a/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java +++ b/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -353,7 +353,7 @@ {"Africa/Gaborone", CAT}, {"Africa/Harare", CAT}, {"Africa/Johannesburg", SAST}, - {"Africa/Juba", EAT}, + {"Africa/Juba", CAT}, {"Africa/Kampala", EAT}, {"Africa/Khartoum", CAT}, {"Africa/Kigali", CAT}, @@ -380,7 +380,9 @@ {"Africa/Timbuktu", GMT}, {"Africa/Tripoli", EET}, {"Africa/Tunis", CET}, - {"Africa/Windhoek", CAT}, + {"Africa/Windhoek", new String[] {"Central African Time", "CAT", + "Western African Time", "WAT", + "Central African Time", "CAT"}}, {"America/Adak", HST}, {"America/Anguilla", AST}, {"America/Antigua", AST}, @@ -569,9 +571,9 @@ {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Time", "DDUT", "Dumont-d'Urville Summer Time", "DDUST", "Dumont-d'Urville Time", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Macquarie Island Standard Time", "MIST", - "Macquarie Island Daylight Time", "MIDT", - "Macquarie Island Time", "MIST"}}, + {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", + "Australian Eastern Daylight Time (Macquarie)", "AEDT", + "Australian Eastern Time (Macquarie)", "AET"}}, {"Antarctica/Mawson", new String[] {"Mawson Time", "MAWT", "Mawson Summer Time", "MAWST", "Mawson Time", "MAWT"}},
diff --git a/src/java.base/share/conf/net.properties b/src/java.base/share/conf/net.properties index d95715d..6bc00e4 100644 --- a/src/java.base/share/conf/net.properties +++ b/src/java.base/share/conf/net.properties
@@ -100,6 +100,24 @@ jdk.http.auth.tunneling.disabledSchemes=Basic # +# Allow restricted HTTP request headers +# +# By default, the following request headers are not allowed to be set by user code +# in HttpRequests: "connection", "content-length", "expect", "host" and "upgrade". +# The 'jdk.httpclient.allowRestrictedHeaders' property allows one or more of these +# headers to be specified as a comma separated list to override the default restriction. +# The names are case-insensitive and white-space is ignored (removed before processing +# the list). Note, this capability is mostly intended for testing and isn't expected +# to be used in real deployments. Protocol errors or other undefined behavior is likely +# to occur when using them. The property is not set by default. +# Note also, that there may be other headers that are restricted from being set +# depending on the context. This includes the "Authorization" header when the +# relevant HttpClient has an authenticator set. These restrictions cannot be +# overridden by this property. +# +# jdk.httpclient.allowRestrictedHeaders=host +# +# # Transparent NTLM HTTP authentication mode on Windows. Transparent authentication # can be used for the NTLM scheme, where the security credentials based on the # currently logged in user's name and password can be obtained directly from the
diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index efbaa5b..0975179 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security
@@ -450,21 +450,22 @@ # Policy for failed Kerberos KDC lookups: # # When a KDC is unavailable (network error, service failure, etc), it is -# put inside a blacklist and accessed less often for future requests. The +# put inside a secondary list and accessed less often for future requests. The # value (case-insensitive) for this policy can be: # # tryLast -# KDCs in the blacklist are always tried after those not on the list. +# KDCs in the secondary list are always tried after those not on the list. # # tryLess[:max_retries,timeout] -# KDCs in the blacklist are still tried by their order in the configuration, -# but with smaller max_retries and timeout values. max_retries and timeout -# are optional numerical parameters (default 1 and 5000, which means once -# and 5 seconds). Please notes that if any of the values defined here is -# more than what is defined in krb5.conf, it will be ignored. +# KDCs in the secondary list are still tried by their order in the +# configuration, but with smaller max_retries and timeout values. +# max_retries and timeout are optional numerical parameters (default 1 and +# 5000, which means once and 5 seconds). Please note that if any of the +# values defined here are more than what is defined in krb5.conf, it will be +# ignored. # -# Whenever a KDC is detected as available, it is removed from the blacklist. -# The blacklist is reset when krb5.conf is reloaded. You can add +# Whenever a KDC is detected as available, it is removed from the secondary +# list. The secondary list is reset when krb5.conf is reloaded. You can add # refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is # reloaded whenever a JAAS authentication is attempted. #
diff --git a/src/java.base/share/lib/security/default.policy b/src/java.base/share/lib/security/default.policy index ab59a33..5db744f 100644 --- a/src/java.base/share/lib/security/default.policy +++ b/src/java.base/share/lib/security/default.policy
@@ -124,6 +124,7 @@ grant codeBase "jrt:/jdk.crypto.cryptoki" { permission java.lang.RuntimePermission "accessClassInPackage.com.sun.crypto.provider"; + permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc"; permission java.lang.RuntimePermission "accessClassInPackage.sun.security.*"; permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
diff --git a/src/java.base/share/native/libfdlibm/k_standard.c b/src/java.base/share/native/libfdlibm/k_standard.c index c0f8d93..d6e18e2 100644 --- a/src/java.base/share/native/libfdlibm/k_standard.c +++ b/src/java.base/share/native/libfdlibm/k_standard.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -739,6 +739,10 @@ errno = EDOM; } break; + default: + exc.retval = zero / zero; + errno = EINVAL; + break; } return exc.retval; }
diff --git a/src/java.base/share/native/libjava/ClassLoader.c b/src/java.base/share/native/libjava/ClassLoader.c index b3d2ef1..f20df59 100644 --- a/src/java.base/share/native/libjava/ClassLoader.c +++ b/src/java.base/share/native/libjava/ClassLoader.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -336,7 +336,8 @@ */ JNIEXPORT jboolean JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_load0 - (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) + (JNIEnv *env, jobject this, jstring name, + jboolean isBuiltin, jboolean throwExceptionIfFail) { const char *cname; jint jniVersion; @@ -350,7 +351,7 @@ cname = JNU_GetStringPlatformChars(env, name, 0); if (cname == 0) return JNI_FALSE; - handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname); + handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname, throwExceptionIfFail); if (handle) { JNI_OnLoad_t JNI_OnLoad; JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle,
diff --git a/src/java.base/share/native/libjava/jni_util.c b/src/java.base/share/native/libjava/jni_util.c index e637f89..4cfff43 100644 --- a/src/java.base/share/native/libjava/jni_util.c +++ b/src/java.base/share/native/libjava/jni_util.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -516,7 +516,7 @@ newString646_US(JNIEnv *env, const char *str) { int len = (int)strlen(str); - jchar buf[512]; + jchar buf[512] = {0}; jchar *str1; jstring result; int i;
diff --git a/src/java.base/share/native/libnet/Inet6Address.c b/src/java.base/share/native/libnet/Inet6Address.c index 3d0151a..f44440a 100644 --- a/src/java.base/share/native/libnet/Inet6Address.c +++ b/src/java.base/share/native/libnet/Inet6Address.c
@@ -37,7 +37,6 @@ jfieldID ia6_ipaddressID; jfieldID ia6_scopeidID; -jfieldID ia6_cachedscopeidID; jfieldID ia6_scopeidsetID; jfieldID ia6_scopeifnameID; jmethodID ia6_ctrID; @@ -65,8 +64,6 @@ CHECK_NULL(ia6_ipaddressID); ia6_scopeidID = (*env)->GetFieldID(env, ia6h_class, "scope_id", "I"); CHECK_NULL(ia6_scopeidID); - ia6_cachedscopeidID = (*env)->GetFieldID(env, ia6_class, "cached_scope_id", "I"); - CHECK_NULL(ia6_cachedscopeidID); ia6_scopeidsetID = (*env)->GetFieldID(env, ia6h_class, "scope_id_set", "Z"); CHECK_NULL(ia6_scopeidsetID); ia6_scopeifnameID = (*env)->GetFieldID(env, ia6h_class, "scope_ifname", "Ljava/net/NetworkInterface;");
diff --git a/src/java.base/share/native/libnet/net_util.h b/src/java.base/share/native/libnet/net_util.h index 1caefd2..97c6acc 100644 --- a/src/java.base/share/native/libnet/net_util.h +++ b/src/java.base/share/native/libnet/net_util.h
@@ -107,7 +107,6 @@ extern jfieldID ia6_holder6ID; extern jfieldID ia6_ipaddressID; extern jfieldID ia6_scopeidID; -extern jfieldID ia6_cachedscopeidID; extern jfieldID ia6_scopeidsetID; extern jfieldID ia6_scopeifnameID; extern jmethodID ia6_ctrID;
diff --git a/src/java.base/share/native/libverify/check_code.c b/src/java.base/share/native/libverify/check_code.c index e78627c..4f90088 100644 --- a/src/java.base/share/native/libverify/check_code.c +++ b/src/java.base/share/native/libverify/check_code.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3830,7 +3830,7 @@ } length = finish - p; if (length + 1 > (int)sizeof(buffer_space)) { - buffer = malloc(length + 1); + buffer = calloc(length + 1, sizeof(char)); check_and_push(context, buffer, VM_MALLOC_BLK); } memcpy(buffer, p, length);
diff --git a/src/java.base/share/native/libzip/zip_util.c b/src/java.base/share/native/libzip/zip_util.c index f129e45..41dbd27 100644 --- a/src/java.base/share/native/libzip/zip_util.c +++ b/src/java.base/share/native/libzip/zip_util.c
@@ -1589,3 +1589,109 @@ inflateEnd(&strm); return JNI_TRUE; } + +static voidpf tracking_zlib_alloc(voidpf opaque, uInt items, uInt size) { + size_t* needed = (size_t*) opaque; + *needed += (size_t) items * (size_t) size; + return (voidpf) calloc((size_t) items, (size_t) size); +} + +static void tracking_zlib_free(voidpf opaque, voidpf address) { + free((void*) address); +} + +static voidpf zlib_block_alloc(voidpf opaque, uInt items, uInt size) { + char** range = (char**) opaque; + voidpf result = NULL; + size_t needed = (size_t) items * (size_t) size; + + if (range[1] - range[0] >= (ptrdiff_t) needed) { + result = (voidpf) range[0]; + range[0] += needed; + } + + return result; +} + +static void zlib_block_free(voidpf opaque, voidpf address) { + /* Nothing to do. */ +} + +static char const* deflateInit2Wrapper(z_stream* strm, int level) { + int err = deflateInit2(strm, level >= 0 && level <= 9 ? level : Z_DEFAULT_COMPRESSION, + Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY); + if (err == Z_MEM_ERROR) { + return "Out of memory in deflateInit2"; + } + + if (err != Z_OK) { + return "Internal error in deflateInit2"; + } + + return NULL; +} + +JNIEXPORT char const* +ZIP_GZip_InitParams(size_t inLen, size_t* outLen, size_t* tmpLen, int level) { + z_stream strm; + *tmpLen = 0; + char const* errorMsg; + + memset(&strm, 0, sizeof(z_stream)); + strm.zalloc = tracking_zlib_alloc; + strm.zfree = tracking_zlib_free; + strm.opaque = (voidpf) tmpLen; + + errorMsg = deflateInit2Wrapper(&strm, level); + + if (errorMsg == NULL) { + *outLen = (size_t) deflateBound(&strm, (uLong) inLen); + deflateEnd(&strm); + } + + return errorMsg; +} + +JNIEXPORT size_t +ZIP_GZip_Fully(char* inBuf, size_t inLen, char* outBuf, size_t outLen, char* tmp, size_t tmpLen, + int level, char* comment, char const** pmsg) { + z_stream strm; + gz_header hdr; + int err; + char* block[] = {tmp, tmpLen + tmp}; + size_t result = 0; + + memset(&strm, 0, sizeof(z_stream)); + strm.zalloc = zlib_block_alloc; + strm.zfree = zlib_block_free; + strm.opaque = (voidpf) block; + + *pmsg = deflateInit2Wrapper(&strm, level); + + if (*pmsg == NULL) { + strm.next_out = (Bytef *) outBuf; + strm.avail_out = (uInt) outLen; + strm.next_in = (Bytef *) inBuf; + strm.avail_in = (uInt) inLen; + + if (comment != NULL) { + memset(&hdr, 0, sizeof(hdr)); + hdr.comment = (Bytef*) comment; + deflateSetHeader(&strm, &hdr); + } + + err = deflate(&strm, Z_FINISH); + + if (err == Z_OK || err == Z_BUF_ERROR) { + *pmsg = "Buffer too small"; + } else if (err != Z_STREAM_END) { + *pmsg = "Intern deflate error"; + } else { + result = (size_t) strm.total_out; + } + + deflateEnd(&strm); + } + + return result; +}
diff --git a/src/java.base/unix/classes/java/io/UnixFileSystem.java b/src/java.base/unix/classes/java/io/UnixFileSystem.java index 068593c..b8c8df2 100644 --- a/src/java.base/unix/classes/java/io/UnixFileSystem.java +++ b/src/java.base/unix/classes/java/io/UnixFileSystem.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,6 +130,11 @@ return (f.getPrefixLength() != 0); } + @Override + public boolean isInvalid(File f) { + return f.getPath().indexOf('\u0000') < 0 ? false : true; + } + public String resolve(File f) { if (isAbsolute(f)) return f.getPath(); SecurityManager sm = System.getSecurityManager();
diff --git a/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java b/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java index 68327f8..751ae49 100644 --- a/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java +++ b/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,14 @@ static final boolean allowsQuotedPathElements = false; /** + * Returns true if loading a native library only if + * it's present on the file system. + */ + static boolean loadLibraryOnlyIfPresent() { + return true; + } + + /** * Returns an alternate path name for the given file * such that if the original pathname did not exist, then the * file may be located at the alternate location.
diff --git a/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java b/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java index 063bd17..9c4b881 100644 --- a/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java +++ b/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java
@@ -98,7 +98,7 @@ protected synchronized native void bind0(int lport, InetAddress laddr) throws SocketException; - protected native void send(DatagramPacket p) throws IOException; + protected native void send0(DatagramPacket p) throws IOException; protected synchronized native int peek(InetAddress i) throws IOException;
diff --git a/src/java.base/unix/native/libjava/ProcessImpl_md.c b/src/java.base/unix/native/libjava/ProcessImpl_md.c index d0c2543..df8b62c 100644 --- a/src/java.base/unix/native/libjava/ProcessImpl_md.c +++ b/src/java.base/unix/native/libjava/ProcessImpl_md.c
@@ -347,8 +347,8 @@ __attribute_noinline__ #endif -/* vfork(2) is deprecated on Solaris */ -#ifndef __solaris__ +/* vfork(2) is deprecated on Solaris and Darwin */ +#if !defined(__APPLE__) && !defined(__solaris__) static pid_t vforkChild(ChildStuff *c) { volatile pid_t resultPid; @@ -478,8 +478,8 @@ static pid_t startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) { switch (c->mode) { -/* vfork(2) is deprecated on Solaris */ -#ifndef __solaris__ +/* vfork(2) is deprecated on Solaris and Darwin */ +#if !defined(__APPLE__) && !defined(__solaris__) case MODE_VFORK: return vforkChild(c); #endif
diff --git a/src/java.base/unix/native/libnet/Inet6AddressImpl.c b/src/java.base/unix/native/libnet/Inet6AddressImpl.c index 335abb1..bdbfd79 100644 --- a/src/java.base/unix/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet6AddressImpl.c
@@ -703,10 +703,6 @@ sa.sa6.sin6_family = AF_INET6; if (scope > 0) { sa.sa6.sin6_scope_id = scope; -#if defined(__linux__) - } else { - sa.sa6.sin6_scope_id = getDefaultIPv6Interface(&sa.sa6.sin6_addr); -#endif } // load network interface address to SOCKETADDRESS, if specified
diff --git a/src/java.base/unix/native/libnet/NetworkInterface.c b/src/java.base/unix/native/libnet/NetworkInterface.c index a674694..7b46cc2 100644 --- a/src/java.base/unix/native/libnet/NetworkInterface.c +++ b/src/java.base/unix/native/libnet/NetworkInterface.c
@@ -1257,7 +1257,8 @@ static int getIndex(int sock, const char *name) { struct ifreq if2; memset((char *)&if2, 0, sizeof(if2)); - strncpy(if2.ifr_name, name, sizeof(if2.ifr_name) - 1); + strncpy(if2.ifr_name, name, sizeof(if2.ifr_name)); + if2.ifr_name[sizeof(if2.ifr_name) - 1] = 0; if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) { return -1; @@ -1320,7 +1321,8 @@ static int getFlags(int sock, const char *ifname, int *flags) { struct ifreq if2; memset((char *)&if2, 0, sizeof(if2)); - strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1); + strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name)); + if2.ifr_name[sizeof(if2.ifr_name) - 1] = 0; if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) { return -1;
diff --git a/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c b/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c index 3fccc34..b75b18b 100644 --- a/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c +++ b/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c
@@ -79,10 +79,6 @@ static jfieldID pdsi_connectedAddress; static jfieldID pdsi_connectedPort; -extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him); -extern int getDefaultScopeID(JNIEnv *env); - - /* * Returns a java.lang.Integer based on 'i' */ @@ -200,7 +196,6 @@ JNI_TRUE) != 0) { return; } - setDefaultScopeID(env, &sa.sa); if (NET_Bind(fd, &sa, len) < 0) { if (errno == EADDRINUSE || errno == EADDRNOTAVAIL || @@ -266,8 +261,6 @@ return; } - setDefaultScopeID(env, &rmtaddr.sa); - if (NET_Connect(fd, &rmtaddr.sa, len) == -1) { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException", "Connect failed"); @@ -334,11 +327,11 @@ /* * Class: java_net_PlainDatagramSocketImpl - * Method: send + * Method: send0 * Signature: (Ljava/net/DatagramPacket;)V */ JNIEXPORT void JNICALL -Java_java_net_PlainDatagramSocketImpl_send(JNIEnv *env, jobject this, +Java_java_net_PlainDatagramSocketImpl_send0(JNIEnv *env, jobject this, jobject packet) { char BUF[MAX_BUFFER_LEN]; @@ -393,7 +386,6 @@ } rmtaddrP = &rmtaddr.sa; } - setDefaultScopeID(env, &rmtaddr.sa); if (packetBufferLen > MAX_BUFFER_LEN) { /* When JNI-ifying the JDK's IO routines, we turned @@ -2143,26 +2135,6 @@ NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed"); return; } - -#ifdef __linux__ - /* - * On 2.4.8+ if we join a group with the interface set to 0 - * then the kernel records the interface it decides. This causes - * subsequent leave groups to fail as there is no match. Thus we - * pick the interface if there is a matching route. - */ - if (index == 0) { - int rt_index = getDefaultIPv6Interface(&(mname6.ipv6mr_multiaddr)); - if (rt_index > 0) { - index = rt_index; - } - } -#endif -#ifdef MACOSX - if (family == AF_INET6 && index == 0) { - index = getDefaultScopeID(env); - } -#endif mname6.ipv6mr_interface = index; } else { jint idx = (*env)->GetIntField(env, niObj, ni_indexID);
diff --git a/src/java.base/unix/native/libnet/PlainSocketImpl.c b/src/java.base/unix/native/libnet/PlainSocketImpl.c index 1aec77f..5767719 100644 --- a/src/java.base/unix/native/libnet/PlainSocketImpl.c +++ b/src/java.base/unix/native/libnet/PlainSocketImpl.c
@@ -47,8 +47,6 @@ jfieldID psi_fdLockID; jfieldID psi_closePendingID; -extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him); - /* * file descriptor used for dup2 */ @@ -264,7 +262,6 @@ JNI_TRUE) != 0) { return; } - setDefaultScopeID(env, &sa.sa); if (trafficClass != 0 && ipv6_available()) { NET_SetTrafficClass(&sa, trafficClass); @@ -512,7 +509,6 @@ &len, JNI_TRUE) != 0) { return; } - setDefaultScopeID(env, &sa.sa); if (NET_Bind(fd, &sa, len) < 0) { if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index cb74eaf..4bfd59f 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c
@@ -444,280 +444,7 @@ } } -#if defined(__linux__) - -/* following code creates a list of addresses from the kernel - * routing table that are routed via the loopback address. - * We check all destination addresses against this table - * and override the scope_id field to use the relevant value for "lo" - * in order to work-around the Linux bug that prevents packets destined - * for certain local addresses from being sent via a physical interface. - */ - -struct loopback_route { - struct in6_addr addr; /* destination address */ - int plen; /* prefix length */ -}; - -static struct loopback_route *loRoutes = 0; -static int nRoutes = 0; /* number of routes */ -static int loRoutes_size = 16; /* initial size */ -static int lo_scope_id = 0; - -static void initLoopbackRoutes(); - -void printAddr (struct in6_addr *addr) { - int i; - for (i=0; i<16; i++) { - printf ("%02x", addr->s6_addr[i]); - } - printf ("\n"); -} - -static jboolean needsLoopbackRoute (struct in6_addr* dest_addr) { - int byte_count; - int extra_bits, i; - struct loopback_route *ptr; - - if (loRoutes == 0) { - initLoopbackRoutes(); - } - - for (ptr = loRoutes, i=0; i<nRoutes; i++, ptr++) { - struct in6_addr *target_addr=&ptr->addr; - int dest_plen = ptr->plen; - byte_count = dest_plen >> 3; - extra_bits = dest_plen & 0x3; - - if (byte_count > 0) { - if (memcmp(target_addr, dest_addr, byte_count)) { - continue; /* no match */ - } - } - - if (extra_bits > 0) { - unsigned char c1 = ((unsigned char *)target_addr)[byte_count]; - unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count]; - unsigned char mask = 0xff << (8 - extra_bits); - if ((c1 & mask) != (c2 & mask)) { - continue; - } - } - return JNI_TRUE; - } - return JNI_FALSE; -} - - -static void initLoopbackRoutes() { - FILE *f; - char srcp[8][5]; - char hopp[8][5]; - int dest_plen, src_plen, use, refcnt, metric; - unsigned long flags; - char dest_str[40]; - struct in6_addr dest_addr; - char device[16]; - struct loopback_route *loRoutesTemp; - - if (loRoutes != 0) { - free (loRoutes); - } - loRoutes = calloc (loRoutes_size, sizeof(struct loopback_route)); - if (loRoutes == 0) { - return; - } - /* - * Scan /proc/net/ipv6_route looking for a matching - * route. - */ - if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) { - return ; - } - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x " - "%4s%4s%4s%4s%4s%4s%4s%4s %02x " - "%4s%4s%4s%4s%4s%4s%4s%4s " - "%08x %08x %08x %08lx %8s", - dest_str, &dest_str[5], &dest_str[10], &dest_str[15], - &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35], - &dest_plen, - srcp[0], srcp[1], srcp[2], srcp[3], - srcp[4], srcp[5], srcp[6], srcp[7], - &src_plen, - hopp[0], hopp[1], hopp[2], hopp[3], - hopp[4], hopp[5], hopp[6], hopp[7], - &metric, &use, &refcnt, &flags, device) == 31) { - - /* - * Some routes should be ignored - */ - if ( (dest_plen < 0 || dest_plen > 128) || - (src_plen != 0) || - (flags & (RTF_POLICY | RTF_FLOW)) || - ((flags & RTF_REJECT) && dest_plen == 0) ) { - continue; - } - - /* - * Convert the destination address - */ - dest_str[4] = ':'; - dest_str[9] = ':'; - dest_str[14] = ':'; - dest_str[19] = ':'; - dest_str[24] = ':'; - dest_str[29] = ':'; - dest_str[34] = ':'; - dest_str[39] = '\0'; - - if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) { - /* not an Ipv6 address */ - continue; - } - if (strcmp(device, "lo") != 0) { - /* Not a loopback route */ - continue; - } else { - if (nRoutes == loRoutes_size) { - loRoutesTemp = realloc (loRoutes, loRoutes_size * - sizeof (struct loopback_route) * 2); - - if (loRoutesTemp == 0) { - free(loRoutes); - loRoutes = NULL; - nRoutes = 0; - fclose (f); - return; - } - loRoutes=loRoutesTemp; - loRoutes_size *= 2; - } - memcpy (&loRoutes[nRoutes].addr,&dest_addr,sizeof(struct in6_addr)); - loRoutes[nRoutes].plen = dest_plen; - nRoutes ++; - } - } - - fclose (f); - { - /* now find the scope_id for "lo" */ - - char devname[21]; - char addr6p[8][5]; - int plen, scope, dad_status, if_idx; - - if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) == 13) { - - if (strcmp(devname, "lo") == 0) { - /* - * Found - so just return the index - */ - fclose(f); - lo_scope_id = if_idx; - return; - } - } - fclose(f); - } - } -} - -/* - * Following is used for binding to local addresses. Equivalent - * to code above, for bind(). - */ - -struct localinterface { - int index; - char localaddr [16]; -}; - -static struct localinterface *localifs = 0; -static int localifsSize = 0; /* size of array */ -static int nifs = 0; /* number of entries used in array */ - -/* not thread safe: make sure called once from one thread */ - -static void initLocalIfs () { - FILE *f; - unsigned char staddr [16]; - char ifname [33]; - struct localinterface *lif=0; - int index, x1, x2, x3; - unsigned int u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,ua,ub,uc,ud,ue,uf; - - if ((f = fopen("/proc/net/if_inet6", "r")) == NULL) { - return ; - } - while (fscanf (f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x " - "%d %x %x %x %32s",&u0,&u1,&u2,&u3,&u4,&u5,&u6,&u7, - &u8,&u9,&ua,&ub,&uc,&ud,&ue,&uf, - &index, &x1, &x2, &x3, ifname) == 21) { - staddr[0] = (unsigned char)u0; - staddr[1] = (unsigned char)u1; - staddr[2] = (unsigned char)u2; - staddr[3] = (unsigned char)u3; - staddr[4] = (unsigned char)u4; - staddr[5] = (unsigned char)u5; - staddr[6] = (unsigned char)u6; - staddr[7] = (unsigned char)u7; - staddr[8] = (unsigned char)u8; - staddr[9] = (unsigned char)u9; - staddr[10] = (unsigned char)ua; - staddr[11] = (unsigned char)ub; - staddr[12] = (unsigned char)uc; - staddr[13] = (unsigned char)ud; - staddr[14] = (unsigned char)ue; - staddr[15] = (unsigned char)uf; - nifs ++; - if (nifs > localifsSize) { - localifs = (struct localinterface *) realloc ( - localifs, sizeof (struct localinterface)* (localifsSize+5)); - if (localifs == 0) { - nifs = 0; - fclose (f); - return; - } - lif = localifs + localifsSize; - localifsSize += 5; - } else { - lif ++; - } - memcpy (lif->localaddr, staddr, 16); - lif->index = index; - } - fclose (f); -} - -/* return the scope_id (interface index) of the - * interface corresponding to the given address - * returns 0 if no match found - */ - -static int getLocalScopeID (char *addr) { - struct localinterface *lif; - int i; - if (localifs == 0) { - initLocalIfs(); - } - for (i=0, lif=localifs; i<nifs; i++, lif++) { - if (memcmp (addr, lif->localaddr, 16) == 0) { - return lif->index; - } - } - return 0; -} - -void platformInit () { - initLoopbackRoutes(); - initLocalIfs(); -} - -#elif defined(_AIX) +#if defined(_AIX) /* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */ extern void aix_close_init(); @@ -803,71 +530,12 @@ *len = sizeof(struct sockaddr_in6); } -#ifdef __linux__ - /* - * On Linux if we are connecting to a link-local address - * we need to specify the interface in the scope_id (2.4 kernel only) - * - * If the scope was cached then we use the cached value. If not cached but - * specified in the Inet6Address we use that, but we first check if the - * address needs to be routed via the loopback interface. In this case, - * we override the specified value with that of the loopback interface. - * If no cached value exists and no value was specified by user, then - * we try to determine a value from the routing table. In all these - * cases the used value is cached for further use. - */ - if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) { - unsigned int cached_scope_id = 0, scope_id = 0; - - if (ia6_cachedscopeidID) { - cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); - /* if cached value exists then use it. Otherwise, check - * if scope is set in the address. - */ - if (!cached_scope_id) { - if (ia6_scopeidID) { - scope_id = getInet6Address_scopeid(env, iaObj); - } - if (scope_id != 0) { - /* check user-specified value for loopback case - * that needs to be overridden - */ - if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) { - cached_scope_id = lo_scope_id; - (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); - } - } else { - /* - * Otherwise consult the IPv6 routing tables to - * try determine the appropriate interface. - */ - if (kernelIsV24()) { - cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr); - } else { - cached_scope_id = getLocalScopeID((char *)&(sa->sa6.sin6_addr)); - if (cached_scope_id == 0) { - cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr); - } - } - (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); - } - } - } - - /* - * If we have a scope_id use the extended form - * of sockaddr_in6. - */ - sa->sa6.sin6_scope_id = cached_scope_id == 0 ? scope_id : cached_scope_id; - } -#else /* handle scope_id */ if (family != java_net_InetAddress_IPv4) { if (ia6_scopeidID) { sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj); } } -#endif } else { jint address; if (family != java_net_InetAddress_IPv4) { @@ -1002,158 +670,6 @@ } /* - * Determine the default interface for an IPv6 address. - * - * 1. Scans /proc/net/ipv6_route for a matching route - * (eg: fe80::/10 or a route for the specific address). - * This will tell us the interface to use (eg: "eth0"). - * - * 2. Lookup /proc/net/if_inet6 to map the interface - * name to an interface index. - * - * Returns :- - * -1 if error - * 0 if no matching interface - * >1 interface index to use for the link-local address. - */ -#if defined(__linux__) -int getDefaultIPv6Interface(struct in6_addr *target_addr) { - FILE *f; - char srcp[8][5]; - char hopp[8][5]; - int dest_plen, src_plen, use, refcnt, metric; - unsigned long flags; - char dest_str[40]; - struct in6_addr dest_addr; - char device[16]; - jboolean match = JNI_FALSE; - - /* - * Scan /proc/net/ipv6_route looking for a matching - * route. - */ - if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) { - return -1; - } - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x " - "%4s%4s%4s%4s%4s%4s%4s%4s %02x " - "%4s%4s%4s%4s%4s%4s%4s%4s " - "%08x %08x %08x %08lx %8s", - dest_str, &dest_str[5], &dest_str[10], &dest_str[15], - &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35], - &dest_plen, - srcp[0], srcp[1], srcp[2], srcp[3], - srcp[4], srcp[5], srcp[6], srcp[7], - &src_plen, - hopp[0], hopp[1], hopp[2], hopp[3], - hopp[4], hopp[5], hopp[6], hopp[7], - &metric, &use, &refcnt, &flags, device) == 31) { - - /* - * Some routes should be ignored - */ - if ( (dest_plen < 0 || dest_plen > 128) || - (src_plen != 0) || - (flags & (RTF_POLICY | RTF_FLOW)) || - ((flags & RTF_REJECT) && dest_plen == 0) ) { - continue; - } - - /* - * Convert the destination address - */ - dest_str[4] = ':'; - dest_str[9] = ':'; - dest_str[14] = ':'; - dest_str[19] = ':'; - dest_str[24] = ':'; - dest_str[29] = ':'; - dest_str[34] = ':'; - dest_str[39] = '\0'; - - if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) { - /* not an Ipv6 address */ - continue; - } else { - /* - * The prefix len (dest_plen) indicates the number of bits we - * need to match on. - * - * dest_plen / 8 => number of bytes to match - * dest_plen % 8 => number of additional bits to match - * - * eg: fe80::/10 => match 1 byte + 2 additional bits in the - * the next byte. - */ - int byte_count = dest_plen >> 3; - int extra_bits = dest_plen & 0x3; - - if (byte_count > 0) { - if (memcmp(target_addr, &dest_addr, byte_count)) { - continue; /* no match */ - } - } - - if (extra_bits > 0) { - unsigned char c1 = ((unsigned char *)target_addr)[byte_count]; - unsigned char c2 = ((unsigned char *)&dest_addr)[byte_count]; - unsigned char mask = 0xff << (8 - extra_bits); - if ((c1 & mask) != (c2 & mask)) { - continue; - } - } - - /* - * We have a match - */ - match = JNI_TRUE; - break; - } - } - fclose(f); - - /* - * If there's a match then we lookup the interface - * index. - */ - if (match) { - char devname[21]; - char addr6p[8][5]; - int plen, scope, dad_status, if_idx; - - if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) == 13) { - - if (strcmp(devname, device) == 0) { - /* - * Found - so just return the index - */ - fclose(f); - return if_idx; - } - } - fclose(f); - } else { - /* - * Couldn't open /proc/net/if_inet6 - */ - return -1; - } - } - - /* - * If we get here it means we didn't there wasn't any - * route or we couldn't get the index of the interface. - */ - return 0; -} -#endif - - -/* * Wrapper for getsockopt system routine - does any necessary * pre/post processing to deal with OS specific oddities :- *
diff --git a/src/java.base/unix/native/libnet/net_util_md.h b/src/java.base/unix/native/libnet/net_util_md.h index 0ef3d3e..59c37e6 100644 --- a/src/java.base/unix/native/libnet/net_util_md.h +++ b/src/java.base/unix/native/libnet/net_util_md.h
@@ -101,7 +101,6 @@ #ifdef __linux__ int kernelIsV24(); -int getDefaultIPv6Interface(struct in6_addr *target_addr); #endif #ifdef __solaris__
diff --git a/src/java.base/windows/classes/java/io/WinNTFileSystem.java b/src/java.base/windows/classes/java/io/WinNTFileSystem.java index 15e7d3d..a45fd3e 100644 --- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java +++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package java.io; import java.io.File; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.util.BitSet; import java.util.Locale; @@ -45,6 +46,21 @@ private final char semicolon; private final String userDir; + // Whether to enable alternative data streams (ADS) by suppressing + // checking the path for invalid characters, in particular ":". + // ADS support will be enabled if and only if the property is set and + // is the empty string or is equal, ignoring case, to the string "true". + // By default ADS support is disabled. + private static final boolean ENABLE_ADS; + static { + String enableADS = GetPropertyAction.privilegedGetProperty("jdk.io.File.enableADS"); + if (enableADS != null) { + ENABLE_ADS = "".equals(enableADS) || Boolean.parseBoolean(enableADS); + } else { + ENABLE_ADS = false; + } + } + public WinNTFileSystem() { Properties props = GetPropertyAction.privilegedGetProperties(); slash = props.getProperty("file.separator").charAt(0); @@ -304,6 +320,36 @@ } @Override + public boolean isInvalid(File f) { + if (f.getPath().indexOf('\u0000') >= 0) + return true; + + if (ENABLE_ADS) + return false; + + // Invalid if there is a ":" at a position greater than 1, or if there + // is a ":" at position 1 and the first character is not a letter + String pathname = f.getPath(); + int lastColon = pathname.lastIndexOf(":"); + + // Valid if there is no ":" present or if the last ":" present is + // at index 1 and the first character is a latter + if (lastColon < 0 || + (lastColon == 1 && isLetter(pathname.charAt(0)))) + return false; + + // Invalid if path creation fails + Path path = null; + try { + path = sun.nio.fs.DefaultFileSystemProvider.theFileSystem().getPath(pathname); + return false; + } catch (InvalidPathException ignored) { + } + + return true; + } + + @Override public String resolve(File f) { String path = f.getPath(); int pl = f.getPrefixLength();
diff --git a/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java b/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java index 40d21a6..43b702f 100644 --- a/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java +++ b/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java
@@ -37,6 +37,14 @@ static final boolean allowsQuotedPathElements = true; /** + * Returns true if loading a native library only if + * it's present on the file system. + */ + static boolean loadLibraryOnlyIfPresent() { + return true; + } + + /** * Returns an alternate path name for the given file * such that if the original pathname did not exist, then the * file may be located at the alternate location.
diff --git a/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java b/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java index 3363f38..2caecb2 100644 --- a/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java +++ b/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java
@@ -124,7 +124,7 @@ socketReceiveOrPeekData(nativefd, p, timeout, connected, false /*receive*/); } - protected void send(DatagramPacket p) throws IOException { + protected void send0(DatagramPacket p) throws IOException { int nativefd = checkAndReturnNativeFD(); if (p == null)
diff --git a/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java b/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java index 6cb4ba9..dd75cce 100644 --- a/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java +++ b/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java
@@ -184,7 +184,7 @@ boolean exclBind) throws SocketException; - protected native void send(DatagramPacket p) throws IOException; + protected native void send0(DatagramPacket p) throws IOException; protected synchronized native int peek(InetAddress i) throws IOException;
diff --git a/src/java.base/windows/native/libjava/java_props_md.c b/src/java.base/windows/native/libjava/java_props_md.c index 4564356..b17b57f 100644 --- a/src/java.base/windows/native/libjava/java_props_md.c +++ b/src/java.base/windows/native/libjava/java_props_md.c
@@ -393,7 +393,7 @@ GetVersionEx((OSVERSIONINFO *) &ver); majorVersion = ver.dwMajorVersion; minorVersion = ver.dwMinorVersion; - /* distinguish Windows Server 2016 and 2019 by build number */ + /* distinguish Windows Server 2016+ by build number */ buildNumber = ver.dwBuildNumber; is_workstation = (ver.wProductType == VER_NT_WORKSTATION); platformId = ver.dwPlatformId; @@ -475,9 +475,13 @@ * Windows Server 2012 6 2 (!VER_NT_WORKSTATION) * Windows Server 2012 R2 6 3 (!VER_NT_WORKSTATION) * Windows 10 10 0 (VER_NT_WORKSTATION) + * Windows 11 10 0 (VER_NT_WORKSTATION) + * where (buildNumber >= 22000) * Windows Server 2016 10 0 (!VER_NT_WORKSTATION) * Windows Server 2019 10 0 (!VER_NT_WORKSTATION) * where (buildNumber > 17762) + * Windows Server 2022 10 0 (!VER_NT_WORKSTATION) + * where (buildNumber > 20347) * * This mapping will presumably be augmented as new Windows * versions are released. @@ -546,14 +550,24 @@ } else if (majorVersion == 10) { if (is_workstation) { switch (minorVersion) { - case 0: sprops.os_name = "Windows 10"; break; + case 0: + /* Windows 11 21H2 (original release) build number is 22000 */ + if (buildNumber >= 22000) { + sprops.os_name = "Windows 11"; + } else { + sprops.os_name = "Windows 10"; + } + break; default: sprops.os_name = "Windows NT (unknown)"; } } else { switch (minorVersion) { case 0: /* Windows server 2019 GA 10/2018 build number is 17763 */ - if (buildNumber > 17762) { + /* Windows server 2022 build number is 20348 */ + if (buildNumber > 20347) { + sprops.os_name = "Windows Server 2022"; + } else if (buildNumber > 17676) { sprops.os_name = "Windows Server 2019"; } else { sprops.os_name = "Windows Server 2016"; @@ -576,6 +590,8 @@ sprops.os_arch = "amd64"; #elif _X86_ sprops.os_arch = "x86"; +#elif defined(_M_ARM64) + sprops.os_arch = "aarch64"; #else sprops.os_arch = "unknown"; #endif
diff --git a/src/java.base/windows/native/libnet/DefaultProxySelector.c b/src/java.base/windows/native/libnet/DefaultProxySelector.c index 645b941..ca3eac5 100644 --- a/src/java.base/windows/native/libnet/DefaultProxySelector.c +++ b/src/java.base/windows/native/libnet/DefaultProxySelector.c
@@ -104,7 +104,6 @@ int nr_elems = 0; wchar_t *context = NULL; wchar_t *current_proxy = NULL; - BOOL error = FALSE; /* * The proxy server list contains one or more of the following strings @@ -116,7 +115,6 @@ LPWSTR pport; LPWSTR phost; int portVal = 0; - wchar_t *next_proxy = NULL; list_item *proxy = NULL; wchar_t* pos = NULL; @@ -290,7 +288,6 @@ } if (win_proxy != NULL) { - wchar_t *context = NULL; int defport = 0; int nr_elems = 0; @@ -314,27 +311,28 @@ nr_elems = createProxyList(win_proxy, lpProto, &head); if (nr_elems != 0 && head != NULL) { int index = 0; + list_item *current = head; proxy_array = (*env)->NewObjectArray(env, nr_elems, proxy_class, NULL); if (proxy_array == NULL || (*env)->ExceptionCheck(env)) { goto noproxy; } - while (head != NULL && index < nr_elems) { + while (current != NULL && index < nr_elems) { jstring jhost; jobject isa; jobject proxy; - if (head->host != NULL && proxy_array != NULL) { + if (current->host != NULL && proxy_array != NULL) { /* Let's create the appropriate Proxy object then. */ - if (head->port == 0) { - head->port = defport; + if (current->port == 0) { + current->port = defport; } - jhost = (*env)->NewString(env, head->host, (jsize)wcslen(head->host)); + jhost = (*env)->NewString(env, current->host, (jsize)wcslen(current->host)); if (jhost == NULL || (*env)->ExceptionCheck(env)) { proxy_array = NULL; } isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, - head->port); + current->port); if (isa == NULL || (*env)->ExceptionCheck(env)) { proxy_array = NULL; } @@ -348,7 +346,7 @@ } index++; } - head = head->next; + current = current->next; } } }
diff --git a/src/java.base/windows/native/libnet/PlainSocketImpl.c b/src/java.base/windows/native/libnet/PlainSocketImpl.c index 65aa212..144d872 100644 --- a/src/java.base/windows/native/libnet/PlainSocketImpl.c +++ b/src/java.base/windows/native/libnet/PlainSocketImpl.c
@@ -118,6 +118,9 @@ (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) { SOCKETADDRESS sa; int rv, sa_len = 0; + int so_rv; + SOCKET s = (SOCKET)fd; + int type = 0, optlen = sizeof(type); jboolean v4MappedAddress = ipv6_available() ? JNI_TRUE : JNI_FALSE; if (NET_InetAddressToSockaddr(env, iaObj, port, &sa, @@ -125,6 +128,16 @@ return -1; } + so_rv = getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&type, &optlen); + + /** + * Windows has a very long socket connect timeout of 2 seconds. + * If it's the loopback adapter we can shorten the wait interval. + */ + if (so_rv == 0 && type == SOCK_STREAM && IS_LOOPBACK_ADDRESS(&sa)) { + NET_EnableFastTcpLoopbackConnect(fd); + } + rv = connect(fd, &sa.sa, sa_len); if (rv == SOCKET_ERROR) { int err = WSAGetLastError();
diff --git a/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c b/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c index 5f9e39f..ae7d585 100644 --- a/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c +++ b/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c
@@ -415,11 +415,11 @@ /* * Class: java_net_TwoStacksPlainDatagramSocketImpl - * Method: send + * Method: send0 * Signature: (Ljava/net/DatagramPacket;)V */ JNIEXPORT void JNICALL -Java_java_net_TwoStacksPlainDatagramSocketImpl_send +Java_java_net_TwoStacksPlainDatagramSocketImpl_send0 (JNIEnv *env, jobject this, jobject packet) { char BUF[MAX_BUFFER_LEN];
diff --git a/src/java.base/windows/native/libnet/net_util_md.c b/src/java.base/windows/native/libnet/net_util_md.c index c09786f..3567945 100644 --- a/src/java.base/windows/native/libnet/net_util_md.c +++ b/src/java.base/windows/native/libnet/net_util_md.c
@@ -735,37 +735,6 @@ return 0; } -/* - * Determine the default interface for an IPv6 address. - * - * Returns :- - * 0 if error - * > 0 interface index to use - */ -jint getDefaultIPv6Interface(JNIEnv *env, struct sockaddr_in6 *target_addr) -{ - int ret; - DWORD b; - struct sockaddr_in6 route; - SOCKET fd = socket(AF_INET6, SOCK_STREAM, 0); - if (fd == INVALID_SOCKET) { - return 0; - } - - ret = WSAIoctl(fd, SIO_ROUTING_INTERFACE_QUERY, - (void *)target_addr, sizeof(struct sockaddr_in6), - (void *)&route, sizeof(struct sockaddr_in6), - &b, 0, 0); - if (ret == SOCKET_ERROR) { - // error - closesocket(fd); - return 0; - } else { - closesocket(fd); - return route.sin6_scope_id; - } -} - /** * Enables SIO_LOOPBACK_FAST_PATH */ @@ -785,6 +754,57 @@ return result == SOCKET_ERROR ? WSAGetLastError() : 0; } +int +IsWindows10RS3OrGreater() { + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; + DWORDLONG const cond_mask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_BUILDNUMBER, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_WIN10); + osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_WIN10); + osvi.dwBuildNumber = 16299; // RS3 (Redstone 3) + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, cond_mask) != 0; +} + +/** + * Shortens the default Windows socket + * connect timeout. Recommended for usage + * on the loopback adapter only. + */ +JNIEXPORT jint JNICALL +NET_EnableFastTcpLoopbackConnect(int fd) { + TCP_INITIAL_RTO_PARAMETERS rto = { + TCP_INITIAL_RTO_UNSPECIFIED_RTT, // Use the default or overriden by the Administrator + 1 // Minimum possible value before Windows 10 RS3 + }; + + /** + * In Windows 10 RS3+ we can use the no retransmissions flag to + * completely remove the timeout delay, which is fixed to 500ms + * if Windows receives RST when the destination port is not open. + */ + if (IsWindows10RS3OrGreater()) { + rto.MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS; + } + + DWORD result_byte_count = -1; + int result = WSAIoctl(fd, // descriptor identifying a socket + SIO_TCP_INITIAL_RTO, // dwIoControlCode + &rto, // pointer to TCP_INITIAL_RTO_PARAMETERS structure + sizeof(rto), // size, in bytes, of the input buffer + NULL, // pointer to output buffer + 0, // size of output buffer + &result_byte_count, // number of bytes returned + NULL, // OVERLAPPED structure + NULL); // completion routine + return (result == SOCKET_ERROR) ? WSAGetLastError() : 0; +} + /** * See net_util.h for documentation */ @@ -803,7 +823,7 @@ { jbyte caddr[16]; jint address; - unsigned int scopeid = 0, cached_scope_id = 0; + unsigned int scopeid = 0; if (family == java_net_InetAddress_IPv4) { // convert to IPv4-mapped address @@ -825,19 +845,11 @@ } else { getInet6Address_ipaddress(env, iaObj, (char *)caddr); scopeid = getInet6Address_scopeid(env, iaObj); - cached_scope_id = (unsigned int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); } sa->sa6.sin6_port = (u_short)htons((u_short)port); memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr)); sa->sa6.sin6_family = AF_INET6; - if ((family == java_net_InetAddress_IPv6) && - IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr) && - (!scopeid && !cached_scope_id)) - { - cached_scope_id = getDefaultIPv6Interface(env, &sa->sa6); - (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id); - } - sa->sa6.sin6_scope_id = scopeid == 0 ? cached_scope_id : scopeid; + sa->sa6.sin6_scope_id = scopeid; if (len != NULL) { *len = sizeof(struct sockaddr_in6); }
diff --git a/src/java.base/windows/native/libnet/net_util_md.h b/src/java.base/windows/native/libnet/net_util_md.h index 2edf008..2f873b6 100644 --- a/src/java.base/windows/native/libnet/net_util_md.h +++ b/src/java.base/windows/native/libnet/net_util_md.h
@@ -26,6 +26,7 @@ #include <WS2tcpip.h> #include <iphlpapi.h> #include <icmpapi.h> +#include <mstcpip.h> /* used to disable connection reset messages on Windows XP */ #ifndef SIO_UDP_CONNRESET @@ -86,10 +87,35 @@ #define GET_PORT(X) ((X)->sa.sa_family == AF_INET ? (X)->sa4.sin_port : (X)->sa6.sin6_port) +/** + * With dual socket implementation the + * IPv4 addresseses might be mapped as IPv6. + * The IPv4 loopback adapter address ranges (127.0.0.0 through 127.255.255.255) will + * be mapped as the following IPv6 ::ffff:127.0.0.0 through ::ffff:127.255.255.255. + * For example, this is done by NET_InetAddressToSockaddr. + */ +#define IN6_IS_ADDR_V4MAPPED_LOOPBACK(x) ( \ + (((x)->s6_words[0] == 0) && \ + ((x)->s6_words[1] == 0) && \ + ((x)->s6_words[2] == 0) && \ + ((x)->s6_words[3] == 0) && \ + ((x)->s6_words[4] == 0) && \ + ((x)->s6_words[5] == 0xFFFF) && \ + (((x)->s6_words[6] & 0x00FF) == 0x007F)) \ +) + +/** + * Check for IPv4 loopback adapter address ranges (127.0.0.0 through 127.255.255.255) + */ +#define IN4_IS_ADDR_NETLONG_LOOPBACK(l) ( \ + ((l & 0xFF000000) == 0x7F000000) \ +) + #define IS_LOOPBACK_ADDRESS(x) ( \ ((x)->sa.sa_family == AF_INET) ? \ - (ntohl((x)->sa4.sin_addr.s_addr) == INADDR_LOOPBACK) : \ - (IN6ADDR_ISLOOPBACK(x)) \ + (IN4_IS_ADDR_NETLONG_LOOPBACK(ntohl((x)->sa4.sin_addr.s_addr))) : \ + ((IN6_IS_ADDR_LOOPBACK(&(x)->sa6.sin6_addr)) || \ + (IN6_IS_ADDR_V4MAPPED_LOOPBACK(&(x)->sa6.sin6_addr))) \ ) JNIEXPORT int JNICALL NET_SocketClose(int fd); @@ -119,6 +145,8 @@ JNIEXPORT int JNICALL NET_WinBind(int s, SOCKETADDRESS *sa, int len, jboolean exclBind); +JNIEXPORT jint JNICALL NET_EnableFastTcpLoopbackConnect(int fd); + /* XP versions of the native routines */ JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0_XP
diff --git a/src/java.base/windows/native/libnio/ch/Net.c b/src/java.base/windows/native/libnio/ch/Net.c index 4b586d3..056c4db 100644 --- a/src/java.base/windows/native/libnio/ch/Net.c +++ b/src/java.base/windows/native/libnio/ch/Net.c
@@ -194,13 +194,25 @@ { SOCKETADDRESS sa; int rv; + int so_rv; int sa_len = 0; SOCKET s = (SOCKET)fdval(env, fdo); + int type = 0, optlen = sizeof(type); if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len, preferIPv6) != 0) { return IOS_THROWN; } + so_rv = getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&type, &optlen); + + /** + * Windows has a very long socket connect timeout of 2 seconds. + * If it's the loopback adapter we can shorten the wait interval. + */ + if (so_rv == 0 && type == SOCK_STREAM && IS_LOOPBACK_ADDRESS(&sa)) { + NET_EnableFastTcpLoopbackConnect((jint)s); + } + rv = connect(s, &sa.sa, sa_len); if (rv != 0) { int err = WSAGetLastError(); @@ -211,9 +223,7 @@ return IOS_THROWN; } else { /* Enable WSAECONNRESET errors when a UDP socket is connected */ - int type = 0, optlen = sizeof(type); - rv = getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&type, &optlen); - if (rv == 0 && type == SOCK_DGRAM) { + if (so_rv == 0 && type == SOCK_DGRAM) { setConnectionReset(s, TRUE); } }
diff --git a/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java b/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java index 69fdf68..783d59d 100644 --- a/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java +++ b/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java
@@ -37,36 +37,55 @@ static boolean isLeopard = isMacOSXLeopard(); static boolean isSnowLeopardOrBelow = isMacOSXSnowLeopardOrBelow(); + public static boolean isMacOSXBigSurOrAbove() { + return currentMacOSXVersionMatchesGivenVersionRange(10, 16, true, + false, true); + } + static boolean isMacOSXLeopard() { return isCurrentMacOSXVersion(5); } static boolean isMacOSXSnowLeopardOrBelow() { - return currentMacOSXVersionMatchesGivenVersionRange(6, true, true, false); + return currentMacOSXVersionMatchesGivenVersionRange(10, 6, true, + true, false); } static boolean isCurrentMacOSXVersion(final int version) { - return currentMacOSXVersionMatchesGivenVersionRange(version, true, false, false); + return isCurrentMacOSXVersion(10, version); + } + + static boolean isCurrentMacOSXVersion(final int major, final int minor) { + return currentMacOSXVersionMatchesGivenVersionRange(major, minor, true, false, false); } static boolean currentMacOSXVersionMatchesGivenVersionRange( final int version, final boolean inclusive, final boolean matchBelow, final boolean matchAbove) { - // split the "10.x.y" version number + return currentMacOSXVersionMatchesGivenVersionRange(10, version, inclusive, matchBelow, matchAbove); + } + + static boolean currentMacOSXVersionMatchesGivenVersionRange( + final int majorVersion, final int minorVersion, final boolean inclusive, + final boolean matchBelow, final boolean matchAbove) { + // split the "x.y.z" version number String osVersion = AccessController.doPrivileged(new GetPropertyAction("os.version")); String[] fragments = osVersion.split("\\."); - // sanity check the "10." part of the version - if (!fragments[0].equals("10")) return false; if (fragments.length < 2) return false; // check if os.version matches the given version using the given match method try { + int majorVers = Integer.parseInt(fragments[0]); int minorVers = Integer.parseInt(fragments[1]); - if (inclusive && minorVers == version) return true; - if (matchBelow && minorVers < version) return true; - if (matchAbove && minorVers > version) return true; + if (inclusive && majorVers == majorVersion && minorVers == minorVersion) return true; + if (matchBelow && + (majorVers < majorVersion || + (majorVers == majorVersion && minorVers < minorVersion))) return true; + if (matchAbove && + (majorVers > majorVersion || + (majorVers == majorVersion && minorVers > minorVersion))) return true; } catch (NumberFormatException e) { // was not an integer
diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java index b388fc0..21fd96c 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -326,6 +326,35 @@ } } + protected void paintFocus(Graphics g, AbstractButton b, + Rectangle viewRect, Rectangle textRect, Rectangle iconRect) { + Graphics2D g2d = null; + Stroke oldStroke = null; + Object oldAntialiasingHint = null; + Color oldColor = g.getColor(); + if (g instanceof Graphics2D) { + g2d = (Graphics2D)g; + oldStroke = g2d.getStroke(); + oldAntialiasingHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2d.setStroke(new BasicStroke(3)); + g2d.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + } + Color ringColor = UIManager.getColor("Focus.color"); + g.setColor(ringColor); + g.drawRoundRect(5, 3, b.getWidth() - 10, b.getHeight() - 7, 15, 15); + if (g2d != null) { + // Restore old state of Java2D renderer + g2d.setStroke(oldStroke); + g2d.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + oldAntialiasingHint); + } + g.setColor(oldColor); + } + protected String layoutAndGetText(final Graphics g, final AbstractButton b, final AquaButtonBorder aquaBorder, final Insets i, Rectangle viewRect, Rectangle iconRect, Rectangle textRect) { // re-initialize the view rect to the selected insets viewRect.x = i.left;
diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java index 1970bc7..0f5aea2 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java
@@ -496,4 +496,8 @@ public static Color getSelectionInactiveForegroundColorUIResource() { return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_FOREGROUND_COLOR)); } + + public static Color getSelectedControlColorUIResource() { + return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.SELECTED_CONTROL_TEXT_COLOR)); + } }
diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java index 0da5889..ee899e7 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java
@@ -307,6 +307,7 @@ final ColorUIResource selectedTabTitlePressedColor = new ColorUIResource(240, 240, 240); final ColorUIResource selectedTabTitleDisabledColor = new ColorUIResource(new Color(1, 1, 1, 0.55f)); final ColorUIResource selectedTabTitleNormalColor = white; + final Color selectedControlTextColor = AquaImageFactory.getSelectedControlColorUIResource(); final ColorUIResource selectedTabTitleShadowDisabledColor = new ColorUIResource(new Color(0, 0, 0, 0.25f)); final ColorUIResource selectedTabTitleShadowNormalColor = mediumTranslucentBlack; final ColorUIResource nonSelectedTabTitleNormalColor = black; @@ -848,7 +849,7 @@ "TabbedPane.tabsOverlapBorder", Boolean.TRUE, "TabbedPane.selectedTabTitlePressedColor", selectedTabTitlePressedColor, "TabbedPane.selectedTabTitleDisabledColor", selectedTabTitleDisabledColor, - "TabbedPane.selectedTabTitleNormalColor", selectedTabTitleNormalColor, + "TabbedPane.selectedTabTitleNormalColor", JRSUIUtils.isMacOSXBigSurOrAbove() ? selectedControlTextColor : selectedTabTitleNormalColor, "TabbedPane.selectedTabTitleShadowDisabledColor", selectedTabTitleShadowDisabledColor, "TabbedPane.selectedTabTitleShadowNormalColor", selectedTabTitleShadowNormalColor, "TabbedPane.nonSelectedTabTitleNormalColor", nonSelectedTabTitleNormalColor,
diff --git a/src/java.desktop/macosx/classes/sun/font/CFont.java b/src/java.desktop/macosx/classes/sun/font/CFont.java index 7fc0017..d062cdb 100644 --- a/src/java.desktop/macosx/classes/sun/font/CFont.java +++ b/src/java.desktop/macosx/classes/sun/font/CFont.java
@@ -211,7 +211,13 @@ PhysicalFont[] fonts = new PhysicalFont[numFonts]; fonts[0] = this; int idx = 1; + if (FontUtilities.isLogging()) { + FontUtilities.getLogger().info("Cascading list for " + this + " :"); + } for (String s : listOfString) { + if (FontUtilities.isLogging()) { + FontUtilities.getLogger().info("Fallback:" + s); + } if (s.equals(".AppleSymbolsFB")) { // Don't know why we get the weird name above .. replace. s = "AppleSymbols";
diff --git a/src/java.desktop/macosx/classes/sun/font/CFontManager.java b/src/java.desktop/macosx/classes/sun/font/CFontManager.java index 883a6c6..1de940e 100644 --- a/src/java.desktop/macosx/classes/sun/font/CFontManager.java +++ b/src/java.desktop/macosx/classes/sun/font/CFontManager.java
@@ -223,7 +223,7 @@ String defaultFallback = "Lucida Grande"; setupLogicalFonts("Dialog", defaultFont, defaultFallback); - setupLogicalFonts("Serif", "Times", "Times"); + setupLogicalFonts("Serif", "Times", "Times New Roman"); setupLogicalFonts("SansSerif", defaultFont, defaultFallback); setupLogicalFonts("Monospaced", "Menlo", "Courier"); setupLogicalFonts("DialogInput", defaultFont, defaultFallback); @@ -249,7 +249,13 @@ family = getFontFamily(realName, fallbackName); if (family != null) return family; - System.err.println("Warning: the fonts \"" + realName + "\" and \"" + fallbackName + "\" are not available for the Java logical font \"" + logicalName + "\", which may have unexpected appearance or behavior. Re-enable the \""+ realName +"\" font to remove this warning."); + if (FontUtilities.debugFonts()) { + FontUtilities.getLogger().severe( + "The fonts \"" + realName + "\" and \"" + fallbackName + + "\" are not available for the Java logical font \"" + logicalName + + "\", which may have unexpected appearance or behavior. Re-enable the \""+ + realName +"\" font to remove this warning."); + } return null; } @@ -259,7 +265,12 @@ family = FontFamily.getFamily(fallbackName); if (family != null){ - System.err.println("Warning: the font \"" + realName + "\" is not available, so \"" + fallbackName + "\" has been substituted, but may have unexpected appearance or behavor. Re-enable the \""+ realName +"\" font to remove this warning."); + if (FontUtilities.debugFonts()) { + FontUtilities.getLogger().warning( + "The font \"" + realName + "\" is not available, so \"" + fallbackName + + "\" has been substituted, but may have unexpected appearance or behavor. Re-enable the \"" + + realName +"\" font to remove this warning."); + } return family; }
diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index 356b1c9..d6f79d7 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java
@@ -30,13 +30,16 @@ import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.print.*; +import java.net.URI; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.concurrent.atomic.AtomicReference; import javax.print.*; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.Destination; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaPrintableArea; import javax.print.attribute.standard.MediaSize; @@ -58,6 +61,7 @@ private static String sShouldNotReachHere = "Should not reach here."; private volatile SecondaryLoop printingLoop; + private AtomicReference<Throwable> printErrorRef = new AtomicReference<>(); private boolean noDefaultPrinter = false; @@ -259,6 +263,21 @@ isPrintToFile = printToFile; } + private void setDestinationFile(String dest) { + if (attributes != null && dest != null) { + try { + URI destURI = new URI(dest); + attributes.add(new Destination(destURI)); + destinationAttr = "" + destURI.getSchemeSpecificPart(); + } catch (Exception e) { + } + } + } + + private String getDestinationFile() { + return destinationAttr; + } + @Override public void print(PrintRequestAttributeSet attributes) throws PrinterException { // NOTE: Some of this code is copied from RasterPrinterJob. @@ -305,6 +324,7 @@ performingPrinting = true; userCancelled = false; } + printErrorRef.set(null); //Add support for PageRange PageRanges pr = (attributes == null) ? null @@ -363,6 +383,15 @@ if (printingLoop != null) { printingLoop.exit(); } + + Throwable printError = printErrorRef.getAndSet(null); + if (printError != null) { + if (printError instanceof PrinterException) { + throw (PrinterException) printError; + } + throw (PrinterException) + new PrinterException().initCause(printError); + } } // Normalize the collated, # copies, numPages, first/last pages. Need to @@ -768,22 +797,36 @@ private Rectangle2D printAndGetPageFormatArea(final Printable printable, final Graphics graphics, final PageFormat pageFormat, final int pageIndex) { final Rectangle2D[] ret = new Rectangle2D[1]; - Runnable r = new Runnable() { public void run() { synchronized(ret) { - try { - int pageResult = printable.print(graphics, pageFormat, pageIndex); - if (pageResult != Printable.NO_SUCH_PAGE) { - ret[0] = getPageFormatArea(pageFormat); + Runnable r = new Runnable() { + @Override + public void run() { + synchronized (ret) { + try { + int pageResult = printable.print( + graphics, pageFormat, pageIndex); + if (pageResult != Printable.NO_SUCH_PAGE) { + ret[0] = getPageFormatArea(pageFormat); + } + } catch (Throwable t) { + printErrorRef.compareAndSet(null, t); + } } - } catch (Exception e) {} // Original code bailed on any exception - }}}; + } + }; if (onEventThread) { - try { EventQueue.invokeAndWait(r); } catch (Exception e) { e.printStackTrace(); } + try { + EventQueue.invokeAndWait(r); + } catch (Throwable t) { + printErrorRef.compareAndSet(null, t); + } } else { r.run(); } - synchronized(ret) { return ret[0]; } + synchronized (ret) { + return ret[0]; + } } // upcall from native
diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java index 8b3851c..ae28ebf 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,10 +54,6 @@ initRobot(); } - @Override - public void dispose() { - } - /** * Moves mouse pointer to given screen coordinates. * @param x X position
diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 1fe8016..c0af456 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
@@ -196,14 +196,16 @@ /* * System colors with default initial values, overwritten by toolkit if system values differ and are available. */ - private static final int NUM_APPLE_COLORS = 3; + private static final int NUM_APPLE_COLORS = 4; public static final int KEYBOARD_FOCUS_COLOR = 0; public static final int INACTIVE_SELECTION_BACKGROUND_COLOR = 1; public static final int INACTIVE_SELECTION_FOREGROUND_COLOR = 2; + public static final int SELECTED_CONTROL_TEXT_COLOR = 3; private static int[] appleColors = { 0xFF808080, // keyboardFocusColor = Color.gray; 0xFFC0C0C0, // secondarySelectedControlColor 0xFF303030, // controlDarkShadowColor + 0xFFFFFFFF, // controlTextColor }; private native void loadNativeColors(final int[] systemColors, final int[] appleColors);
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m index c708724..bd151ca 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m
@@ -128,7 +128,7 @@ // send up to the GestureHandler to recursively dispatch on the AWT event thread DECLARE_CLASS(jc_GestureHandler, "com/apple/eawt/event/GestureHandler"); - DECLARE_METHOD(sjm_handleGestureFromNative, jc_GestureHandler, + DECLARE_STATIC_METHOD(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V"); (*env)->CallStaticVoidMethod(env, jc_GestureHandler, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CInputMethod.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CInputMethod.m index 88585a6..3bfd726 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CInputMethod.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CInputMethod.m
@@ -115,9 +115,7 @@ AWT_ASSERT_APPKIT_THREAD; if (!view) return; - if (!inputMethod) return; - - [view setInputMethod:inputMethod]; // inputMethod is a GlobalRef + [view setInputMethod:inputMethod]; // inputMethod is a GlobalRef or null to disable. } + (void) _nativeEndComposition:(AWTView *)view {
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m index cbca56a..db5c192 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m
@@ -359,12 +359,7 @@ DECLARE_METHOD(jm_setCollated, sjc_CPrinterJob, "setCollated", "(Z)V"); DECLARE_METHOD(jm_setPageRangeAttribute, sjc_CPrinterJob, "setPageRangeAttribute", "(IIZ)V"); DECLARE_METHOD(jm_setPrintToFile, sjc_CPrinterJob, "setPrintToFile", "(Z)V"); - - if (src.jobDisposition == NSPrintSaveJob) { - (*env)->CallVoidMethod(env, dstPrinterJob, jm_setPrintToFile, true); - } else { - (*env)->CallVoidMethod(env, dstPrinterJob, jm_setPrintToFile, false); - } + DECLARE_METHOD(jm_setDestinationFile, sjc_CPrinterJob, "setDestinationFile", "(Ljava/lang/String;)V"); // get the selected printer's name, and set the appropriate PrintService on the Java side NSString *name = [[src printer] name]; @@ -374,6 +369,19 @@ NSMutableDictionary* printingDictionary = [src dictionary]; + if (src.jobDisposition == NSPrintSaveJob) { + (*env)->CallVoidMethod(env, dstPrinterJob, jm_setPrintToFile, true); + CHECK_EXCEPTION(); + NSURL *url = [printingDictionary objectForKey:NSPrintJobSavingURL]; + NSString *nsStr = [url absoluteString]; + jstring str = NSStringToJavaString(env, nsStr); + (*env)->CallVoidMethod(env, dstPrinterJob, jm_setDestinationFile, str); + CHECK_EXCEPTION(); + } else { + (*env)->CallVoidMethod(env, dstPrinterJob, jm_setPrintToFile, false); + CHECK_EXCEPTION(); + } + NSNumber* nsCopies = [printingDictionary objectForKey:NSPrintCopies]; if ([nsCopies respondsToSelector:@selector(integerValue)]) { @@ -429,6 +437,7 @@ DECLARE_METHOD(jm_getSelectAttrib, sjc_CPrinterJob, "getSelectAttrib", "()I"); DECLARE_METHOD(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I"); DECLARE_METHOD(jm_getPageFormat, sjc_CPrinterJob, "getPageFormatFromAttributes", "()Ljava/awt/print/PageFormat;"); + DECLARE_METHOD(jm_getDestinationFile, sjc_CPrinterJob, "getDestinationFile", "()Ljava/lang/String;"); NSMutableDictionary* printingDictionary = [dst dictionary]; @@ -476,6 +485,17 @@ if (page != NULL) { javaPageFormatToNSPrintInfo(env, NULL, page, dst); } + + jstring dest = (*env)->CallObjectMethod(env, srcPrinterJob, jm_getDestinationFile); + CHECK_EXCEPTION(); + if (dest != NULL) { + [dst setJobDisposition:NSPrintSaveJob]; + NSString *nsDestStr = JavaStringToNSString(env, dest); + NSURL *nsURL = [NSURL fileURLWithPath:nsDestStr isDirectory:NO]; + [printingDictionary setObject:nsURL forKey:NSPrintJobSavingURL]; + } else { + [dst setJobDisposition:NSPrintSpoolJob]; + } } /*
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m index 7eb539c..ca61907 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m
@@ -119,6 +119,7 @@ appleColors[sun_lwawt_macosx_LWCToolkit_KEYBOARD_FOCUS_COLOR] = [NSColor keyboardFocusIndicatorColor]; appleColors[sun_lwawt_macosx_LWCToolkit_INACTIVE_SELECTION_BACKGROUND_COLOR] = [NSColor secondarySelectedControlColor]; appleColors[sun_lwawt_macosx_LWCToolkit_INACTIVE_SELECTION_FOREGROUND_COLOR] = [NSColor controlDarkShadowColor]; + appleColors[sun_lwawt_macosx_LWCToolkit_SELECTED_CONTROL_TEXT_COLOR] = [NSColor controlTextColor]; for (i = 0; i < sun_lwawt_macosx_LWCToolkit_NUM_APPLE_COLORS; i++) { [appleColors[i] retain];
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/GeomUtilities.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/GeomUtilities.m index dd1d647..13ad3d7 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/GeomUtilities.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/GeomUtilities.m
@@ -24,7 +24,6 @@ */ #import "GeomUtilities.h" -#import <JavaNativeFoundation/JavaNativeFoundation.h> static jobject NewJavaRect(JNIEnv *env, jdouble x, jdouble y, jdouble w, jdouble h) { DECLARE_CLASS_RETURN(sjc_Rectangle2DDouble, "java/awt/geom/Rectangle2D$Double", NULL);
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m index 1d10a4c..2c764a1 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityUtilities.m
@@ -50,17 +50,21 @@ NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component) { + GET_CACCESSIBILITY_CLASS_RETURN(NSZeroSize); DECLARE_CLASS_RETURN(jc_Dimension, "java/awt/Dimension", NSZeroSize); DECLARE_FIELD_RETURN(jf_width, jc_Dimension, "width", "I", NSZeroSize); DECLARE_FIELD_RETURN(jf_height, jc_Dimension, "height", "I", NSZeroSize); DECLARE_STATIC_METHOD_RETURN(jm_getSize, sjc_CAccessibility, "getSize", "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Dimension;", NSZeroSize); - jobject dimension = (*env)->CallStaticObjectMethod(env, jc_Dimension, jm_getSize, axComponent, component); + jobject dimension = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getSize, axComponent, component); CHECK_EXCEPTION(); if (dimension == NULL) return NSZeroSize; - return NSMakeSize((*env)->GetIntField(env, dimension, jf_width), (*env)->GetIntField(env, dimension, jf_height)); + + NSSize size = NSMakeSize((*env)->GetIntField(env, dimension, jf_width), (*env)->GetIntField(env, dimension, jf_height)); + (*env)->DeleteLocalRef(env, dimension); + return size; } NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component) @@ -211,7 +215,9 @@ axComponent, component); CHECK_EXCEPTION(); if (jpoint == NULL) return NSZeroPoint; - return NSMakePoint((*env)->GetIntField(env, jpoint, sjf_X), (*env)->GetIntField(env, jpoint, sjf_Y)); + NSPoint p = NSMakePoint((*env)->GetIntField(env, jpoint, sjf_X), (*env)->GetIntField(env, jpoint, sjf_Y)); + (*env)->DeleteLocalRef(env, jpoint); + return p; } jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component)
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m index 162f868..9119bb3 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m
@@ -1430,6 +1430,7 @@ - (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env { + GET_CACCESSIBILITY_CLASS_RETURN(nil); DECLARE_CLASS_RETURN(jc_Container, "java/awt/Container", nil); DECLARE_STATIC_METHOD_RETURN(jm_accessibilityHitTest, sjc_CAccessibility, "accessibilityHitTest", "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;", nil);
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m index 0a48c45..6399689 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m
@@ -259,6 +259,7 @@ static void AWT_NSUncaughtExceptionHandler(NSException *exception) { NSLog(@"Apple AWT Internal Exception: %@", [exception description]); + NSLog(@"trace: %@", [exception callStackSymbols]); } @interface AWTStarter : NSObject
diff --git a/src/java.desktop/macosx/native/libosxapp/ThreadUtilities.m b/src/java.desktop/macosx/native/libosxapp/ThreadUtilities.m index 74be170..deb179e 100644 --- a/src/java.desktop/macosx/native/libosxapp/ThreadUtilities.m +++ b/src/java.desktop/macosx/native/libosxapp/ThreadUtilities.m
@@ -33,7 +33,7 @@ JavaVM *jvm = NULL; static JNIEnv *appKitEnv = NULL; static jobject appkitThreadGroup = NULL; -static NSString* JavaRunLoopMode = @"javaRunLoopMode"; +static NSString* JavaRunLoopMode = @"AWTRunLoopMode"; static NSArray<NSString*> *javaModes = nil; static inline void attachCurrentThread(void** env) {
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java index df654aa..bff23de 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java
@@ -66,10 +66,12 @@ import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.StringTokenizer; -import com.sun.imageio.plugins.common.ImageUtil; import com.sun.imageio.plugins.common.I18N; +import com.sun.imageio.plugins.common.ImageUtil; +import com.sun.imageio.plugins.common.ReaderUtil; /** This class is the Java Image IO plugin reader for BMP images. * It may subsample the image, clip the image, select sub-bands, @@ -226,6 +228,33 @@ } } + private void readColorPalette(int sizeOfPalette) throws IOException { + final int UNIT_SIZE = 1024000; + if (sizeOfPalette < UNIT_SIZE) { + palette = new byte[sizeOfPalette]; + iis.readFully(palette, 0, sizeOfPalette); + } else { + int bytesToRead = sizeOfPalette; + int bytesRead = 0; + List<byte[]> bufs = new ArrayList<>(); + while (bytesToRead != 0) { + int sz = Math.min(bytesToRead, UNIT_SIZE); + byte[] unit = new byte[sz]; + iis.readFully(unit, 0, sz); + bufs.add(unit); + bytesRead += sz; + bytesToRead -= sz; + } + byte[] paletteData = new byte[bytesRead]; + int copiedBytes = 0; + for (byte[] ba : bufs) { + System.arraycopy(ba, 0, paletteData, copiedBytes, ba.length); + copiedBytes += ba.length; + } + palette = paletteData; + } + } + /** * Process the image header. * @@ -308,8 +337,7 @@ // Read in the palette int numberOfEntries = (int)((bitmapOffset - 14 - size) / 3); int sizeOfPalette = numberOfEntries*3; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; } else { @@ -346,8 +374,7 @@ } int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries * 4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; @@ -407,8 +434,7 @@ if (colorsUsed != 0) { // there is a palette sizeOfPalette = (int)colorsUsed*4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = (int)colorsUsed; @@ -433,8 +459,7 @@ // Read in the palette int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries*4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; @@ -532,8 +557,7 @@ // Read in the palette int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries*4; - palette = new byte[sizeOfPalette]; - iis.readFully(palette, 0, sizeOfPalette); + readColorPalette(sizeOfPalette); metadata.palette = palette; metadata.paletteSize = numberOfEntries; @@ -595,7 +619,7 @@ } if (metadata.compression == BI_RGB) { - long imageDataSize = (width * height * (bitsPerPixel / 8)); + long imageDataSize = ((long)width * height * (bitsPerPixel / 8)); if (imageDataSize > (bitmapFileSize - bitmapOffset)) { throw new IIOException(I18N.getString("BMPImageReader9")); } @@ -1513,9 +1537,8 @@ } // Read till we have the whole image - byte values[] = new byte[imSize]; - int bytesRead = 0; - iis.readFully(values, 0, imSize); + byte[] values = ReaderUtil. + staggeredReadByteStream(iis, imSize); // Since data is compressed, decompress it decodeRLE8(imSize, padding, values, bdata); @@ -1697,8 +1720,8 @@ } // Read till we have the whole image - byte[] values = new byte[imSize]; - iis.readFully(values, 0, imSize); + byte[] values = ReaderUtil. + staggeredReadByteStream(iis, imSize); // Decompress the RLE4 compressed data. decodeRLE4(imSize, padding, values, bdata);
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java index 0f8d1d6..906aa3a 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ import java.awt.Point; import java.awt.Rectangle; import java.io.IOException; +import java.util.List; +import java.util.ArrayList; import javax.imageio.stream.ImageInputStream; /** @@ -213,4 +215,47 @@ } return result; } + + /** + * An utility method to allocate and initialize a byte array + * step by step with pre-defined limit, instead of allocating + * a large array up-front based on the length derived from + * an image header. + * + * @param iis a {@code ImageInputStream} to decode data and store + * it in byte array. + * @param length the size of data to decode + * + * @return array of size length when decode succeeeds + * + * @throws IOException if decoding of stream fails + */ + public static byte[] staggeredReadByteStream(ImageInputStream iis, + int length) throws IOException { + final int UNIT_SIZE = 1024000; + byte[] decodedData; + if (length < UNIT_SIZE) { + decodedData = new byte[length]; + iis.readFully(decodedData, 0, length); + } else { + int bytesToRead = length; + int bytesRead = 0; + List<byte[]> bufs = new ArrayList<>(); + while (bytesToRead != 0) { + int sz = Math.min(bytesToRead, UNIT_SIZE); + byte[] unit = new byte[sz]; + iis.readFully(unit, 0, sz); + bufs.add(unit); + bytesRead += sz; + bytesToRead -= sz; + } + decodedData = new byte[bytesRead]; + int copiedBytes = 0; + for (byte[] ba : bufs) { + System.arraycopy(ba, 0, decodedData, copiedBytes, ba.length); + copiedBytes += ba.length; + } + } + return decodedData; + } }
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java index 988c85b..a51505b 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -998,6 +998,11 @@ } } + if (tableIndex >= prefix.length) { + throw new IIOException("Code buffer limit reached," + + " no End of Image tag present, possibly data is corrupted. "); + } + int ti = tableIndex; int oc = oldCode;
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java index a41c54a..c7ffac8 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java
@@ -1139,6 +1139,13 @@ throw new IIOException("Unsupported Image Type"); } + if ((long)width * height > Integer.MAX_VALUE - 2) { + // We are not able to properly decode image that has number + // of pixels greater than Integer.MAX_VALUE - 2 + throw new IIOException("Can not read image of the size " + + width + " by " + height); + } + image = getDestination(param, imageTypes, width, height); imRas = image.getRaster();
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java index 18cd5c3..a6289a3 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java
@@ -1400,6 +1400,13 @@ int width = metadata.IHDR_width; int height = metadata.IHDR_height; + if ((long)width * height > Integer.MAX_VALUE - 2) { + // We are not able to properly decode image that has number + // of pixels greater than Integer.MAX_VALUE - 2 + throw new IIOException("Can not read image of the size " + + width + " by " + height); + } + // Init default values sourceXSubsampling = 1; sourceYSubsampling = 1;
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java index a1b0439..4516ce0 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFDecompressor.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1438,7 +1438,11 @@ * * @param byteCount the number of bytes of compressed data. */ - public void setByteCount(int byteCount) { + public void setByteCount(int byteCount) throws IOException{ + if (byteCount < 0) { + throw new IIOException("Strip byte count can't be" + + " negative: " + byteCount); + } this.byteCount = byteCount; }
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java index c0279b1..6ca5cbd 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFFaxDecompressor.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import javax.imageio.IIOException; import javax.imageio.plugins.tiff.BaselineTIFFTagSet; import javax.imageio.plugins.tiff.TIFFField; +import com.sun.imageio.plugins.common.ReaderUtil; class TIFFFaxDecompressor extends TIFFDecompressor { @@ -637,14 +638,14 @@ this.bitsPerScanline = scanlineStride*8; this.lineBitNum = 8*dstOffset; - this.data = new byte[byteCount]; this.bitPointer = 0; this.bytePointer = 0; this.prevChangingElems = new int[w + 1]; this.currChangingElems = new int[w + 1]; stream.seek(offset); - stream.readFully(data); + this.data = ReaderUtil. + staggeredReadByteStream(stream, byteCount); if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) { decodeRLE();
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java index 423b97c..0bbe294 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFLZWDecompressor.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ import java.io.IOException; import javax.imageio.IIOException; import javax.imageio.plugins.tiff.BaselineTIFFTagSet; +import com.sun.imageio.plugins.common.ReaderUtil; class TIFFLZWDecompressor extends TIFFDecompressor { @@ -95,9 +96,8 @@ } stream.seek(offset); - - byte[] sdata = new byte[byteCount]; - stream.readFully(sdata); + byte[] sdata = ReaderUtil. + staggeredReadByteStream(stream, byteCount); if (flipBits) { for (int i = 0; i < byteCount; i++) {
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java index 6ffc1f0..9b5a746 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFNullDecompressor.java
@@ -136,12 +136,7 @@ int lastRow = activeSrcHeight - 1; for (int y = 0; y < activeSrcHeight; y++) { - int bytesRead = stream.read(b, dstOffset, activeBytesPerRow); - if (bytesRead < 0) { - throw new EOFException(); - } else if (bytesRead != activeBytesPerRow) { - break; - } + stream.readFully(b, dstOffset, activeBytesPerRow); dstOffset += scanlineStride; // Skip unneeded bytes (row suffix + row prefix). @@ -154,17 +149,10 @@ stream.seek(offset); int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8; if(bytesPerRow == scanlineStride) { - if (stream.read(b, dstOffset, bytesPerRow*srcHeight) < 0) { - throw new EOFException(); - } + stream.readFully(b, dstOffset, bytesPerRow*srcHeight); } else { for (int y = 0; y < srcHeight; y++) { - int bytesRead = stream.read(b, dstOffset, bytesPerRow); - if (bytesRead < 0) { - throw new EOFException(); - } else if (bytesRead != bytesPerRow) { - break; - } + stream.readFully(b, dstOffset, bytesPerRow); dstOffset += scanlineStride; } }
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java index 42a44a4..0a5dfe8 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFPackBitsDecompressor.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package com.sun.imageio.plugins.tiff; import java.io.IOException; +import com.sun.imageio.plugins.common.ReaderUtil; public class TIFFPackBitsDecompressor extends TIFFDecompressor { @@ -77,8 +78,8 @@ int scanlineStride) throws IOException { stream.seek(offset); - byte[] srcData = new byte[byteCount]; - stream.readFully(srcData); + byte[] srcData = ReaderUtil. + staggeredReadByteStream(stream, byteCount); int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8; byte[] buf;
diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java index 11151d8..0f10904 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFYCbCrDecompressor.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,7 +180,7 @@ super.setOffset(offset); } - public void setByteCount(int byteCount) { + public void setByteCount(int byteCount) throws IOException { if(decompressor != null) { decompressor.setByteCount(byteCount); }
diff --git a/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java b/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java index 96ca26c..9589f2a 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/AbstractDataLine.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -315,13 +315,7 @@ //boolean sendEvents = false; //long position = getLongFramePosition(); - synchronized (this) { - - if (this.active != active) { - this.active = active; - //sendEvents = true; - } - } + this.active = active; // $$kk: 11.19.99: take ACTIVE / INACTIVE / EOM events out; // putting them in is technically an API change. @@ -347,12 +341,9 @@ boolean sendEvents = false; long position = getLongFramePosition(); - synchronized (this) { - - if (this.started != started) { - this.started = started; - sendEvents = true; - } + if (this.started != started) { + this.started = started; + sendEvents = true; } if (sendEvents) {
diff --git a/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java b/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java index 53738c1..905bbad 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/AbstractLine.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -162,11 +162,9 @@ boolean sendEvents = false; long position = getLongFramePosition(); - synchronized (this) { - if (this.open != open) { - this.open = open; - sendEvents = true; - } + if (this.open != open) { + this.open = open; + sendEvents = true; } if (sendEvents) {
diff --git a/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java b/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java index de9d124..eac3037 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,12 +78,26 @@ public Soundbank getSoundbank(AudioInputStream ais) throws InvalidMidiDataException, IOException { + int MEGABYTE = 1048576; + int DEFAULT_BUFFER_SIZE = 65536; + int MAX_FRAME_SIZE = 1024; try { byte[] buffer; - if (ais.getFrameLength() == -1) { + int frameSize = ais.getFormat().getFrameSize(); + if (frameSize <= 0 || frameSize > MAX_FRAME_SIZE) { + throw new InvalidMidiDataException("Formats with frame size " + + frameSize + " are not supported"); + } + + long totalSize = ais.getFrameLength() * frameSize; + if (totalSize >= Integer.MAX_VALUE - 2) { + throw new InvalidMidiDataException( + "Can not allocate enough memory to read audio data."); + } + + if (ais.getFrameLength() == -1 || totalSize > MEGABYTE) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buff = new byte[1024 - - (1024 % ais.getFormat().getFrameSize())]; + byte[] buff = new byte[DEFAULT_BUFFER_SIZE - (DEFAULT_BUFFER_SIZE % frameSize)]; int ret; while ((ret = ais.read(buff)) != -1) { baos.write(buff, 0, ret); @@ -91,8 +105,7 @@ ais.close(); buffer = baos.toByteArray(); } else { - buffer = new byte[(int) (ais.getFrameLength() - * ais.getFormat().getFrameSize())]; + buffer = new byte[(int) totalSize]; new DataInputStream(ais).readFully(buffer); } ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
diff --git a/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java b/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java index b016bed..74e3075 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1252,7 +1252,7 @@ } @Override - public synchronized void setMicrosecondPosition(long microseconds) { + public void setMicrosecondPosition(long microseconds) { if (Printer.trace) Printer.trace("> DirectClip: setMicrosecondPosition: " + microseconds); long frames = Toolkit.micros2frames(getFormat(), microseconds);
diff --git a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java index e13bae6..6f5a4bb 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileReader.java
@@ -392,6 +392,10 @@ // meta int metaType = readUnsigned(); int metaLength = (int) readVarInt(); + if (metaLength < 0) { + throw new InvalidMidiDataException("length out of bounds: " + + metaLength); + } final byte[] metaData; try { metaData = new byte[metaLength];
diff --git a/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java b/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java index 2c3be15..f8365f7 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java
@@ -73,6 +73,10 @@ samplerate = chunk.readUnsignedInt(); /* framerate = */chunk.readUnsignedInt(); framesize = chunk.readUnsignedShort(); + if (framesize == 0) { + throw new UnsupportedAudioFileException( + "Can not process audio format with 0 frame size"); + } bits = chunk.readUnsignedShort(); } if (chunk.getFormat().equals("data")) {
diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index b46fc2b..7f4b860 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,9 @@ import sun.awt.image.SunWritableRaster; import sun.java2d.SunGraphicsEnvironment; +import static sun.java2d.SunGraphicsEnvironment.toDeviceSpace; +import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs; + /** * This class is used to generate native system input events * for the purposes of test automation, self-running demos, and @@ -134,8 +137,6 @@ Toolkit toolkit = Toolkit.getDefaultToolkit(); if (toolkit instanceof ComponentFactory) { peer = ((ComponentFactory)toolkit).createRobot(this, screen); - disposer = new RobotDisposer(peer); - sun.java2d.Disposer.addRecord(anchor, disposer); } initLegalButtonMask(); } @@ -177,22 +178,6 @@ } } - private transient Object anchor = new Object(); - - static class RobotDisposer implements sun.java2d.DisposerRecord { - private final RobotPeer peer; - public RobotDisposer(RobotPeer peer) { - this.peer = peer; - } - public void dispose() { - if (peer != null) { - peer.dispose(); - } - } - } - - private transient RobotDisposer disposer; - /** * Moves mouse pointer to given screen coordinates. * @param x X position @@ -395,13 +380,9 @@ */ public synchronized Color getPixelColor(int x, int y) { checkScreenCaptureAllowed(); - AffineTransform tx = GraphicsEnvironment. - getLocalGraphicsEnvironment().getDefaultScreenDevice(). - getDefaultConfiguration().getDefaultTransform(); - x = (int) (x * tx.getScaleX()); - y = (int) (y * tx.getScaleY()); - Color color = new Color(peer.getRGBPixel(x, y)); - return color; + Point point = peer.useAbsoluteCoordinates() ? toDeviceSpaceAbs(x, y) + : toDeviceSpace(x, y); + return new Color(peer.getRGBPixel(point.x, point.y)); } /** @@ -534,16 +515,17 @@ } else { - int sX = (int) Math.floor(screenRect.x * uiScaleX); - int sY = (int) Math.floor(screenRect.y * uiScaleY); - int sWidth = (int) Math.ceil(screenRect.width * uiScaleX); - int sHeight = (int) Math.ceil(screenRect.height * uiScaleY); - int temppixels[]; - Rectangle scaledRect = new Rectangle(sX, sY, sWidth, sHeight); - temppixels = peer.getRGBPixels(scaledRect); + Rectangle scaledRect; + if (peer.useAbsoluteCoordinates()) { + scaledRect = toDeviceSpaceAbs(gc, screenRect.x, + screenRect.y, screenRect.width, screenRect.height); + } else { + scaledRect = toDeviceSpace(gc, screenRect.x, + screenRect.y, screenRect.width, screenRect.height); + } // HighResolutionImage - pixels = temppixels; + pixels = peer.getRGBPixels(scaledRect); buffer = new DataBufferInt(pixels, pixels.length); raster = Raster.createPackedRaster(buffer, scaledRect.width, scaledRect.height, scaledRect.width, bandmasks, null);
diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java index 9c3da21..de99302 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java
@@ -864,7 +864,7 @@ ProfileDeferralInfo pInfo = new ProfileDeferralInfo("CIEXYZ.pf", ColorSpace.TYPE_XYZ, 3, - CLASS_DISPLAY); + CLASS_ABSTRACT); XYZprofile = getDeferredInstance(pInfo); } thisProfile = XYZprofile; @@ -880,7 +880,7 @@ ProfileDeferralInfo pInfo = new ProfileDeferralInfo("PYCC.pf", ColorSpace.TYPE_3CLR, 3, - CLASS_DISPLAY); + CLASS_COLORSPACECONVERSION); PYCCprofile = getDeferredInstance(pInfo); } else { throw new IllegalArgumentException( @@ -1030,10 +1030,10 @@ static byte[] getProfileDataFromStream(InputStream s) throws IOException { BufferedInputStream bis = new BufferedInputStream(s); - bis.mark(128); + bis.mark(128); // 128 is the length of the ICC profile header byte[] header = bis.readNBytes(128); - if (header[36] != 0x61 || header[37] != 0x63 || + if (header.length < 128 || header[36] != 0x61 || header[37] != 0x63 || header[38] != 0x73 || header[39] != 0x70) { return null; /* not a valid profile */ }
diff --git a/src/java.desktop/share/classes/java/awt/font/TextJustifier.java b/src/java.desktop/share/classes/java/awt/font/TextJustifier.java index b00b00f..11fb03d 100644 --- a/src/java.desktop/share/classes/java/awt/font/TextJustifier.java +++ b/src/java.desktop/share/classes/java/awt/font/TextJustifier.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,10 +155,13 @@ boolean absorbing = hitLimit && absorbweight > 0; // predivide delta by weight - float weightedDelta = delta / weight; // not used if weight == 0 + float weightedDelta = 0; + if (weight != 0) { // not used if weight == 0 + weightedDelta = delta / weight; + } float weightedAbsorb = 0; - if (hitLimit && absorbweight > 0) { + if (hitLimit && absorbweight != 0) { weightedAbsorb = (delta - gslimit) / absorbweight; }
diff --git a/src/java.desktop/share/classes/java/awt/peer/RobotPeer.java b/src/java.desktop/share/classes/java/awt/peer/RobotPeer.java index 36a74a0..10a9018 100644 --- a/src/java.desktop/share/classes/java/awt/peer/RobotPeer.java +++ b/src/java.desktop/share/classes/java/awt/peer/RobotPeer.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ package java.awt.peer; -import java.awt.*; +import java.awt.Rectangle; +import java.awt.Robot; /** * RobotPeer defines an interface whereby toolkits support automated testing @@ -118,7 +119,12 @@ int[] getRGBPixels(Rectangle bounds); /** - * Disposes the robot peer when it is not needed anymore. + * Determines if absolute coordinates should be used by this peer. + * + * @return {@code true} if absolute coordinates should be used, + * {@code false} otherwise */ - void dispose(); + default boolean useAbsoluteCoordinates() { + return false; + } }
diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java index 3faf2d8..4984d38 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java
@@ -757,8 +757,11 @@ } /** - * Find the new toggle button that focus needs to be + * Find the new toggle/radio button that focus needs to be * moved to in the group, select the button + * In case of radio button, setPressed and setArmed is called + * on the button model, so that Action set on button is performed + * on selecting the button * * @param next, indicate if it's arrow up/left or down/right */ @@ -780,12 +783,16 @@ if (newSelectedBtn != null && (newSelectedBtn != activeBtn)) { ButtonModel btnModel = newSelectedBtn.getModel(); - btnModel.setPressed(true); - btnModel.setArmed(true); + if (newSelectedBtn instanceof JRadioButton) { + btnModel.setPressed(true); + btnModel.setArmed(true); + } newSelectedBtn.requestFocusInWindow(); newSelectedBtn.setSelected(true); - btnModel.setPressed(false); - btnModel.setArmed(false); + if (newSelectedBtn instanceof JRadioButton) { + btnModel.setPressed(false); + btnModel.setArmed(false); + } } } }
diff --git a/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java b/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java index 5da9a27..860f1a3 100644 --- a/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java +++ b/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java
@@ -465,7 +465,7 @@ public float nextTabStop(float x, int tabOffset) { if (tabSize == 0) return x; - float ntabs = (x - tabBase) / tabSize; + int ntabs = (int) ((x - tabBase) / tabSize); return tabBase + ((ntabs + 1) * tabSize); }
diff --git a/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/src/java.desktop/share/classes/sun/awt/SunToolkit.java index 97b9daf..be097df 100644 --- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1408,15 +1408,6 @@ } @SuppressWarnings("serial") - public static class OperationTimedOut extends RuntimeException { - public OperationTimedOut(String msg) { - super(msg); - } - public OperationTimedOut() { - } - } - - @SuppressWarnings("serial") public static class IllegalThreadException extends RuntimeException { public IllegalThreadException(String msg) { super(msg); @@ -1433,7 +1424,7 @@ /** * Parameterless version of realsync which uses default timout (see DEFAUL_WAIT_TIME). */ - public void realSync() throws OperationTimedOut { + public void realSync() { realSync(DEFAULT_WAIT_TIME); } @@ -1482,7 +1473,7 @@ * * @param timeout the maximum time to wait in milliseconds, negative means "forever". */ - public void realSync(final long timeout) throws OperationTimedOut { + public void realSync(final long timeout) { if (EventQueue.isDispatchThread()) { throw new IllegalThreadException("The SunToolkit.realSync() method cannot be used on the event dispatch thread (EDT)."); } @@ -1538,7 +1529,7 @@ && bigLoop < MAX_ITERS); } - private long timeout(long end){ + protected long timeout(long end){ return end - TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); } @@ -1568,6 +1559,9 @@ */ @SuppressWarnings("serial") private final boolean waitForIdle(final long end) { + if (timeout(end) <= 0) { + return false; + } flushPendingEvents(); final boolean queueWasEmpty; final AtomicBoolean queueEmpty = new AtomicBoolean();
diff --git a/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java b/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java index 4c3750d..f5e0a4b 100644 --- a/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java +++ b/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java
@@ -151,34 +151,9 @@ this.key = key; } - static WeakHashMap<Font2D, Boolean> aatInfo = new WeakHashMap<>(); private static final WeakHashMap<Font2D, FaceRef> facePtr = new WeakHashMap<>(); - private static boolean isAAT(Font2D font) { - Boolean aatObj; - synchronized (aatInfo) { - aatObj = aatInfo.get(font); - } - if (aatObj != null) { - return aatObj.booleanValue(); - } - boolean aat = false; - if (font instanceof TrueTypeFont) { - TrueTypeFont ttf = (TrueTypeFont)font; - aat = ttf.getDirectoryEntry(TrueTypeFont.morxTag) != null || - ttf.getDirectoryEntry(TrueTypeFont.mortTag) != null; - } else if (font instanceof PhysicalFont) { - PhysicalFont pf = (PhysicalFont)font; - aat = pf.getTableBytes(TrueTypeFont.morxTag) != null || - pf.getTableBytes(TrueTypeFont.mortTag) != null; - } - synchronized (aatInfo) { - aatInfo.put(font, Boolean.valueOf(aat)); - } - return aat; - } - private long getFacePtr(Font2D font2D) { FaceRef ref; synchronized (facePtr) { @@ -192,11 +167,9 @@ Point2D.Float pt, GVData data) { Font2D font = key.font(); FontStrike strike = font.getStrike(desc); - long pNativeFont = font.getPlatformNativeFontPtr(); // used on OSX long pFace = getFacePtr(font); if (pFace != 0) { - shape(font, strike, ptSize, mat, pNativeFont, - pFace, isAAT(font), + shape(font, strike, ptSize, mat, pFace, tr.text, data, key.script(), tr.start, tr.limit, baseIndex, pt, typo_flags, gmask); @@ -206,13 +179,12 @@ /* Native method to invoke harfbuzz layout engine */ private static native boolean shape(Font2D font, FontStrike strike, float ptSize, float[] mat, - long pNativeFont, long pFace, boolean aat, + long pFace, char[] chars, GVData data, int script, int offset, int limit, int baseIndex, Point2D.Float pt, int typo_flags, int slot); private static native long createFace(Font2D font, - boolean aat, long platformNativeFontPtr); private static native void disposeFace(long facePtr); @@ -227,7 +199,7 @@ private synchronized long getNativePtr() { if (facePtr == null) { - facePtr = createFace(font, isAAT(font), + facePtr = createFace(font, font.getPlatformNativeFontPtr()); if (facePtr != 0) { Disposer.addObjectRecord(font, this);
diff --git a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java index 8c16c1d..51cf3c7 100644 --- a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java +++ b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
@@ -582,7 +582,9 @@ /* checksum */ ibuffer.get(); table.offset = ibuffer.get() & 0x7FFFFFFF; table.length = ibuffer.get() & 0x7FFFFFFF; - if (table.offset + table.length > fileSize) { + if ((table.offset + table.length < table.length) || + (table.offset + table.length > fileSize)) + { throw new FontFormatException("bad table, tag="+table.tag); } } @@ -877,8 +879,11 @@ break; } } + if (entry == null || entry.length == 0 || - entry.offset+entry.length > fileSize) { + (entry.offset + entry.length < entry.length) || + (entry.offset + entry.length > fileSize)) + { return null; } @@ -967,6 +972,9 @@ return false; } ByteBuffer eblcTable = getTableBuffer(EBLCTag); + if (eblcTable == null) { + return false; + } int numSizes = eblcTable.getInt(4); /* The bitmapSizeTable's start at offset of 8. * Each bitmapSizeTable entry is 48 bytes.
diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java b/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java index a928d78..47a4689 100644 --- a/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java
@@ -27,6 +27,7 @@ import java.awt.AWTError; import java.awt.Color; +import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; @@ -401,53 +402,124 @@ } /** + * Returns the bounds of the graphics configuration in device space. + * + * @param config the graphics configuration which bounds are requested + * @return the bounds of the area covered by this + * {@code GraphicsConfiguration} in device space (pixels) + */ + public static Rectangle getGCDeviceBounds(GraphicsConfiguration config) { + AffineTransform tx = config.getDefaultTransform(); + Rectangle bounds = config.getBounds(); + bounds.width *= tx.getScaleX(); + bounds.height *= tx.getScaleY(); + return bounds; + } + + /** + * Converts the size (w, h) from the device space to the user's space using + * passed graphics configuration. + * + * @param gc the graphics configuration to be used for transformation + * @param w the width in the device space + * @param h the height in the device space + * @return the size in the user's space + */ + public static Dimension toUserSpace(GraphicsConfiguration gc, + int w, int h) { + AffineTransform tx = gc.getDefaultTransform(); + return new Dimension( + Region.clipRound(w / tx.getScaleX()), + Region.clipRound(h / tx.getScaleY()) + ); + } + + /** + * Converts absolute coordinates from the user's space to the device space + * using appropriate device transformation. + * + * @param x absolute coordinate in the user's space + * @param y absolute coordinate in the user's space + * @return the point which uses device space (pixels) + */ + public static Point toDeviceSpaceAbs(int x, int y) { + GraphicsConfiguration gc = getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration(); + gc = getGraphicsConfigurationAtPoint(gc, x, y); + return toDeviceSpaceAbs(gc, x, y, 0, 0).getLocation(); + } + + /** + * Converts the rectangle from the user's space to the device space using + * appropriate device transformation. + * + * @param rect the rectangle in the user's space + * @return the rectangle which uses device space (pixels) + */ + public static Rectangle toDeviceSpaceAbs(Rectangle rect) { + GraphicsConfiguration gc = getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration(); + gc = getGraphicsConfigurationAtPoint(gc, rect.x, rect.y); + return toDeviceSpaceAbs(gc, rect.x, rect.y, rect.width, rect.height); + } + + /** + * Converts absolute coordinates (x, y) and the size (w, h) from the user's + * space to the device space using passed graphics configuration. + * + * @param gc the graphics configuration to be used for transformation + * @param x absolute coordinate in the user's space + * @param y absolute coordinate in the user's space + * @param w the width in the user's space + * @param h the height in the user's space + * @return the rectangle which uses device space (pixels) + */ + public static Rectangle toDeviceSpaceAbs(GraphicsConfiguration gc, + int x, int y, int w, int h) { + AffineTransform tx = gc.getDefaultTransform(); + Rectangle screen = gc.getBounds(); + return new Rectangle( + screen.x + Region.clipRound((x - screen.x) * tx.getScaleX()), + screen.y + Region.clipRound((y - screen.y) * tx.getScaleY()), + Region.clipRound(w * tx.getScaleX()), + Region.clipRound(h * tx.getScaleY()) + ); + } + + /** * Converts coordinates from the user's space to the device space using * appropriate device transformation. * - * @param x coordinate in the user space - * @param y coordinate in the user space - * @return the point which uses device space(pixels) + * @param x coordinate in the user's space + * @param y coordinate in the user's space + * @return the point which uses device space (pixels) */ - public static Point convertToDeviceSpace(double x, double y) { - GraphicsConfiguration gc = getLocalGraphicsEnvironment() - .getDefaultScreenDevice().getDefaultConfiguration(); - gc = getGraphicsConfigurationAtPoint(gc, x, y); - - AffineTransform tx = gc.getDefaultTransform(); - x = Region.clipRound(x * tx.getScaleX()); - y = Region.clipRound(y * tx.getScaleY()); - return new Point((int) x, (int) y); - } - - /** - * Converts bounds from the user's space to the device space using - * appropriate device transformation. - * - * @param bounds the rectangle in the user space - * @return the rectangle which uses device space(pixels) - */ - public static Rectangle convertToDeviceSpace(Rectangle bounds) { + public static Point toDeviceSpace(int x, int y) { GraphicsConfiguration gc = getLocalGraphicsEnvironment() .getDefaultScreenDevice().getDefaultConfiguration(); - gc = getGraphicsConfigurationAtPoint(gc, bounds.x, bounds.y); - return convertToDeviceSpace(gc, bounds); + gc = getGraphicsConfigurationAtPoint(gc, x, y); + return toDeviceSpace(gc, x, y, 0, 0).getLocation(); } /** - * Converts bounds from the user's space to the device space using - * appropriate device transformation of the passed graphics configuration. + * Converts coordinates (x, y) and the size (w, h) from the user's + * space to the device space using passed graphics configuration. * - * @param bounds the rectangle in the user space - * @return the rectangle which uses device space(pixels) + * @param gc the graphics configuration to be used for transformation + * @param x coordinate in the user's space + * @param y coordinate in the user's space + * @param w the width in the user's space + * @param h the height in the user's space + * @return the rectangle which uses device space (pixels) */ - public static Rectangle convertToDeviceSpace(GraphicsConfiguration gc, - Rectangle bounds) { + public static Rectangle toDeviceSpace(GraphicsConfiguration gc, + int x, int y, int w, int h) { AffineTransform tx = gc.getDefaultTransform(); return new Rectangle( - Region.clipRound(bounds.x * tx.getScaleX()), - Region.clipRound(bounds.y * tx.getScaleY()), - Region.clipRound(bounds.width * tx.getScaleX()), - Region.clipRound(bounds.height * tx.getScaleY()) + Region.clipRound(x * tx.getScaleX()), + Region.clipRound(y * tx.getScaleY()), + Region.clipRound(w * tx.getScaleX()), + Region.clipRound(h * tx.getScaleY()) ); } }
diff --git a/src/java.desktop/share/native/libfontmanager/HBShaper.c b/src/java.desktop/share/native/libfontmanager/HBShaper.c index c431b12..ffb3419 100644 --- a/src/java.desktop/share/native/libfontmanager/HBShaper.c +++ b/src/java.desktop/share/native/libfontmanager/HBShaper.c
@@ -28,9 +28,6 @@ #include "hb.h" #include "hb-jdk.h" #include "hb-ot.h" -#ifdef MACOSX -#include "hb-coretext.h" -#endif #include "scriptMapping.h" static jclass gvdClass = 0; @@ -201,9 +198,7 @@ jobject font2D, jobject fontStrike, jfloat ptSize, - jlong pNativeFont, - jfloatArray matrix, - jboolean aat) { + jfloatArray matrix) { JDKFontInfo *fi = (JDKFontInfo*)malloc(sizeof(JDKFontInfo)); @@ -213,13 +208,11 @@ fi->env = env; // this is valid only for the life of this JNI call. fi->font2D = font2D; fi->fontStrike = fontStrike; - fi->nativeFont = pNativeFont; - fi->aat = aat; (*env)->GetFloatArrayRegion(env, matrix, 0, 4, fi->matrix); fi->ptSize = ptSize; fi->xPtSize = euclidianDistance(fi->matrix[0], fi->matrix[1]); fi->yPtSize = euclidianDistance(fi->matrix[2], fi->matrix[3]); - if (!aat && (getenv("HB_NODEVTX") != NULL)) { + if (getenv("HB_NODEVTX") != NULL) { fi->devScale = fi->xPtSize / fi->ptSize; } else { fi->devScale = 1.0f; @@ -238,9 +231,7 @@ jobject fontStrike, jfloat ptSize, jfloatArray matrix, - jlong pNativeFont, jlong pFace, - jboolean aat, jcharArray text, jobject gvdata, jint script, @@ -268,8 +259,7 @@ unsigned int buflen; JDKFontInfo *jdkFontInfo = - createJDKFontInfo(env, font2D, fontStrike, ptSize, - pNativeFont, matrix, aat); + createJDKFontInfo(env, font2D, fontStrike, ptSize, matrix); if (!jdkFontInfo) { return JNI_FALSE; }
diff --git a/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc b/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc index 8618d90..77fda4a 100644 --- a/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc +++ b/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc
@@ -28,9 +28,6 @@ #include "hb.h" #include "hb-jdk.h" -#ifdef MACOSX -#include "hb-coretext.h" -#endif #include <stdlib.h> #if defined(__GNUC__) && __GNUC__ >= 4 @@ -366,19 +363,12 @@ /* * Class: sun_font_SunLayoutEngine * Method: createFace - * Signature: (Lsun/font/Font2D;ZJJ)J + * Signature: (Lsun/font/Font2D;JJ)J */ JNIEXPORT jlong JNICALL Java_sun_font_SunLayoutEngine_createFace(JNIEnv *env, jclass cls, jobject font2D, - jboolean aat, jlong platformFontPtr) { -#ifdef MACOSX - if (aat && platformFontPtr) { - hb_face_t *face = hb_coretext_face_create((CGFontRef)platformFontPtr); - return ptr_to_jlong(face); - } -#endif Font2DPtr *fi = (Font2DPtr*)malloc(sizeof(Font2DPtr)); if (!fi) { return 0; @@ -442,10 +432,6 @@ hb_font_t* hb_jdk_font_create(hb_face_t* hbFace, JDKFontInfo *jdkFontInfo, hb_destroy_func_t destroy) { -#ifdef MACOSX - if (jdkFontInfo->aat && jdkFontInfo->nativeFont) { - return _hb_jdk_ct_font_create(hbFace, jdkFontInfo); - } -#endif + return _hb_jdk_font_create(hbFace, jdkFontInfo, destroy); }
diff --git a/src/java.desktop/share/native/libfontmanager/hb-jdk.h b/src/java.desktop/share/native/libfontmanager/hb-jdk.h index 8013923..71cac70 100644 --- a/src/java.desktop/share/native/libfontmanager/hb-jdk.h +++ b/src/java.desktop/share/native/libfontmanager/hb-jdk.h
@@ -38,13 +38,11 @@ JNIEnv* env; jobject font2D; jobject fontStrike; - long nativeFont; float matrix[4]; float ptSize; float xPtSize; float yPtSize; float devScale; // How much applying the full glyph tx scales x distance. - jboolean aat; } JDKFontInfo;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh index 6971c2e..f44bf43 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh
@@ -133,10 +133,11 @@ region_count = varStore->varStore.get_region_index_count (get_ivs ()); if (do_blend) { - scalars.resize (region_count); - varStore->varStore.get_scalars (get_ivs (), - (int *)coords, num_coords, - &scalars[0], region_count); + if (unlikely (!scalars.resize (region_count))) + set_error (); + else + varStore->varStore.get_scalars (get_ivs (), (int *)coords, num_coords, + &scalars[0], region_count); } seen_blend = true; }
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-coretext.cc b/src/java.desktop/share/native/libharfbuzz/hb-coretext.cc deleted file mode 100644 index f8d0308..0000000 --- a/src/java.desktop/share/native/libharfbuzz/hb-coretext.cc +++ /dev/null
@@ -1,1206 +0,0 @@ -/* - * Copyright © 2012,2013 Mozilla Foundation. - * Copyright © 2012,2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" -#include "hb-shaper-impl.hh" - -#include "hb-coretext.h" -#include "hb-aat-layout.hh" -#include <math.h> - - -/** - * SECTION:hb-coretext - * @title: hb-coretext - * @short_description: CoreText integration - * @include: hb-coretext.h - * - * Functions for using HarfBuzz with the CoreText fonts. - **/ - -/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ -#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f - -static CGFloat -coretext_font_size_from_ptem (float ptem) -{ - /* CoreText points are CSS pixels (96 per inch), - * NOT typographic points (72 per inch). - * - * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html - */ - ptem *= 96.f / 72.f; - return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem; -} -static float -coretext_font_size_to_ptem (CGFloat size) -{ - size *= 72.f / 96.f; - return size <= 0.f ? 0 : size; -} - -static void -release_table_data (void *user_data) -{ - CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data); - CFRelease(cf_data); -} - -static hb_blob_t * -reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) -{ - CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data); - CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); - if (unlikely (!cf_data)) - return nullptr; - - const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data)); - const size_t length = CFDataGetLength (cf_data); - if (!data || !length) - { - CFRelease (cf_data); - return nullptr; - } - - return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, - reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)), - release_table_data); -} - -static void -_hb_cg_font_release (void *data) -{ - CGFontRelease ((CGFontRef) data); -} - - -static CTFontDescriptorRef -get_last_resort_font_desc () -{ - // TODO Handle allocation failures? - CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); - CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, - (const void **) &last_resort, - 1, - &kCFTypeArrayCallBacks); - CFRelease (last_resort); - CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, - (const void **) &kCTFontCascadeListAttribute, - (const void **) &cascade_list, - 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease (cascade_list); - - CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); - CFRelease (attributes); - return font_desc; -} - -static void -release_data (void *info, const void *data, size_t size) -{ - assert (hb_blob_get_length ((hb_blob_t *) info) == size && - hb_blob_get_data ((hb_blob_t *) info, nullptr) == data); - - hb_blob_destroy ((hb_blob_t *) info); -} - -static CGFontRef -create_cg_font (hb_face_t *face) -{ - CGFontRef cg_font = nullptr; - if (face->destroy == _hb_cg_font_release) - { - cg_font = CGFontRetain ((CGFontRef) face->user_data); - } - else - { - hb_blob_t *blob = hb_face_reference_blob (face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) - DEBUG_MSG (CORETEXT, face, "Face has empty blob"); - - CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); - if (likely (provider)) - { - cg_font = CGFontCreateWithDataProvider (provider); - if (unlikely (!cg_font)) - DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); - CGDataProviderRelease (provider); - } - } - return cg_font; -} - -static CTFontRef -create_ct_font (CGFontRef cg_font, CGFloat font_size) -{ - CTFontRef ct_font = nullptr; - - /* CoreText does not enable trak table usage / tracking when creating a CTFont - * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems - * to be through the CTFontCreateUIFontForLanguage call. */ - CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font); - if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) || - CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay"))) - { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 -# define kCTFontUIFontSystem kCTFontSystemFontType -# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType -#endif - CTFontUIFontType font_type = kCTFontUIFontSystem; - if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold"))) - font_type = kCTFontUIFontEmphasizedSystem; - - ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr); - CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font); - if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo) - { - CFRelease(ct_font); - ct_font = nullptr; - } - CFRelease (ct_result_name); - } - CFRelease (cg_postscript_name); - - if (!ct_font) - ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr); - - if (unlikely (!ct_font)) { - DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed"); - return nullptr; - } - - /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter - * bug indicate that the cascade list reconfiguration occasionally causes - * crashes in CoreText on OS X 10.9, thus let's skip this step on older - * operating system versions. Except for the emoji font, where _not_ - * reconfiguring the cascade list causes CoreText crashes. For details, see - * crbug.com/549610 */ - // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h - if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) { - CFStringRef fontName = CTFontCopyPostScriptName (ct_font); - bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; - CFRelease (fontName); - if (!isEmojiFont) - return ct_font; - } - - CFURLRef original_url = nullptr; -#if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - ATSFontRef atsFont; - FSRef fsref; - OSStatus status; - atsFont = CTFontGetPlatformFont (ct_font, NULL); - status = ATSFontGetFileReference (atsFont, &fsref); - if (status == noErr) - original_url = CFURLCreateFromFSRef (NULL, &fsref); -#else - original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute); -#endif - - /* Create font copy with cascade list that has LastResort first; this speeds up CoreText - * font fallback which we don't need anyway. */ - { - CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc (); - CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc); - CFRelease (last_resort_font_desc); - if (new_ct_font) - { - /* The CTFontCreateCopyWithAttributes call fails to stay on the same font - * when reconfiguring the cascade list and may switch to a different font - * when there are fonts that go by the same name, since the descriptor is - * just name and size. - * - * Avoid reconfiguring the cascade lists if the new font is outside the - * system locations that we cannot access from the sandboxed renderer - * process in Blink. This can be detected by the new file URL location - * that the newly found font points to. */ - CFURLRef new_url = nullptr; -#if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - atsFont = CTFontGetPlatformFont (new_ct_font, NULL); - status = ATSFontGetFileReference (atsFont, &fsref); - if (status == noErr) - new_url = CFURLCreateFromFSRef (NULL, &fsref); -#else - new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); -#endif - // Keep reconfigured font if URL cannot be retrieved (seems to be the case - // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606 - if (!original_url || !new_url || CFEqual (original_url, new_url)) { - CFRelease (ct_font); - ct_font = new_ct_font; - } else { - CFRelease (new_ct_font); - DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed."); - } - if (new_url) - CFRelease (new_url); - } - else - DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed"); - } - - if (original_url) - CFRelease (original_url); - return ct_font; -} - -hb_coretext_face_data_t * -_hb_coretext_shaper_face_data_create (hb_face_t *face) -{ - CGFontRef cg_font = create_cg_font (face); - - if (unlikely (!cg_font)) - { - DEBUG_MSG (CORETEXT, face, "CGFont creation failed.."); - return nullptr; - } - - return (hb_coretext_face_data_t *) cg_font; -} - -void -_hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data) -{ - CFRelease ((CGFontRef) data); -} - -hb_face_t * -hb_coretext_face_create (CGFontRef cg_font) -{ - return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release); -} - -/* - * Since: 0.9.10 - */ -CGFontRef -hb_coretext_face_get_cg_font (hb_face_t *face) -{ - return (CGFontRef) (const void *) face->data.coretext; -} - - -hb_coretext_font_data_t * -_hb_coretext_shaper_font_data_create (hb_font_t *font) -{ - hb_face_t *face = font->face; - const hb_coretext_face_data_t *face_data = face->data.coretext; - if (unlikely (!face_data)) return nullptr; - CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; - - CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem)); - - if (unlikely (!ct_font)) - { - DEBUG_MSG (CORETEXT, font, "CGFont creation failed.."); - return nullptr; - } - - return (hb_coretext_font_data_t *) ct_font; -} - -void -_hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data) -{ - CFRelease ((CTFontRef) data); -} - -static const hb_coretext_font_data_t * -hb_coretext_font_data_sync (hb_font_t *font) -{ -retry: - const hb_coretext_font_data_t *data = font->data.coretext; - if (unlikely (!data)) return nullptr; - - if (fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) > .5) - { - /* XXX-MT-bug - * Note that evaluating condition above can be dangerous if another thread - * got here first and destructed data. That's, as always, bad use pattern. - * If you modify the font (change font size), other threads must not be - * using it at the same time. However, since this check is delayed to - * when one actually tries to shape something, this is a XXX race condition - * (and the only one we have that I know of) right now. Ie. you modify the - * font size in one thread, then (supposedly safely) try to use it from two - * or more threads and BOOM! I'm not sure how to fix this. We want RCU. - */ - - /* Drop and recreate. */ - /* If someone dropped it in the mean time, throw it away and don't touch it. - * Otherwise, destruct it. */ - if (likely (font->data.coretext.cmpexch (const_cast<hb_coretext_font_data_t *> (data), nullptr))) - _hb_coretext_shaper_font_data_destroy (const_cast<hb_coretext_font_data_t *> (data)); - else - goto retry; - } - return font->data.coretext; -} - - -/* - * Since: 1.7.2 - */ -hb_font_t * -hb_coretext_font_create (CTFontRef ct_font) -{ - CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr); - hb_face_t *face = hb_coretext_face_create (cg_font); - CFRelease (cg_font); - hb_font_t *font = hb_font_create (face); - hb_face_destroy (face); - - if (unlikely (hb_object_is_immutable (font))) - return font; - - hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font))); - - /* Let there be dragons here... */ - font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); - - return font; -} - -CTFontRef -hb_coretext_font_get_ct_font (hb_font_t *font) -{ - const hb_coretext_font_data_t *data = hb_coretext_font_data_sync (font); - return data ? (CTFontRef) data : nullptr; -} - - -/* - * shaper - */ - -struct feature_record_t { - unsigned int feature; - unsigned int setting; -}; - -struct active_feature_t { - feature_record_t rec; - unsigned int order; - - static int cmp (const void *pa, const void *pb) { - const active_feature_t *a = (const active_feature_t *) pa; - const active_feature_t *b = (const active_feature_t *) pb; - return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 : - a->order < b->order ? -1 : a->order > b->order ? 1 : - a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 : - 0; - } - bool operator== (const active_feature_t *f) { - return cmp (this, f) == 0; - } -}; - -struct feature_event_t { - unsigned int index; - bool start; - active_feature_t feature; - - static int cmp (const void *pa, const void *pb) { - const feature_event_t *a = (const feature_event_t *) pa; - const feature_event_t *b = (const feature_event_t *) pb; - return a->index < b->index ? -1 : a->index > b->index ? 1 : - a->start < b->start ? -1 : a->start > b->start ? 1 : - active_feature_t::cmp (&a->feature, &b->feature); - } -}; - -struct range_record_t { - CTFontRef font; - unsigned int index_first; /* == start */ - unsigned int index_last; /* == end - 1 */ -}; - - -hb_bool_t -_hb_coretext_shape (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) -{ - hb_face_t *face = font->face; - CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; - CTFontRef ct_font = (CTFontRef) hb_coretext_font_data_sync (font); - - CGFloat ct_font_size = CTFontGetSize (ct_font); - CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; - CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size; - - /* Attach marks to their bases, to match the 'ot' shaper. - * Adapted from a very old version of hb-ot-shape:hb_form_clusters(). - * Note that this only makes us be closer to the 'ot' shaper, - * but by no means the same. For example, if there's - * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will - * continue pointing to B2 even though B2 was merged into B1's - * cluster... */ - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - { - hb_unicode_funcs_t *unicode = buffer->unicode; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 1; i < count; i++) - if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint))) - buffer->merge_clusters (i - 1, i + 1); - } - - hb_vector_t<feature_record_t> feature_records; - hb_vector_t<range_record_t> range_records; - - /* - * Set up features. - * (copied + modified from code from hb-uniscribe.cc) - */ - if (num_features) - { - /* Sort features by start/end events. */ - hb_vector_t<feature_event_t> feature_events; - for (unsigned int i = 0; i < num_features; i++) - { - const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag); - if (!mapping) - continue; - - active_feature_t feature; - feature.rec.feature = mapping->aatFeatureType; - feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable; - feature.order = i; - - feature_event_t *event; - - event = feature_events.push (); - event->index = features[i].start; - event->start = true; - event->feature = feature; - - event = feature_events.push (); - event->index = features[i].end; - event->start = false; - event->feature = feature; - } - feature_events.qsort (); - /* Add a strategic final event. */ - { - active_feature_t feature; - feature.rec.feature = HB_TAG_NONE; - feature.rec.setting = 0; - feature.order = num_features + 1; - - feature_event_t *event = feature_events.push (); - event->index = 0; /* This value does magic. */ - event->start = false; - event->feature = feature; - } - - /* Scan events and save features for each range. */ - hb_vector_t<active_feature_t> active_features; - unsigned int last_index = 0; - for (unsigned int i = 0; i < feature_events.length; i++) - { - feature_event_t *event = &feature_events[i]; - - if (event->index != last_index) - { - /* Save a snapshot of active features and the range. */ - range_record_t *range = range_records.push (); - - if (active_features.length) - { - CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - /* TODO sort and resolve conflicting features? */ - /* active_features.qsort (); */ - for (unsigned int j = 0; j < active_features.length; j++) - { - CFStringRef keys[] = { - kCTFontFeatureTypeIdentifierKey, - kCTFontFeatureSelectorIdentifierKey - }; - CFNumberRef values[] = { - CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature), - CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting) - }; - static_assert ((ARRAY_LENGTH_CONST (keys) == ARRAY_LENGTH_CONST (values)), ""); - CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault, - (const void **) keys, - (const void **) values, - ARRAY_LENGTH (keys), - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - for (unsigned int i = 0; i < ARRAY_LENGTH (values); i++) - CFRelease (values[i]); - - CFArrayAppendValue (features_array, dict); - CFRelease (dict); - - } - - CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, - (const void **) &kCTFontFeatureSettingsAttribute, - (const void **) &features_array, - 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease (features_array); - - CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); - CFRelease (attributes); - - range->font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, font_desc); - CFRelease (font_desc); - } - else - { - range->font = nullptr; - } - - range->index_first = last_index; - range->index_last = event->index - 1; - - last_index = event->index; - } - - if (event->start) - { - active_features.push (event->feature); - } else { - active_feature_t *feature = active_features.find (&event->feature); - if (feature) - active_features.remove (feature - active_features.arrayZ ()); - } - } - } - - unsigned int scratch_size; - hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); - -#define ALLOCATE_ARRAY(Type, name, len, on_no_room) \ - Type *name = (Type *) scratch; \ - { \ - unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ - if (unlikely (_consumed > scratch_size)) \ - { \ - on_no_room; \ - assert (0); \ - } \ - scratch += _consumed; \ - scratch_size -= _consumed; \ - } - - ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/); - unsigned int chars_len = 0; - for (unsigned int i = 0; i < buffer->len; i++) { - hb_codepoint_t c = buffer->info[i].codepoint; - if (likely (c <= 0xFFFFu)) - pchars[chars_len++] = c; - else if (unlikely (c > 0x10FFFFu)) - pchars[chars_len++] = 0xFFFDu; - else { - pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); - pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); - } - } - - ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/); - chars_len = 0; - for (unsigned int i = 0; i < buffer->len; i++) - { - hb_codepoint_t c = buffer->info[i].codepoint; - unsigned int cluster = buffer->info[i].cluster; - log_clusters[chars_len++] = cluster; - if (hb_in_range (c, 0x10000u, 0x10FFFFu)) - log_clusters[chars_len++] = cluster; /* Surrogates. */ - } - -#define FAIL(...) \ - HB_STMT_START { \ - DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \ - ret = false; \ - goto fail; \ - } HB_STMT_END; - - bool ret = true; - CFStringRef string_ref = nullptr; - CTLineRef line = nullptr; - - if (false) - { -resize_and_retry: - DEBUG_MSG (CORETEXT, buffer, "Buffer resize"); - /* string_ref uses the scratch-buffer for backing store, and line references - * string_ref (via attr_string). We must release those before resizing buffer. */ - assert (string_ref); - assert (line); - CFRelease (string_ref); - CFRelease (line); - string_ref = nullptr; - line = nullptr; - - /* Get previous start-of-scratch-area, that we use later for readjusting - * our existing scratch arrays. */ - unsigned int old_scratch_used; - hb_buffer_t::scratch_buffer_t *old_scratch; - old_scratch = buffer->get_scratch_buffer (&old_scratch_used); - old_scratch_used = scratch - old_scratch; - - if (unlikely (!buffer->ensure (buffer->allocated * 2))) - FAIL ("Buffer resize failed"); - - /* Adjust scratch, pchars, and log_cluster arrays. This is ugly, but really the - * cleanest way to do without completely restructuring the rest of this shaper. */ - scratch = buffer->get_scratch_buffer (&scratch_size); - pchars = reinterpret_cast<UniChar *> (((char *) scratch + ((char *) pchars - (char *) old_scratch))); - log_clusters = reinterpret_cast<unsigned int *> (((char *) scratch + ((char *) log_clusters - (char *) old_scratch))); - scratch += old_scratch_used; - scratch_size -= old_scratch_used; - } - { - string_ref = CFStringCreateWithCharactersNoCopy (nullptr, - pchars, chars_len, - kCFAllocatorNull); - if (unlikely (!string_ref)) - FAIL ("CFStringCreateWithCharactersNoCopy failed"); - - /* Create an attributed string, populate it, and create a line from it, then release attributed string. */ - { - CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (kCFAllocatorDefault, - chars_len); - if (unlikely (!attr_string)) - FAIL ("CFAttributedStringCreateMutable failed"); - CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref); - if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) - { - CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), - kCTVerticalFormsAttributeName, kCFBooleanTrue); - } - - if (buffer->props.language) - { -/* What's the iOS equivalent of this check? - * The symbols was introduced in iOS 7.0. - * At any rate, our fallback is safe and works fine. */ -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 -# define kCTLanguageAttributeName CFSTR ("NSLanguage") -#endif - CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault, - hb_language_to_string (buffer->props.language), - kCFStringEncodingUTF8, - kCFAllocatorNull); - if (unlikely (!lang)) - { - CFRelease (attr_string); - FAIL ("CFStringCreateWithCStringNoCopy failed"); - } - CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), - kCTLanguageAttributeName, lang); - CFRelease (lang); - } - CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), - kCTFontAttributeName, ct_font); - - if (num_features && range_records.length) - { - unsigned int start = 0; - range_record_t *last_range = &range_records[0]; - for (unsigned int k = 0; k < chars_len; k++) - { - range_record_t *range = last_range; - while (log_clusters[k] < range->index_first) - range--; - while (log_clusters[k] > range->index_last) - range++; - if (range != last_range) - { - if (last_range->font) - CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, k - start), - kCTFontAttributeName, last_range->font); - - start = k; - } - - last_range = range; - } - if (start != chars_len && last_range->font) - CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, chars_len - start), - kCTFontAttributeName, last_range->font); - } - /* Enable/disable kern if requested. - * - * Note: once kern is disabled, reenabling it doesn't currently seem to work in CoreText. - */ - if (num_features) - { - unsigned int zeroint = 0; - CFNumberRef zero = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &zeroint); - for (unsigned int i = 0; i < num_features; i++) - { - const hb_feature_t &feature = features[i]; - if (feature.tag == HB_TAG('k','e','r','n') && - feature.start < chars_len && feature.start < feature.end) - { - CFRange feature_range = CFRangeMake (feature.start, - MIN (feature.end, chars_len) - feature.start); - if (feature.value) - CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName); - else - CFAttributedStringSetAttribute (attr_string, feature_range, kCTKernAttributeName, zero); - } - } - CFRelease (zero); - } - - int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; - CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level); -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel; -#endif - CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault, - (const void **) &kCTTypesetterOptionForcedEmbeddingLevel, - (const void **) &level_number, - 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease (level_number); - if (unlikely (!options)) - { - CFRelease (attr_string); - FAIL ("CFDictionaryCreate failed"); - } - - CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options); - CFRelease (options); - CFRelease (attr_string); - if (unlikely (!typesetter)) - FAIL ("CTTypesetterCreateWithAttributedStringAndOptions failed"); - - line = CTTypesetterCreateLine (typesetter, CFRangeMake(0, 0)); - CFRelease (typesetter); - if (unlikely (!line)) - FAIL ("CTTypesetterCreateLine failed"); - } - - CFArrayRef glyph_runs = CTLineGetGlyphRuns (line); - unsigned int num_runs = CFArrayGetCount (glyph_runs); - DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs); - - buffer->len = 0; - uint32_t status_and = ~0, status_or = 0; - double advances_so_far = 0; - /* For right-to-left runs, CoreText returns the glyphs positioned such that - * any trailing whitespace is to the left of (0,0). Adjust coordinate system - * to fix for that. Test with any RTL string with trailing spaces. - * https://crbug.com/469028 - */ - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - { - advances_so_far -= CTLineGetTrailingWhitespaceWidth (line); - if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) - advances_so_far = -advances_so_far; - } - - const CFRange range_all = CFRangeMake (0, 0); - - for (unsigned int i = 0; i < num_runs; i++) - { - CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i)); - CTRunStatus run_status = CTRunGetStatus (run); - status_or |= run_status; - status_and &= run_status; - DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status); - double run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr); - if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) - run_advance = -run_advance; - DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); - - /* CoreText does automatic font fallback (AKA "cascading") for characters - * not supported by the requested font, and provides no way to turn it off, - * so we must detect if the returned run uses a font other than the requested - * one and fill in the buffer with .notdef glyphs instead of random glyph - * indices from a different font. - */ - CFDictionaryRef attributes = CTRunGetAttributes (run); - CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName)); - if (!CFEqual (run_ct_font, ct_font)) - { - /* The run doesn't use our main font instance. We have to figure out - * whether font fallback happened, or this is just CoreText giving us - * another CTFont using the same underlying CGFont. CoreText seems - * to do that in a variety of situations, one of which being vertical - * text, but also perhaps for caching reasons. - * - * First, see if it uses any of our subfonts created to set font features... - * - * Next, compare the CGFont to the one we used to create our fonts. - * Even this doesn't work all the time. - * - * Finally, we compare PS names, which I don't think are unique... - * - * Looks like if we really want to be sure here we have to modify the - * font to change the name table, similar to what we do in the uniscribe - * backend. - * - * However, even that wouldn't work if we were passed in the CGFont to - * construct a hb_face to begin with. - * - * See: https://github.com/harfbuzz/harfbuzz/pull/36 - * - * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098 - */ - bool matched = false; - for (unsigned int i = 0; i < range_records.length; i++) - if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font)) - { - matched = true; - break; - } - if (!matched) - { - CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, nullptr); - if (run_cg_font) - { - matched = CFEqual (run_cg_font, cg_font); - CFRelease (run_cg_font); - } - } - if (!matched) - { - CFStringRef font_ps_name = CTFontCopyName (ct_font, kCTFontPostScriptNameKey); - CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey); - CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0); - CFRelease (run_ps_name); - CFRelease (font_ps_name); - if (result == kCFCompareEqualTo) - matched = true; - } - if (!matched) - { - CFRange range = CTRunGetStringRange (run); - DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld", - range.location, range.location + range.length); - if (!buffer->ensure_inplace (buffer->len + range.length)) - goto resize_and_retry; - hb_glyph_info_t *info = buffer->info + buffer->len; - - hb_codepoint_t notdef = 0; - hb_direction_t dir = buffer->props.direction; - hb_position_t x_advance, y_advance, x_offset, y_offset; - hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance, &y_advance); - hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset); - hb_position_t advance = x_advance + y_advance; - x_offset = -x_offset; - y_offset = -y_offset; - - unsigned int old_len = buffer->len; - for (CFIndex j = range.location; j < range.location + range.length; j++) - { - UniChar ch = CFStringGetCharacterAtIndex (string_ref, j); - if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j) - { - ch = CFStringGetCharacterAtIndex (string_ref, j - 1); - if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu)) - /* This is the second of a surrogate pair. Don't need .notdef - * for this one. */ - continue; - } - if (buffer->unicode->is_default_ignorable (ch)) - continue; - - info->codepoint = notdef; - info->cluster = log_clusters[j]; - - info->mask = advance; - info->var1.i32 = x_offset; - info->var2.i32 = y_offset; - - info++; - buffer->len++; - } - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - buffer->reverse_range (old_len, buffer->len); - advances_so_far += run_advance; - continue; - } - } - - unsigned int num_glyphs = CTRunGetGlyphCount (run); - if (num_glyphs == 0) - continue; - - if (!buffer->ensure_inplace (buffer->len + num_glyphs)) - goto resize_and_retry; - - hb_glyph_info_t *run_info = buffer->info + buffer->len; - - /* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always - * succeed, and so copying data to our own buffer will be rare. Reports - * have it that this changed in OS X 10.10 Yosemite, and nullptr is returned - * frequently. At any rate, we can test that codepath by setting USE_PTR - * to false. */ - -#define USE_PTR true - -#define SCRATCH_SAVE() \ - unsigned int scratch_size_saved = scratch_size; \ - hb_buffer_t::scratch_buffer_t *scratch_saved = scratch - -#define SCRATCH_RESTORE() \ - scratch_size = scratch_size_saved; \ - scratch = scratch_saved; - - { /* Setup glyphs */ - SCRATCH_SAVE(); - const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : nullptr; - if (!glyphs) { - ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry); - CTRunGetGlyphs (run, range_all, glyph_buf); - glyphs = glyph_buf; - } - const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : nullptr; - if (!string_indices) { - ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry); - CTRunGetStringIndices (run, range_all, index_buf); - string_indices = index_buf; - } - hb_glyph_info_t *info = run_info; - for (unsigned int j = 0; j < num_glyphs; j++) - { - info->codepoint = glyphs[j]; - info->cluster = log_clusters[string_indices[j]]; - info++; - } - SCRATCH_RESTORE(); - } - { - /* Setup positions. - * Note that CoreText does not return advances for glyphs. As such, - * for all but last glyph, we use the delta position to next glyph as - * advance (in the advance direction only), and for last glyph we set - * whatever is needed to make the whole run's advance add up. */ - SCRATCH_SAVE(); - const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : nullptr; - if (!positions) { - ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry); - CTRunGetPositions (run, range_all, position_buf); - positions = position_buf; - } - hb_glyph_info_t *info = run_info; - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - { - hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult; - for (unsigned int j = 0; j < num_glyphs; j++) - { - double advance; - if (likely (j + 1 < num_glyphs)) - advance = positions[j + 1].x - positions[j].x; - else /* last glyph */ - advance = run_advance - (positions[j].x - positions[0].x); - info->mask = advance * x_mult; - info->var1.i32 = x_offset; - info->var2.i32 = positions[j].y * y_mult; - info++; - } - } - else - { - hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult; - for (unsigned int j = 0; j < num_glyphs; j++) - { - double advance; - if (likely (j + 1 < num_glyphs)) - advance = positions[j + 1].y - positions[j].y; - else /* last glyph */ - advance = run_advance - (positions[j].y - positions[0].y); - info->mask = advance * y_mult; - info->var1.i32 = positions[j].x * x_mult; - info->var2.i32 = y_offset; - info++; - } - } - SCRATCH_RESTORE(); - advances_so_far += run_advance; - } -#undef SCRATCH_RESTORE -#undef SCRATCH_SAVE -#undef USE_PTR -#undef ALLOCATE_ARRAY - - buffer->len += num_glyphs; - } - - /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel, - * or if it does, it doesn't respect it. So we get runs with wrong - * directions. As such, disable the assert... It wouldn't crash, but - * cursoring will be off... - * - * https://crbug.com/419769 - */ - if (false) - { - /* Make sure all runs had the expected direction. */ - bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - assert (bool (status_and & kCTRunStatusRightToLeft) == backward); - assert (bool (status_or & kCTRunStatusRightToLeft) == backward); - } - - buffer->clear_positions (); - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - for (unsigned int i = 0; i < count; i++) - { - pos->x_advance = info->mask; - pos->x_offset = info->var1.i32; - pos->y_offset = info->var2.i32; - - info++, pos++; - } - else - for (unsigned int i = 0; i < count; i++) - { - pos->y_advance = info->mask; - pos->x_offset = info->var1.i32; - pos->y_offset = info->var2.i32; - - info++, pos++; - } - - /* Fix up clusters so that we never return out-of-order indices; - * if core text has reordered glyphs, we'll merge them to the - * beginning of the reordered cluster. CoreText is nice enough - * to tell us whenever it has produced nonmonotonic results... - * Note that we assume the input clusters were nonmonotonic to - * begin with. - * - * This does *not* mean we'll form the same clusters as Uniscribe - * or the native OT backend, only that the cluster indices will be - * monotonic in the output buffer. */ - if (count > 1 && (status_or & kCTRunStatusNonMonotonic)) - { - hb_glyph_info_t *info = buffer->info; - if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) - { - unsigned int cluster = info[count - 1].cluster; - for (unsigned int i = count - 1; i > 0; i--) - { - cluster = MIN (cluster, info[i - 1].cluster); - info[i - 1].cluster = cluster; - } - } - else - { - unsigned int cluster = info[0].cluster; - for (unsigned int i = 1; i < count; i++) - { - cluster = MIN (cluster, info[i].cluster); - info[i].cluster = cluster; - } - } - } - } - - buffer->unsafe_to_break_all (); - -#undef FAIL - -fail: - if (string_ref) - CFRelease (string_ref); - if (line) - CFRelease (line); - - for (unsigned int i = 0; i < range_records.length; i++) - if (range_records[i].font) - CFRelease (range_records[i].font); - - return ret; -} - - -/* - * AAT shaper - */ - -/* - * shaper face data - */ - -struct hb_coretext_aat_face_data_t {}; - -hb_coretext_aat_face_data_t * -_hb_coretext_aat_shaper_face_data_create (hb_face_t *face) -{ - return hb_aat_layout_has_substitution (face) || hb_aat_layout_has_positioning (face) ? - (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; -} - -void -_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_face_data_t *data HB_UNUSED) -{ -} - - -/* - * shaper font data - */ - -struct hb_coretext_aat_font_data_t {}; - -hb_coretext_aat_font_data_t * -_hb_coretext_aat_shaper_font_data_create (hb_font_t *font) -{ - return font->data.coretext ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; -} - -void -_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_font_data_t *data HB_UNUSED) -{ -} - - -/* - * shaper - */ - -hb_bool_t -_hb_coretext_aat_shape (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) -{ - return _hb_coretext_shape (shape_plan, font, buffer, features, num_features); -}
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-coretext.h b/src/java.desktop/share/native/libharfbuzz/hb-coretext.h deleted file mode 100644 index 4b0a6f0..0000000 --- a/src/java.desktop/share/native/libharfbuzz/hb-coretext.h +++ /dev/null
@@ -1,64 +0,0 @@ -/* - * Copyright © 2012 Mozilla Foundation. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Mozilla Author(s): Jonathan Kew - */ - -#ifndef HB_CORETEXT_H -#define HB_CORETEXT_H - -#include "hb.h" - -#include <TargetConditionals.h> -#if TARGET_OS_IPHONE -# include <CoreText/CoreText.h> -# include <CoreGraphics/CoreGraphics.h> -#else -# include <ApplicationServices/ApplicationServices.h> -#endif - -HB_BEGIN_DECLS - - -#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t') -#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x') -#define HB_CORETEXT_TAG_KERX HB_TAG('k','e','r','x') - - -HB_EXTERN hb_face_t * -hb_coretext_face_create (CGFontRef cg_font); - -HB_EXTERN hb_font_t * -hb_coretext_font_create (CTFontRef ct_font); - - -HB_EXTERN CGFontRef -hb_coretext_face_get_cg_font (hb_face_t *face); - -HB_EXTERN CTFontRef -hb_coretext_font_get_ct_font (hb_font_t *font); - - -HB_END_DECLS - -#endif /* HB_CORETEXT_H */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh index 63dbfce..91418d7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh
@@ -178,7 +178,7 @@ bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (c->check_struct (this))) + if (unlikely (!c->check_struct (this))) return_trace (false); switch (u.format)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh index 5ae0359..5416949 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh
@@ -77,7 +77,7 @@ return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; unsigned int i; - unsigned int count = len; + unsigned int count = len - 1; for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) ;
diff --git a/src/java.desktop/share/native/libmlib_image/mlib_ImageAffine.h b/src/java.desktop/share/native/libmlib_image/mlib_ImageAffine.h index be21823..567d8f3 100644 --- a/src/java.desktop/share/native/libmlib_image/mlib_ImageAffine.h +++ b/src/java.desktop/share/native/libmlib_image/mlib_ImageAffine.h
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -215,7 +215,7 @@ SRC = MLIB_S32_MAX; \ if (SRC <= MLIB_S32_MIN) \ SRC = MLIB_S32_MIN; \ - DST = (mlib_s32) SRC + DST = (mlib_s32) SRC #endif /* MLIB_USE_FTOI_CLAMPING */
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java index 4bfe673..ef9589a 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,19 +22,22 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package sun.awt.X11; -import java.awt.*; -import java.awt.peer.*; +import java.awt.GraphicsConfiguration; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.peer.RobotPeer; import java.security.AccessController; -import sun.security.action.GetPropertyAction; import sun.awt.AWTAccessor; import sun.awt.SunToolkit; import sun.awt.UNIXToolkit; import sun.awt.X11GraphicsConfig; +import sun.security.action.GetPropertyAction; -class XRobotPeer implements RobotPeer { +final class XRobotPeer implements RobotPeer { static final boolean tryGtk; static { @@ -70,11 +73,6 @@ } @Override - public void dispose() { - // does nothing - } - - @Override public void mouseMove(int x, int y) { mouseMoveImpl(xgc, xgc.scaleUp(x), xgc.scaleUp(y)); }
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index 95ad7c9..eafabd4 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java
@@ -126,6 +126,7 @@ import java.util.SortedMap; import java.util.TreeMap; import java.util.Vector; +import java.util.concurrent.TimeUnit; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; @@ -2583,7 +2584,7 @@ * @inheritDoc */ @Override - protected boolean syncNativeQueue(final long timeout) { + protected boolean syncNativeQueue(long timeout) { if (timeout <= 0) { return false; } @@ -2608,31 +2609,33 @@ oops_updated = false; long event_number = getEventNumber(); - // Generate OOPS ConfigureNotify event - XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(), - win.scaleUp(++oops_position), 0); // Change win position each time to avoid system optimization + oops_position += 5; if (oops_position > 50) { oops_position = 0; } + // Generate OOPS ConfigureNotify event + XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(), + oops_position, 0); XSync(); eventLog.finer("Generated OOPS ConfigureNotify event"); - long start = System.currentTimeMillis(); + long end = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) + timeout; + // This "while" is a protection from spurious wake-ups. + // However, we shouldn't wait for too long. while (!oops_updated) { + timeout = timeout(end); + if (timeout <= 0) { + break; + } try { // Wait for OOPS ConfigureNotify event awtLockWait(timeout); } catch (InterruptedException e) { throw new RuntimeException(e); } - // This "while" is a protection from spurious - // wake-ups. However, we shouldn't wait for too long - if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) { - throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start)); - } } // Don't take into account OOPS ConfigureNotify event return getEventNumber() - event_number > 1;
diff --git a/src/java.desktop/unix/native/common/java2d/opengl/J2D_GL/glxext.h b/src/java.desktop/unix/native/common/java2d/opengl/J2D_GL/glxext.h index c0ba1b7..bfd7507 100644 --- a/src/java.desktop/unix/native/common/java2d/opengl/J2D_GL/glxext.h +++ b/src/java.desktop/unix/native/common/java2d/opengl/J2D_GL/glxext.h
@@ -698,8 +698,10 @@ /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ /* (as used in the GLX_OML_sync_control extension). */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +/* JDK modification */ +#elif defined(__sun__) #include <inttypes.h> -#elif defined(__sun__) || defined(__digital__) +#elif defined(__digital__) #include <inttypes.h> #if defined(__STDC__) #if defined(__arch64__) || defined(_LP64)
diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java index d873ad0..208ac4d 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java
@@ -463,7 +463,7 @@ // display mode Rectangle screenBounds = getDefaultConfiguration().getBounds(); w.setBounds(screenBounds.x, screenBounds.y, - dm.getWidth(), dm.getHeight()); + screenBounds.width, screenBounds.height); // Note: no call to replaceSurfaceData is required here since // replacement will be caused by an upcoming display change event } else {
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java index 5f10294..f984df8 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java
@@ -520,7 +520,11 @@ @Override public boolean updateGraphicsData(GraphicsConfiguration gc) { + var old = getGraphicsConfiguration().getDefaultTransform(); winGraphicsConfig = (Win32GraphicsConfig)gc; + if (gc != null && !old.equals(gc.getDefaultTransform())) { + syncBounds(); // the bounds of the peer depend on the DPI + } try { replaceSurfaceData(); } catch (InvalidPipeException e) { @@ -529,6 +533,14 @@ return false; } + /** + * Make sure that the native peer's coordinates are in sync with the target. + */ + void syncBounds() { + Rectangle r = ((Component) target).getBounds(); + setBounds(r.x, r.y, r.width, r.height, SET_BOUNDS); + } + //This will return null for Components not yet added to a Container @Override public ColorModel getColorModel() {
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java index ea4fc4a..930064d 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WDialogPeer.java
@@ -36,6 +36,8 @@ import sun.awt.AWTAccessor; import sun.awt.im.InputMethodManager; +import static sun.java2d.SunGraphicsEnvironment.toUserSpace; + final class WDialogPeer extends WWindowPeer implements DialogPeer { // Toolkit & peer internals @@ -117,8 +119,8 @@ if (((Dialog)target).isUndecorated()) { return super.getMinimumSize(); } - return new Dimension(scaleDownX(getSysMinWidth()), - scaleDownY(getSysMinHeight())); + return toUserSpace(getGraphicsConfiguration(), + getSysMinWidth(), getSysMinHeight()); } @Override
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java index eaa830f..8671f25 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java
@@ -38,7 +38,9 @@ import sun.awt.im.InputMethodManager; import sun.security.action.GetPropertyAction; -import static sun.java2d.SunGraphicsEnvironment.convertToDeviceSpace; +import static sun.java2d.SunGraphicsEnvironment.getGCDeviceBounds; +import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs; +import static sun.java2d.SunGraphicsEnvironment.toUserSpace; class WFramePeer extends WWindowPeer implements FramePeer { @@ -97,10 +99,9 @@ */ private Rectangle adjustMaximizedBounds(Rectangle bounds) { // All calculations should be done in the device space - bounds = convertToDeviceSpace(bounds); - + bounds = toDeviceSpaceAbs(bounds); GraphicsConfiguration gc = getGraphicsConfiguration(); - Rectangle currentDevBounds = convertToDeviceSpace(gc, gc.getBounds()); + Rectangle currentDevBounds = getGCDeviceBounds(gc); // Prepare data for WM_GETMINMAXINFO message. // ptMaxPosition should be in coordinate system of the current monitor, // not the main monitor, or monitor on which we maximize the window. @@ -148,13 +149,13 @@ @Override public final Dimension getMinimumSize() { + GraphicsConfiguration gc = getGraphicsConfiguration(); Dimension d = new Dimension(); if (!((Frame)target).isUndecorated()) { - d.setSize(scaleDownX(getSysMinWidth()), - scaleDownY(getSysMinHeight())); + d.setSize(toUserSpace(gc, getSysMinWidth(), getSysMinHeight())); } - if (((Frame)target).getMenuBar() != null) { - d.height += scaleDownY(getSysMenuHeight()); + if (((Frame) target).getMenuBar() != null) { + d.height += toUserSpace(gc, 0, getSysMenuHeight()).height; } return d; }
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WRobotPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WRobotPeer.java index 15ef130..1f4cedf 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WRobotPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WRobotPeer.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,29 +30,17 @@ import java.awt.Rectangle; import java.awt.peer.RobotPeer; -import sun.java2d.SunGraphicsEnvironment; +import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs; -final class WRobotPeer extends WObjectPeer implements RobotPeer -{ - WRobotPeer() { - create(); - } +final class WRobotPeer implements RobotPeer { + WRobotPeer(GraphicsDevice screen) { - create(); } - private synchronized native void _dispose(); - - @Override - protected void disposeImpl() { - _dispose(); - } - - public native void create(); public native void mouseMoveImpl(int x, int y); @Override public void mouseMove(int x, int y) { - Point point = SunGraphicsEnvironment.convertToDeviceSpace(x, y); + Point point = toDeviceSpaceAbs(x, y); mouseMoveImpl(point.x, point.y); } @Override @@ -80,5 +68,10 @@ return pixelArray; } + @Override + public boolean useAbsoluteCoordinates() { + return true; + } + private native void getRGBPixels(int x, int y, int width, int height, int pixelArray[]); }
diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java index 6ceebba..72cee00 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java
@@ -63,10 +63,11 @@ import sun.awt.Win32GraphicsConfig; import sun.awt.Win32GraphicsDevice; import sun.awt.Win32GraphicsEnvironment; -import sun.java2d.SunGraphicsEnvironment; import sun.java2d.pipe.Region; import sun.util.logging.PlatformLogger; +import static sun.java2d.SunGraphicsEnvironment.toUserSpace; + public class WWindowPeer extends WPanelPeer implements WindowPeer, DisplayChangedListener { @@ -108,8 +109,6 @@ * WindowStateEvent is posted to the EventQueue. */ private WindowListener windowListener; - private float scaleX; - private float scaleY; /** * Initialize JNI field IDs @@ -222,8 +221,6 @@ GraphicsConfiguration gc = getGraphicsConfiguration(); Win32GraphicsDevice gd = (Win32GraphicsDevice) gc.getDevice(); gd.addDisplayChangedListener(this); - scaleX = gd.getDefaultScaleX(); - scaleY = gd.getDefaultScaleY(); initActiveWindowsTracking((Window)target); @@ -310,6 +307,12 @@ } } + @Override + final void syncBounds() { + // Windows will take care of the top-level window/frame/dialog, and + // update the location/size when DPI changes. + } + // Synchronize the insets members (here & in helper) with actual window // state. native void updateInsets(Insets i); @@ -438,9 +441,10 @@ minimumSize = ((Component)target).getMinimumSize(); } if (minimumSize != null) { - int w = Math.max(minimumSize.width, scaleDownX(getSysMinWidth())); - int h = Math.max(minimumSize.height, scaleDownY(getSysMinHeight())); - setMinSize(w, h); + Dimension sysMin = toUserSpace(getGraphicsConfiguration(), + getSysMinWidth(), getSysMinHeight()); + setMinSize(Math.max(minimumSize.width, sysMin.width), + Math.max(minimumSize.height, sysMin.height)); } else { setMinSize(0, 0); } @@ -598,21 +602,6 @@ AWTAccessor.getComponentAccessor(). setGraphicsConfiguration((Component)target, winGraphicsConfig); - - checkDPIChange(oldDev, newDev); - } - - private void checkDPIChange(Win32GraphicsDevice oldDev, - Win32GraphicsDevice newDev) { - float newScaleX = newDev.getDefaultScaleX(); - float newScaleY = newDev.getDefaultScaleY(); - - if (scaleX != newScaleX || scaleY != newScaleY) { - windowDPIChange(oldDev.getScreen(), scaleX, scaleY, - newDev.getScreen(), newScaleX, newScaleY); - scaleX = newScaleX; - scaleY = newScaleY; - } } /** @@ -666,77 +655,9 @@ return true; } - // These are the peer bounds. They get updated at: - // 1. the WWindowPeer.setBounds() method. - // 2. the native code (on WM_SIZE/WM_MOVE) - private volatile int sysX = 0; - private volatile int sysY = 0; - private volatile int sysW = 0; - private volatile int sysH = 0; - @Override public native void repositionSecurityWarning(); - @Override - public void setBounds(int x, int y, int width, int height, int op) { - sysX = x; - sysY = y; - sysW = width; - sysH = height; - - int cx = x + width / 2; - int cy = y + height / 2; - GraphicsConfiguration current = getGraphicsConfiguration(); - GraphicsConfiguration other = SunGraphicsEnvironment - .getGraphicsConfigurationAtPoint(current, cx, cy); - if (!current.equals(other)) { - AffineTransform tx = other.getDefaultTransform(); - double otherScaleX = tx.getScaleX(); - double otherScaleY = tx.getScaleY(); - initScales(); - if (scaleX != otherScaleX || scaleY != otherScaleY) { - x = (int) Math.floor(x * otherScaleX / scaleX); - y = (int) Math.floor(y * otherScaleY / scaleY); - } - } - - super.setBounds(x, y, width, height, op); - } - - private void initScales() { - - if (scaleX >= 1 && scaleY >= 1) { - return; - } - - GraphicsConfiguration gc = getGraphicsConfiguration(); - if (gc instanceof Win32GraphicsConfig) { - Win32GraphicsDevice gd = ((Win32GraphicsConfig) gc).getDevice(); - scaleX = gd.getDefaultScaleX(); - scaleY = gd.getDefaultScaleY(); - } else { - AffineTransform tx = gc.getDefaultTransform(); - scaleX = (float) tx.getScaleX(); - scaleY = (float) tx.getScaleY(); - } - } - - final int scaleUpX(int x) { - return Region.clipRound(x * scaleX); - } - - final int scaleUpY(int y) { - return Region.clipRound(y * scaleY); - } - - final int scaleDownX(int x) { - return Region.clipRound(x / scaleX); - } - - final int scaleDownY(int y) { - return Region.clipRound(y / scaleY); - } - @Override public void print(Graphics g) { // We assume we print the whole frame, @@ -905,9 +826,6 @@ } } - native void windowDPIChange(int prevScreen, float prevScaleX, float prevScaleY, - int newScreen, float newScaleX, float newScaleY); - /* * The method maps the list of the active windows to the window's AppContext, * then the method registers ActiveWindowListener, GuiDisposedListener listeners;
diff --git a/src/java.desktop/windows/native/libawt/windows/MouseInfo.cpp b/src/java.desktop/windows/native/libawt/windows/MouseInfo.cpp index 37fbc91..560764e 100644 --- a/src/java.desktop/windows/native/libawt/windows/MouseInfo.cpp +++ b/src/java.desktop/windows/native/libawt/windows/MouseInfo.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -106,8 +106,8 @@ yID = env->GetFieldID(pointClass, "y", "I"); CHECK_NULL_RETURN(yID, (jint)0); - int x = (device == NULL) ? pt.x : device->ScaleDownX(pt.x); - int y = (device == NULL) ? pt.y : device->ScaleDownY(pt.y); + int x = (device == NULL) ? pt.x : device->ScaleDownAbsX(pt.x); + int y = (device == NULL) ? pt.y : device->ScaleDownAbsY(pt.y); env->SetIntField(point, xID, x); env->SetIntField(point, yID, y);
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp index f83bb12..dec21b1 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ #include "awt_Win32GraphicsDevice.h" #include "Hashtable.h" #include "ComCtl32Util.h" +#include "math.h" #include <Region.h> @@ -603,7 +604,7 @@ /* * Fix for 4046446. */ - SetWindowPos(GetHWnd(), 0, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE); + Reshape(x, y, w, h); /* Set default colors. */ m_colorForeground = colorForeground; @@ -1087,6 +1088,7 @@ WIN_MSG(WM_DESTROY) WIN_MSG(WM_MOVE) WIN_MSG(WM_SIZE) + WIN_MSG(WM_DPICHANGED) WIN_MSG(WM_ACTIVATE) WIN_MSG(WM_SETFOCUS) WIN_MSG(WM_KILLFOCUS) @@ -1505,9 +1507,9 @@ case WM_SIZE: { RECT r; - // fix 4128317 : use GetClientRect for full 32-bit int precision and + // fix 4128317 : use GetWindowRect for full 32-bit int precision and // to avoid negative client area dimensions overflowing 16-bit params - robi - ::GetClientRect( GetHWnd(), &r ); + ::GetWindowRect(GetHWnd(), &r); mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top); //mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam)); SetCompositionWindow(r); @@ -2233,8 +2235,8 @@ */ RECT* r = (RECT*)(buffer + rgndata->rdh.dwSize); RECT* un[2] = {0, 0}; - DWORD i; - for (i = 0; i < rgndata->rdh.nCount; i++, r++) { + DWORD i; + for (i = 0; i < rgndata->rdh.nCount; i++, r++) { int width = r->right-r->left; int height = r->bottom-r->top; if (width > 0 && height > 0) { @@ -2246,13 +2248,22 @@ } } } + // The Windows may request to update the small region of pixels that + // cannot be represented in the user's space, in this case, we will + // request to repaint the smallest non-empty bounding box in the user's + // space + int screen = GetScreenImOn(); + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* device = devices->GetDevice(screen); + float scaleX = (device == NULL) ? 1 : device->GetScaleX(); + float scaleY = (device == NULL) ? 1 : device->GetScaleY(); for(i = 0; i < 2; i++) { if (un[i] != 0) { - DoCallback("handleExpose", "(IIII)V", - ScaleDownX(un[i]->left), - ScaleDownY(un[i]->top), - ScaleDownX(un[i]->right - un[i]->left), - ScaleDownY(un[i]->bottom - un[i]->top)); + int x1 = floor(un[i]->left / scaleX); + int y1 = floor(un[i]->top / scaleY); + int x2 = ceil(un[i]->right / scaleX); + int y2 = ceil(un[i]->bottom / scaleY); + DoCallback("handleExpose", "(IIII)V", x1, y1, x2 - x1, y2 - y1); } } delete [] buffer; @@ -3888,8 +3899,8 @@ } HWND hTop = GetTopLevelParentForWindow(hWnd); ::ClientToScreen(hTop, &p); - int sx = ScaleUpX(x) - p.x; - int sy = ScaleUpY(y) - p.y; + int sx = ScaleUpAbsX(x) - p.x; + int sy = ScaleUpAbsY(y) - p.y; if (!m_bitsCandType) { SetCandidateWindow(m_bitsCandType, sx, sy); return; @@ -4767,34 +4778,71 @@ } } +int AwtComponent::GetScreenImOn() { + HWND hWindow = GetAncestor(GetHWnd(), GA_ROOT); + AwtComponent *comp = AwtComponent::GetComponent(hWindow); + if (comp && comp->IsTopLevel()) { + return comp->GetScreenImOn(); + } + return AwtWin32GraphicsDevice::DeviceIndexForWindow(hWindow); +} + int AwtComponent::ScaleUpX(int x) { - int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); + int screen = GetScreenImOn(); Devices::InstanceAccess devices; AwtWin32GraphicsDevice* device = devices->GetDevice(screen); return device == NULL ? x : device->ScaleUpX(x); } +int AwtComponent::ScaleUpAbsX(int x) { + int screen = GetScreenImOn(); + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* device = devices->GetDevice(screen); + return device == NULL ? x : device->ScaleUpAbsX(x); +} + int AwtComponent::ScaleUpY(int y) { - int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); + int screen = GetScreenImOn(); Devices::InstanceAccess devices; AwtWin32GraphicsDevice* device = devices->GetDevice(screen); return device == NULL ? y : device->ScaleUpY(y); } +int AwtComponent::ScaleUpAbsY(int y) { + int screen = GetScreenImOn(); + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* device = devices->GetDevice(screen); + return device == NULL ? y : device->ScaleUpAbsY(y); +} + int AwtComponent::ScaleDownX(int x) { - int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); + int screen = GetScreenImOn(); Devices::InstanceAccess devices; AwtWin32GraphicsDevice* device = devices->GetDevice(screen); return device == NULL ? x : device->ScaleDownX(x); } +int AwtComponent::ScaleDownAbsX(int x) { + int screen = GetScreenImOn(); + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* device = devices->GetDevice(screen); + return device == NULL ? x : device->ScaleDownAbsX(x); +} + int AwtComponent::ScaleDownY(int y) { - int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); + int screen = GetScreenImOn(); Devices::InstanceAccess devices; AwtWin32GraphicsDevice* device = devices->GetDevice(screen); return device == NULL ? y : device->ScaleDownY(y); } +int AwtComponent::ScaleDownAbsY(int y) { + int screen = GetScreenImOn(); + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* device = devices->GetDevice(screen); + return device == NULL ? y : device->ScaleDownAbsY(y); +} + jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -5090,7 +5138,7 @@ id, when, modifiers, ScaleDownX(x + insets.left), ScaleDownY(y + insets.top), - ScaleDownX(xAbs), ScaleDownY(yAbs), + ScaleDownAbsX(xAbs), ScaleDownAbsY(yAbs), clickCount, popupTrigger, button); if (safe_ExceptionOccurred(env)) { @@ -5163,8 +5211,8 @@ id, when, modifiers, ScaleDownX(x + insets.left), ScaleDownY(y + insets.top), - ScaleDownX(xAbs), - ScaleDownY(yAbs), + ScaleDownAbsX(xAbs), + ScaleDownAbsY(yAbs), clickCount, popupTrigger, scrollType, scrollAmount, roundedWheelRotation, preciseWheelRotation); @@ -5674,8 +5722,8 @@ RECT rect; VERIFY(::GetWindowRect(p->GetHWnd(),&rect)); result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", - p->ScaleDownX(rect.left), - p->ScaleDownY(rect.top)); + p->ScaleDownAbsX(rect.left), + p->ScaleDownAbsY(rect.top)); } ret: env->DeleteGlobalRef(self);
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.h b/src/java.desktop/windows/native/libawt/windows/awt_Component.h index 69006d4..13dba41 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.h
@@ -275,6 +275,7 @@ /* * methods on this component */ + virtual int GetScreenImOn(); virtual void Show(); virtual void Hide(); virtual void Reshape(int x, int y, int w, int h); @@ -755,9 +756,13 @@ virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha); int ScaleUpX(int x); + int ScaleUpAbsX(int x); int ScaleUpY(int y); + int ScaleUpAbsY(int y); int ScaleDownX(int x); + int ScaleDownAbsX(int x); int ScaleDownY(int y); + int ScaleDownAbsY(int y); private: /* A bitmask keeps the button's numbers as MK_LBUTTON, MK_MBUTTON, MK_RBUTTON
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Cursor.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Cursor.cpp index 36ceb1a..cff9acd 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Cursor.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Cursor.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -477,8 +477,8 @@ int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor); Devices::InstanceAccess devices; AwtWin32GraphicsDevice *device = devices->GetDevice(screen); - int x = (device == NULL) ? p.x : device->ScaleDownX(p.x); - int y = (device == NULL) ? p.y : device->ScaleDownY(p.y); + int x = (device == NULL) ? p.x : device->ScaleDownAbsX(p.x); + int y = (device == NULL) ? p.y : device->ScaleDownAbsY(p.y); env->SetIntField(point, AwtCursor::pointXID, x); env->SetIntField(point, AwtCursor::pointYID, y);
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp b/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp index 2c2d9dc..de3e53c 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp
@@ -1170,14 +1170,14 @@ return S_OK; } -static void ScaleDown(POINT &pt) { +static void ScaleDownAbs(POINT &pt) { HMONITOR monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor); Devices::InstanceAccess devices; AwtWin32GraphicsDevice *device = devices->GetDevice(screen); if (device) { - pt.x = device->ScaleDownX(pt.x); - pt.y = device->ScaleDownY(pt.y); + pt.x = device->ScaleDownAbsX(pt.x); + pt.y = device->ScaleDownAbsY(pt.y); } } @@ -1186,7 +1186,7 @@ void AwtDragSource::call_dSCenter(JNIEnv* env, jobject self, jint targetActions, jint modifiers, POINT pt) { - ScaleDown(pt); + ScaleDownAbs(pt); DECLARE_VOID_JAVA_METHOD(dSCenter, dSCClazz, "dragEnter", "(IIII)V"); DASSERT(!JNU_IsNull(env, self)); env->CallVoidMethod(self, dSCenter, targetActions, modifiers, pt.x, pt.y); @@ -1199,7 +1199,7 @@ void AwtDragSource::call_dSCmotion(JNIEnv* env, jobject self, jint targetActions, jint modifiers, POINT pt) { - ScaleDown(pt); + ScaleDownAbs(pt); DECLARE_VOID_JAVA_METHOD(dSCmotion, dSCClazz, "dragMotion", "(IIII)V"); DASSERT(!JNU_IsNull(env, self)); env->CallVoidMethod(self, dSCmotion, targetActions, modifiers, pt.x, pt.y); @@ -1212,7 +1212,7 @@ void AwtDragSource::call_dSCchanged(JNIEnv* env, jobject self, jint targetActions, jint modifiers, POINT pt) { - ScaleDown(pt); + ScaleDownAbs(pt); DECLARE_VOID_JAVA_METHOD(dSCchanged, dSCClazz, "operationChanged", "(IIII)V"); DASSERT(!JNU_IsNull(env, self)); @@ -1225,7 +1225,7 @@ void AwtDragSource::call_dSCexit(JNIEnv* env, jobject self, POINT pt) { - ScaleDown(pt); + ScaleDownAbs(pt); DECLARE_VOID_JAVA_METHOD(dSCexit, dSCClazz, "dragExit", "(II)V"); DASSERT(!JNU_IsNull(env, self)); env->CallVoidMethod(self, dSCexit, pt.x, pt.y); @@ -1238,7 +1238,7 @@ void AwtDragSource::call_dSCddfinished(JNIEnv* env, jobject self, jboolean success, jint operations, POINT pt) { - ScaleDown(pt); + ScaleDownAbs(pt); DECLARE_VOID_JAVA_METHOD(dSCddfinished, dSCClazz, "dragDropFinished", "(ZIII)V"); DASSERT(!JNU_IsNull(env, self)); env->CallVoidMethod(self, dSCddfinished, success, operations, pt.x, pt.y); @@ -1251,7 +1251,7 @@ void AwtDragSource::call_dSCmouseMoved(JNIEnv* env, jobject self, jint targetActions, jint modifiers, POINT pt) { - ScaleDown(pt); + ScaleDownAbs(pt); DECLARE_VOID_JAVA_METHOD(dSCmouseMoved, dSCClazz, "dragMouseMoved", "(IIII)V"); DASSERT(!JNU_IsNull(env, self));
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp b/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp index 119b2c3..e812837 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -631,18 +631,18 @@ CATCH_BAD_ALLOC; } -int ScaleDownX(int x, HWND hwnd) { +int ScaleDownAbsX(int x, HWND hwnd) { int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(hwnd); Devices::InstanceAccess devices; AwtWin32GraphicsDevice* device = devices->GetDevice(screen); - return device == NULL ? x : device->ScaleDownX(x); + return device == NULL ? x : device->ScaleDownAbsX(x); } -int ScaleDownY(int y, HWND hwnd) { +int ScaleDownAbsY(int y, HWND hwnd) { int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(hwnd); Devices::InstanceAccess devices; AwtWin32GraphicsDevice* device = devices->GetDevice(screen); - return device == NULL ? y : device->ScaleDownY(y); + return device == NULL ? y : device->ScaleDownAbsY(y); } jobject AwtFileDialog::_GetLocationOnScreen(void *param) @@ -657,7 +657,8 @@ RECT rect; VERIFY(::GetWindowRect(hwnd, &rect)); result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", - ScaleDownX(rect.left, hwnd), ScaleDownY(rect.top, hwnd)); + ScaleDownAbsX(rect.left, hwnd), + ScaleDownAbsY(rect.top, hwnd)); } if (result != NULL)
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp index 8acea81..6fc4b82 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp
@@ -328,17 +328,13 @@ frame->CreateHWnd(env, L"", style, exStyle, - 0, 0, 0, 0, + x, y, width, height, hwndParent, NULL, ::GetSysColor(COLOR_WINDOWTEXT), ::GetSysColor(COLOR_WINDOWFRAME), self); - /* - * Reshape here instead of during create, so that a - * WM_NCCALCSIZE is sent. - */ - frame->Reshape(x, y, width, height); + frame->RecalcNonClient(); } } } catch (...) { @@ -655,31 +651,38 @@ // Override AwtWindow::Reshape() to handle minimized/maximized // frames (see 6525850, 4065534) -void AwtFrame::Reshape(int x, int y, int width, int height) +void AwtFrame::Reshape(int x, int y, int w, int h) { if (isIconic()) { // normal AwtComponent::Reshape will not work for iconified windows so... + POINT pt = {x + w / 2, y + h / 2}; + Devices::InstanceAccess devices; + HMONITOR monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor); + AwtWin32GraphicsDevice *device = devices->GetDevice(screen); + // Try to set the correct size and jump to the correct location, even if + // it is on the different monitor. Note that for the "size" we use the + // current monitor, so the WM_DPICHANGED will adjust it for the "target" + // monitor. + MONITORINFO *miInfo = AwtWin32GraphicsDevice::GetMonitorInfo(screen); + x = device == NULL ? x : device->ScaleUpAbsX(x); + y = device == NULL ? y : device->ScaleUpAbsY(y); + w = ScaleUpX(w); + h = ScaleUpY(h); + // SetWindowPlacement takes workspace coordinates, but if taskbar is at + // top/left of screen, workspace coords != screen coords, so offset by + // workspace origin + x = x - (miInfo->rcWork.left - miInfo->rcMonitor.left); + y = y - (miInfo->rcWork.top - miInfo->rcMonitor.top); WINDOWPLACEMENT wp; - POINT ptMinPosition = {x,y}; - POINT ptMaxPosition = {0,0}; - RECT rcNormalPosition = {x,y,x+width,y+height}; - RECT rcWorkspace; - HWND hWndDesktop = GetDesktopWindow(); - HWND hWndSelf = GetHWnd(); - - // SetWindowPlacement takes workspace coordinates, but - // if taskbar is at top of screen, workspace coords != - // screen coords, so offset by workspace origin - VERIFY(::SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&rcWorkspace, 0)); - ::OffsetRect(&rcNormalPosition, -rcWorkspace.left, -rcWorkspace.top); - + ::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT)); // set the window size for when it is not-iconified wp.length = sizeof(wp); wp.flags = WPF_SETMINPOSITION; wp.showCmd = IsVisible() ? SW_SHOWMINIMIZED : SW_HIDE; - wp.ptMinPosition = ptMinPosition; - wp.ptMaxPosition = ptMaxPosition; - wp.rcNormalPosition = rcNormalPosition; + wp.ptMinPosition = {x, y}; + wp.ptMaxPosition = {0, 0}; + wp.rcNormalPosition = {x, y, x + w, y + h}; // If the call is not guarded with ignoreWmSize, // a regression for bug 4851435 appears. @@ -687,7 +690,7 @@ // changing the iconified state of the frame // while calling the Frame.setBounds() method. m_ignoreWmSize = TRUE; - ::SetWindowPlacement(hWndSelf, &wp); + ::SetWindowPlacement(GetHWnd(), &wp); m_ignoreWmSize = FALSE; return; @@ -704,7 +707,7 @@ SetStyle(style); } - AwtWindow::Reshape(x, y, width, height); + AwtWindow::Reshape(x, y, w, h); }
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_List.cpp b/src/java.desktop/windows/native/libawt/windows/awt_List.cpp index 69484f0..a04f618 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_List.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_List.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -288,14 +288,17 @@ UnsubclassHWND(); AwtToolkit::DestroyComponentHWND(m_hwnd); - CreateHWnd(env, L"", style, exStyle, - rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, + CreateHWnd(env, L"", style, exStyle, 0, 0, 0, 0, parentHWnd, NULL, ::GetSysColor(COLOR_WINDOWTEXT), ::GetSysColor(COLOR_WINDOW), peer); + SetWindowPos(GetHWnd(), 0, + rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, + SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE); + SendListMessage(WM_SETFONT, (WPARAM)font, (LPARAM)FALSE); SendListMessage(LB_SETITEMHEIGHT, 0, MAKELPARAM(itemHeight, 0)); SendListMessage(LB_RESETCONTENT);
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp index 12c733d..33457eb 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,32 +23,17 @@ * questions. */ -#include "awt.h" -#include "awt_Toolkit.h" -#include "awt_Component.h" -#include "awt_Robot.h" #include "sun_awt_windows_WRobotPeer.h" #include "java_awt_event_InputEvent.h" +#include "awt_Component.h" #include <winuser.h> -AwtRobot::AwtRobot( jobject peer ) -{ - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - m_peerObject = env->NewWeakGlobalRef(peer); - JNU_CHECK_EXCEPTION(env); - JNI_SET_PDATA(peer, this); -} - -AwtRobot::~AwtRobot() -{ -} - static int signum(int i) { // special version of signum which returns 1 when value is 0 return i >= 0 ? 1 : -1; } -void AwtRobot::MouseMove( jint x, jint y) +static void MouseMove(jint x, jint y) { INPUT mouseInput = {0}; mouseInput.type = INPUT_MOUSE; @@ -59,7 +44,7 @@ ::SendInput(1, &mouseInput, sizeof(mouseInput)); } -void AwtRobot::MousePress( jint buttonMask ) +static void MousePress(jint buttonMask) { DWORD dwFlags = 0L; // According to MSDN: Software Driving Software @@ -101,7 +86,7 @@ ::SendInput(1, &mouseInput, sizeof(mouseInput)); } -void AwtRobot::MouseRelease( jint buttonMask ) +static void MouseRelease(jint buttonMask) { DWORD dwFlags = 0L; // According to MSDN: Software Driving Software @@ -144,11 +129,11 @@ ::SendInput(1, &mouseInput, sizeof(mouseInput)); } -void AwtRobot::MouseWheel (jint wheelAmt) { +static void MouseWheel(jint wheelAmt) { mouse_event(MOUSEEVENTF_WHEEL, 0, 0, wheelAmt * -1 * WHEEL_DELTA, 0); } -inline jint AwtRobot::WinToJavaPixel(USHORT r, USHORT g, USHORT b) +inline jint WinToJavaPixel(USHORT r, USHORT g, USHORT b) { jint value = 0xFF << 24 | // alpha channel is always turned all the way up @@ -158,7 +143,7 @@ return value; } -void AwtRobot::GetRGBPixels(jint x, jint y, jint width, jint height, jintArray pixelArray) +static void GetRGBPixels(jint x, jint y, jint width, jint height, jintArray pixelArray) { DASSERT(width > 0 && height > 0); @@ -255,17 +240,7 @@ ::DeleteDC(hdcScreen); } -void AwtRobot::KeyPress( jint jkey ) -{ - DoKeyEvent(jkey, 0); // no flags means key down -} - -void AwtRobot::KeyRelease( jint jkey ) -{ - DoKeyEvent(jkey, KEYEVENTF_KEYUP); -} - -void AwtRobot::DoKeyEvent( jint jkey, DWORD dwFlags ) +static void DoKeyEvent(jint jkey, DWORD dwFlags) { UINT vkey; UINT modifiers; @@ -297,48 +272,16 @@ } } -// -// utility function to get the C++ object from the Java one -// -// (static) -AwtRobot * AwtRobot::GetRobot( jobject self ) -{ - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - AwtRobot * robot = (AwtRobot *)JNI_GET_PDATA(self); - DASSERT( !::IsBadWritePtr( robot, sizeof(AwtRobot))); - return robot; -} - -////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // Native method declarations // -JNIEXPORT void JNICALL Java_sun_awt_windows_WRobotPeer_create( - JNIEnv * env, jobject self) -{ - TRY; - - new AwtRobot(self); - - CATCH_BAD_ALLOC; -} - -JNIEXPORT void JNICALL Java_sun_awt_windows_WRobotPeer__1dispose( - JNIEnv *env, jobject self) -{ - TRY_NO_VERIFY; - - AwtObject::_Dispose(self); - - CATCH_BAD_ALLOC; -} - JNIEXPORT void JNICALL Java_sun_awt_windows_WRobotPeer_mouseMoveImpl( JNIEnv * env, jobject self, jint x, jint y) { TRY; - AwtRobot::GetRobot(self)->MouseMove(x, y); + MouseMove(x, y); CATCH_BAD_ALLOC; } @@ -348,7 +291,7 @@ { TRY; - AwtRobot::GetRobot(self)->MousePress(buttons); + MousePress(buttons); CATCH_BAD_ALLOC; } @@ -358,7 +301,7 @@ { TRY; - AwtRobot::GetRobot(self)->MouseRelease(buttons); + MouseRelease(buttons); CATCH_BAD_ALLOC; } @@ -368,7 +311,7 @@ { TRY; - AwtRobot::GetRobot(self)->MouseWheel(wheelAmt); + MouseWheel(wheelAmt); CATCH_BAD_ALLOC; } @@ -378,7 +321,7 @@ { TRY; - AwtRobot::GetRobot(self)->GetRGBPixels(x, y, width, height, pixelArray); + GetRGBPixels(x, y, width, height, pixelArray); CATCH_BAD_ALLOC; } @@ -388,7 +331,7 @@ { TRY; - AwtRobot::GetRobot(self)->KeyPress(javakey); + DoKeyEvent(javakey, 0); // no flags means key down CATCH_BAD_ALLOC; } @@ -398,7 +341,7 @@ { TRY; - AwtRobot::GetRobot(self)->KeyRelease(javakey); + DoKeyEvent(javakey, KEYEVENTF_KEYUP); CATCH_BAD_ALLOC; }
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Robot.h b/src/java.desktop/windows/native/libawt/windows/awt_Robot.h deleted file mode 100644 index 2b1def7..0000000 --- a/src/java.desktop/windows/native/libawt/windows/awt_Robot.h +++ /dev/null
@@ -1,58 +0,0 @@ -/* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef AWT_ROBOT_H -#define AWT_ROBOT_H - -#include "awt_Toolkit.h" -#include "awt_Object.h" -#include "sun_awt_windows_WRobotPeer.h" -#include "jlong.h" - -class AwtRobot : public AwtObject -{ - public: - AwtRobot( jobject peer ); - virtual ~AwtRobot(); - - void MouseMove( jint x, jint y); - void MousePress( jint buttonMask ); - void MouseRelease( jint buttonMask ); - - void MouseWheel(jint wheelAmt); - jint getNumberOfButtons(); - - void GetRGBPixels(jint x, jint y, jint width, jint height, jintArray pixelArray); - - void KeyPress( jint key ); - void KeyRelease( jint key ); - static AwtRobot * GetRobot( jobject self ); - - private: - void DoKeyEvent( jint jkey, DWORD dwFlags ); - static jint WinToJavaPixel(USHORT r, USHORT g, USHORT b); -}; - -#endif // AWT_ROBOT_H
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp index 7d13fbe..463c1fd 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsConfig.cpp
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,16 +99,12 @@ AwtWin32GraphicsDevice *device = devices->GetDevice(screen); if (TRUE == MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW)) { - - int x = (device == NULL) ? rRW.left : device->ScaleDownX(rRW.left); - int y = (device == NULL) ? rRW.top : device->ScaleDownY(rRW.top); int w = (device == NULL) ? rRW.right - rRW.left : device->ScaleDownX(rRW.right - rRW.left); int h = (device == NULL) ? rRW.bottom - rRW.top : device->ScaleDownY(rRW.bottom - rRW.top); - bounds = env->NewObject(clazz, mid, x, y, w, h); - + bounds = env->NewObject(clazz, mid, rRW.left, rRW.top, w, h); } else { // 4910760 - don't return a null bounds, return the bounds of the
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp index 258b290..2731474 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
@@ -77,6 +77,7 @@ this->devicesArray = arr; this->scaleX = 1; this->scaleY = 1; + disableScaleAutoRefresh = FALSE; javaDevice = NULL; colorData = new ImgColorData; colorData->grayscale = GS_NOTGRAY; @@ -633,21 +634,45 @@ return ClipRound(x * scaleX); } +int AwtWin32GraphicsDevice::ScaleUpAbsX(int x) +{ + LONG screen = pMonitorInfo->rcMonitor.left; + return screen + ClipRound((x - screen) * scaleX); +} + int AwtWin32GraphicsDevice::ScaleUpY(int y) { return ClipRound(y * scaleY); } +int AwtWin32GraphicsDevice::ScaleUpAbsY(int y) +{ + LONG screen = pMonitorInfo->rcMonitor.top; + return screen + ClipRound((y - screen) * scaleY); +} + int AwtWin32GraphicsDevice::ScaleDownX(int x) { return ClipRound(x / scaleX); } +int AwtWin32GraphicsDevice::ScaleDownAbsX(int x) +{ + LONG screen = pMonitorInfo->rcMonitor.left; + return screen + ClipRound((x - screen) / scaleX); +} + int AwtWin32GraphicsDevice::ScaleDownY(int y) { return ClipRound(y / scaleY); } +int AwtWin32GraphicsDevice::ScaleDownAbsY(int y) +{ + LONG screen = pMonitorInfo->rcMonitor.top; + return screen + ClipRound((y - screen) / scaleY); +} + int AwtWin32GraphicsDevice::ClipRound(double value) { value -= 0.5; @@ -666,11 +691,13 @@ void AwtWin32GraphicsDevice::InitDesktopScales() { - float dpiX = -1.0f; - float dpiY = -1.0f; - GetScreenDpi(GetMonitor(), &dpiX, &dpiY); - if (dpiX > 0 && dpiY > 0) { - SetScale(dpiX / 96, dpiY / 96); + if (!disableScaleAutoRefresh) { + float dpiX = -1.0f; + float dpiY = -1.0f; + GetScreenDpi(GetMonitor(), &dpiX, &dpiY); + if (dpiX > 0 && dpiY > 0) { + SetScale(dpiX / 96, dpiY / 96); + } } } @@ -694,6 +721,11 @@ // REMIND: noop for now } +void AwtWin32GraphicsDevice::DisableScaleAutoRefresh() +{ + disableScaleAutoRefresh = TRUE; +} + /** * Invalidates the GraphicsDevice object associated with this * device by disabling offscreen acceleration and calling @@ -754,6 +786,21 @@ } } +/** + * This function updates the scale factor for all monitors on the system. + */ +void AwtWin32GraphicsDevice::ResetAllDesktopScales() +{ + if (!Devices::GetInstance()){ + return; + } + Devices::InstanceAccess devices; + int devicesNum = devices->GetNumDevices(); + for (int deviceIndex = 0; deviceIndex < devicesNum; deviceIndex++) { + devices->GetDevice(deviceIndex)->InitDesktopScales(); + } +} + void AwtWin32GraphicsDevice::DisableOffscreenAccelerationForDevice( HMONITOR hMonitor) { @@ -1393,6 +1440,7 @@ AwtWin32GraphicsDevice *device = devices->GetDevice(screen); if (device != NULL ) { + device->DisableScaleAutoRefresh(); device->SetScale(scaleX, scaleY); } } @@ -1441,4 +1489,3 @@ device->InitDesktopScales(); } } -
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h index d5fc0d5..f298aad 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.h
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,15 +65,20 @@ int GetDeviceIndex() { return screen; } void Release(); void DisableOffscreenAcceleration(); + void DisableScaleAutoRefresh(); void Invalidate(JNIEnv *env); void InitDesktopScales(); void SetScale(float scaleX, float scaleY); float GetScaleX(); float GetScaleY(); int ScaleUpX(int x); + int ScaleUpAbsX(int x); int ScaleUpY(int y); + int ScaleUpAbsY(int x); int ScaleDownX(int x); + int ScaleDownAbsX(int x); int ScaleDownY(int y); + int ScaleDownAbsY(int y); static int DeviceIndexForWindow(HWND hWnd); static jobject GetColorModel(JNIEnv *env, jboolean dynamic, @@ -88,6 +93,7 @@ static HMONITOR GetMonitor(int deviceIndex); static LPMONITORINFO GetMonitorInfo(int deviceIndex); static void ResetAllMonitorInfo(); + static void ResetAllDesktopScales(); static BOOL IsPrimaryPalettized() { return primaryPalettized; } static int GetDefaultDeviceIndex() { return primaryIndex; } static void DisableOffscreenAccelerationForDevice(HMONITOR hMonitor); @@ -117,6 +123,7 @@ Devices *devicesArray; float scaleX; float scaleY; + BOOL disableScaleAutoRefresh; static HDC MakeDCFromMonitor(HMONITOR); static int ClipRound(double value);
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp index e73c261..dbca3d7 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp
@@ -153,17 +153,6 @@ jboolean isFSEMState; }; -// struct for _WindowDPIChange() method -struct ScaleStruct { - jobject window; - jint prevScreen; - jfloat prevScaleX; - jfloat prevScaleY; - jint screen; - jfloat scaleX; - jfloat scaleY; -}; - struct OverrideHandle { jobject frame; HWND handle; @@ -179,10 +168,6 @@ jfieldID AwtWindow::securityWarningWidthID; jfieldID AwtWindow::securityWarningHeightID; -jfieldID AwtWindow::sysXID; -jfieldID AwtWindow::sysYID; -jfieldID AwtWindow::sysWID; -jfieldID AwtWindow::sysHID; jfieldID AwtWindow::windowTypeID; jmethodID AwtWindow::notifyWindowStateChangedMID; @@ -1128,20 +1113,19 @@ // specify WS_EX_TOOLWINDOW to remove parentless windows from taskbar exStyle |= WS_EX_TOOLWINDOW; } - window->CreateHWnd(env, L"", - style, exStyle, - 0, 0, 0, 0, - (awtParent != NULL) ? awtParent->GetHWnd() : NULL, - NULL, - ::GetSysColor(COLOR_WINDOWTEXT), - ::GetSysColor(COLOR_WINDOW), - self); - jint x = env->GetIntField(target, AwtComponent::xID); jint y = env->GetIntField(target, AwtComponent::yID); jint width = env->GetIntField(target, AwtComponent::widthID); jint height = env->GetIntField(target, AwtComponent::heightID); + window->CreateHWnd(env, L"", + style, exStyle, + x, y, width, height, + (awtParent != NULL) ? awtParent->GetHWnd() : NULL, + NULL, + ::GetSysColor(COLOR_WINDOWTEXT), + ::GetSysColor(COLOR_WINDOW), + self); /* * Initialize icon as inherited from parent if it exists */ @@ -1151,13 +1135,7 @@ window->m_iconInherited = TRUE; } window->DoUpdateIcon(); - - - /* - * Reshape here instead of during create, so that a WM_NCCALCSIZE - * is sent. - */ - window->Reshape(x, y, width, height); + window->RecalcNonClient(); } } catch (...) { env->DeleteLocalRef(target); @@ -1215,6 +1193,48 @@ VERIFY(::SetWindowPos(GetHWnd(), NULL, defLoc.left, defLoc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER)); } +/** + * Override AwtComponent::Reshape() to handle absolute screen coordinates used + * by the top-level windows. + */ +void AwtWindow::Reshape(int x, int y, int w, int h) { + if (IsEmbeddedFrame()) { + // Not the "real" top level window + return AwtComponent::Reshape(x, y, w, h); + } + // Yes, use x,y in user's space to find the nearest monitor in device space. + POINT pt = {x + w / 2, y + h / 2}; + Devices::InstanceAccess devices; + HMONITOR monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + int screen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(monitor); + AwtWin32GraphicsDevice *device = devices->GetDevice(screen); + // Try to set the correct size and jump to the correct location, even if it is + // on the different monitor. Note that for the "size" we use the current + // monitor, so the WM_DPICHANGED will adjust it for the "target" monitor. + int scaleUpAbsX = device == NULL ? x : device->ScaleUpAbsX(x); + int scaleUpAbsY = device == NULL ? y : device->ScaleUpAbsY(y); + ReshapeNoScale(scaleUpAbsX, scaleUpAbsY, ScaleUpX(w), ScaleUpY(h)); + // The window manager may tweak the size for different reasons, so try + // to make sure our window has the correct size in the user's space. + // NOOP if the size was changed already or changing is in progress. + RECT rc; + ::GetWindowRect(GetHWnd(), &rc); + ReshapeNoScale(rc.left, rc.top, ScaleUpX(w), ScaleUpY(h)); + // the window manager may ignore our "SetWindowPos" request, in this, + // case the WmMove/WmSize will not come and we need to manually resync + // the "java.awt.Window" locations, because "java.awt.Window" already + // uses location ignored by the window manager. + ::GetWindowRect(GetHWnd(), &rc); + if (x != ScaleDownAbsX(rc.left) || y != ScaleDownAbsY(rc.top)) { + WmMove(rc.left, rc.top); + } + int userW = ScaleDownX(rc.right - rc.left); + int userH = ScaleDownY(rc.bottom - rc.top); + if (w != userW || h != userH) { + WmSize(SIZENORMAL, rc.right - rc.left, rc.bottom - rc.top); + } +} + void AwtWindow::Show() { m_visible = true; @@ -1774,6 +1794,15 @@ return AwtCanvas::WmShowWindow(show, status); } +void AwtWindow::WmDPIChanged(const LPARAM &lParam) { + // need to update the scales now, otherwise the ReshapeNoScale() will + // calculate the bounds wrongly + AwtWin32GraphicsDevice::ResetAllDesktopScales(); + RECT *r = (RECT *) lParam; + ReshapeNoScale(r->left, r->top, r->right - r->left, r->bottom - r->top); + CheckIfOnNewScreen(true); +} + /* * Override AwtComponent's move handling to first update the * java AWT target's position fields directly, since Windows @@ -1789,30 +1818,21 @@ // NOTE: See also AwtWindow::Reshape return mrDoDefault; } - - if (m_screenNum == -1) { - // Set initial value - m_screenNum = GetScreenImOn(); - } - else { - CheckIfOnNewScreen(); - } + // Check for the new screen and update the java peer + CheckIfOnNewScreen(false); // postpone if different DPI /* Update the java AWT target component's fields directly */ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (env->EnsureLocalCapacity(1) < 0) { return mrConsume; } - jobject peer = GetPeer(env); - jobject target = env->GetObjectField(peer, AwtObject::targetID); + jobject target = GetTarget(env); RECT rect; ::GetWindowRect(GetHWnd(), &rect); - (env)->SetIntField(target, AwtComponent::xID, ScaleDownX(rect.left)); - (env)->SetIntField(target, AwtComponent::yID, ScaleDownY(rect.top)); - (env)->SetIntField(peer, AwtWindow::sysXID, ScaleDownX(rect.left)); - (env)->SetIntField(peer, AwtWindow::sysYID, ScaleDownY(rect.top)); + (env)->SetIntField(target, AwtComponent::xID, ScaleDownAbsX(rect.left)); + (env)->SetIntField(target, AwtComponent::yID, ScaleDownAbsY(rect.top)); SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED); env->DeleteLocalRef(target); @@ -1857,13 +1877,22 @@ MsgRouting AwtWindow::WmEnterSizeMove() { m_winSizeMove = TRUE; + // Below is a workaround, see CheckWindowDPIChange + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* device = devices->GetDevice(m_screenNum); + if (device) { + prevScaleRec.screen = m_screenNum; + prevScaleRec.scaleX = device->GetScaleX(); + prevScaleRec.scaleY = device->GetScaleY(); + } + // Above is a workaround return mrDoDefault; } MsgRouting AwtWindow::WmExitSizeMove() { m_winSizeMove = FALSE; - CheckWindowDPIChange(); + CheckWindowDPIChange(); // workaround return mrDoDefault; } @@ -1880,6 +1909,8 @@ UpdateSecurityWarningVisibility(); return mrDoDefault; } + // Check for the new screen and update the java peer + CheckIfOnNewScreen(false); // postpone if different DPI JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (env->EnsureLocalCapacity(1) < 0) @@ -1887,15 +1918,8 @@ jobject target = GetTarget(env); // fix 4167248 : ensure the insets are up-to-date before using BOOL insetsChanged = UpdateInsets(NULL); - int newWidth = w + m_insets.left + m_insets.right; - int newHeight = h + m_insets.top + m_insets.bottom; - - (env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(newWidth)); - (env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(newHeight)); - - jobject peer = GetPeer(env); - (env)->SetIntField(peer, AwtWindow::sysWID, ScaleDownX(newWidth)); - (env)->SetIntField(peer, AwtWindow::sysHID, ScaleDownY(newHeight)); + (env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(w)); + (env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(h)); if (!AwtWindow::IsResizing()) { WindowResized(); @@ -1977,6 +2001,11 @@ LRESULT retValue = 0L; switch(message) { + case WM_DPICHANGED: { + WmDPIChanged(lParam); + mr = mrConsume; + break; + } case WM_GETICON: mr = WmGetIcon(wParam, retValue); break; @@ -2120,14 +2149,28 @@ return scrnNum; } -/* Check to see if we've been moved onto another screen. +/* + * Check to see if we've been moved onto another screen. * If so, update internal data, surfaces, etc. */ - -void AwtWindow::CheckIfOnNewScreen() { +void AwtWindow::CheckIfOnNewScreen(BOOL force) { int curScrn = GetScreenImOn(); if (curScrn != m_screenNum) { // we've been moved + // if moved from one monitor to another with different DPI, we should + // update the m_screenNum only if the size was updated as well in the + // WM_DPICHANGED. + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice* oldDevice = devices->GetDevice(m_screenNum); + AwtWin32GraphicsDevice* newDevice = devices->GetDevice(curScrn); + if (!force && m_winSizeMove && oldDevice && newDevice) { + if (oldDevice->GetScaleX() != newDevice->GetScaleX() + || oldDevice->GetScaleY() != newDevice->GetScaleY()) { + // scales are different, wait for WM_DPICHANGED + return; + } + } + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jclass peerCls = env->GetObjectClass(m_peerObject); @@ -2149,67 +2192,39 @@ } } +// The shared code is not ready to the top-level window which crosses a few +// monitors with different DPI. Popup windows will start to use wrong screen, +// will be placed in the wrong place and will use the wrong size, see 8249164 +// So we will "JUMP TO" the new screen. void AwtWindow::CheckWindowDPIChange() { - - if (prevScaleRec.screen != -1 ) { - float prevScaleX = prevScaleRec.scaleX; - float prevScaleY = prevScaleRec.scaleY; - - if (prevScaleX >= 1 && prevScaleY >= 1) { - Devices::InstanceAccess devices; - AwtWin32GraphicsDevice* device = devices->GetDevice(m_screenNum); - if (device) { - float scaleX = device->GetScaleX(); - float scaleY = device->GetScaleY(); - if (prevScaleX != scaleX || prevScaleY != scaleY) { - WindowDPIChange(prevScaleRec.screen, prevScaleX, prevScaleY, - m_screenNum, scaleX, scaleY); + if (prevScaleRec.screen != -1 && prevScaleRec.screen != m_screenNum) { + Devices::InstanceAccess devices; + AwtWin32GraphicsDevice *device = devices->GetDevice(m_screenNum); + if (device) { + if (prevScaleRec.scaleX != device->GetScaleX() + || prevScaleRec.scaleY != device->GetScaleY()) { + RECT rect; + ::GetWindowRect(GetHWnd(), &rect); + int x = rect.left; + int y = rect.top; + int w = rect.right - rect.left; + int h = rect.bottom - rect.top; + RECT bounds; + if (MonitorBounds(device->GetMonitor(), &bounds)) { + x = x < bounds.left ? bounds.left : x; + y = y < bounds.top ? bounds.top : y; + x = (x + w > bounds.right) ? bounds.right - w : x; + y = (y + h > bounds.bottom) ? bounds.bottom - h : y; } + ReshapeNoScale(x, y, w, h); } } prevScaleRec.screen = -1; + prevScaleRec.scaleX = -1.0f; + prevScaleRec.scaleY = -1.0f; } } -void AwtWindow::WindowDPIChange(int prevScreen, - float prevScaleX, float prevScaleY, - int screen, float scaleX, - float scaleY) -{ - int x; - int y; - int w; - int h; - RECT rect; - - if (prevScaleX == scaleX && prevScaleY == scaleY) { - return; - } - - ::GetWindowRect(GetHWnd(), &rect); - x = rect.left; - y = rect.top; - w = (rect.right - rect.left) * scaleX / prevScaleX; - h = (rect.bottom - rect.top) * scaleY / prevScaleY; - - if (prevScreen != screen) { - Devices::InstanceAccess devices; - AwtWin32GraphicsDevice* device = devices->GetDevice(screen); - if (device) { - RECT bounds; - if (MonitorBounds(device->GetMonitor(), &bounds)) { - x = x < bounds.left ? bounds.left : x; - y = y < bounds.top ? bounds.top : y; - - x = (x + w > bounds.right) ? bounds.right - w : x; - y = (y + h > bounds.bottom) ? bounds.bottom - h : y; - } - } - } - - ReshapeNoScale(x, y, w, h); -} - BOOL AwtWindow::IsFocusableWindow() { /* * For Window/Frame/Dialog to accept focus it should: @@ -2582,15 +2597,11 @@ { env->SetIntField(target, AwtComponent::widthID, w = minWidth); - env->SetIntField(peer, AwtWindow::sysWID, - w); } if (h < minHeight) { env->SetIntField(target, AwtComponent::heightID, h = minHeight); - env->SetIntField(peer, AwtWindow::sysHID, - h); } } env->DeleteLocalRef(target); @@ -3257,39 +3268,6 @@ env->DeleteGlobalRef(self); } -void AwtWindow::_WindowDPIChange(void* param) -{ - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - - ScaleStruct *ss = (ScaleStruct *)param; - jobject self = ss->window; - jint prevScreen = ss->prevScreen; - jfloat prevScaleX = ss->prevScaleX; - jfloat prevScaleY = ss->prevScaleY; - jint screen = ss->screen; - jfloat scaleX = ss->scaleX; - jfloat scaleY = ss->scaleY; - - PDATA pData; - JNI_CHECK_PEER_GOTO(self, ret); - AwtWindow *window = (AwtWindow *)pData; - - if (window->m_winSizeMove) { - if (window->prevScaleRec.screen == -1) { - window->prevScaleRec.screen = prevScreen; - window->prevScaleRec.scaleX = prevScaleX; - window->prevScaleRec.scaleY = prevScaleY; - } - } - else { - window->WindowDPIChange(prevScreen, prevScaleX, prevScaleY, - screen, scaleX, scaleY); - } - -ret: - env->DeleteGlobalRef(self); - delete ss; -} extern "C" int getSystemMetricValue(int msgType); extern "C" { @@ -3347,11 +3325,6 @@ { TRY; - CHECK_NULL(AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I")); - CHECK_NULL(AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I")); - CHECK_NULL(AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I")); - CHECK_NULL(AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I")); - AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType", "Ljava/awt/Window$Type;"); @@ -3992,33 +3965,6 @@ } /* -* Class: sun_awt_windows_WWindowPeer -* Method: windowDPIChange -* Signature: (IFFIFF)V -*/ -JNIEXPORT void JNICALL -Java_sun_awt_windows_WWindowPeer_windowDPIChange(JNIEnv *env, jobject self, - jint prevScreen, jfloat prevScaleX, jfloat prevScaleY, - jint screen, jfloat scaleX, jfloat scaleY) -{ - TRY; - - ScaleStruct *ss = new ScaleStruct; - ss->window = env->NewGlobalRef(self); - ss->prevScreen = prevScreen; - ss->prevScaleX = prevScaleX; - ss->prevScaleY = prevScaleY; - ss->screen = screen; - ss->scaleX = scaleX; - ss->scaleY = scaleY; - - AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_WindowDPIChange, ss); - // global refs and ss are deleted in _WindowDPIChange - - CATCH_BAD_ALLOC; -} - -/* * Class: sun_awt_windows_WLightweightFramePeer * Method: overrideNativeHandle * Signature: (J)V
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Window.h b/src/java.desktop/windows/native/libawt/windows/awt_Window.h index 38f0128..6e035cc 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Window.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.h
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,12 +58,6 @@ static jfieldID securityWarningHeightID; /* sun.awt.windows.WWindowPeer field and method IDs */ - // The coordinates at the peer. - static jfieldID sysXID; - static jfieldID sysYID; - static jfieldID sysWID; - static jfieldID sysHID; - static jfieldID windowTypeID; static jmethodID notifyWindowStateChangedMID; @@ -129,6 +123,7 @@ return FALSE; } + virtual void Reshape(int x, int y, int w, int h); virtual void Invalidate(RECT* r); virtual void Show(); virtual void SetResizable(BOOL isResizable); @@ -136,7 +131,7 @@ virtual void RecalcNonClient(); virtual void RedrawNonClient(); virtual int GetScreenImOn(); - virtual void CheckIfOnNewScreen(); + virtual void CheckIfOnNewScreen(BOOL force); virtual void Grab(); virtual void Ungrab(); virtual void Ungrab(BOOL doPost); @@ -248,7 +243,6 @@ static void _RepositionSecurityWarning(void* param); static void _SetFullScreenExclusiveModeState(void* param); static void _GetNativeWindowSize(void* param); - static void _WindowDPIChange(void* param); static void _OverrideHandle(void *param); inline static BOOL IsResizing() { @@ -409,8 +403,7 @@ void InitOwner(AwtWindow *owner); void CheckWindowDPIChange(); - void WindowDPIChange(int prevScreen, float prevScaleX, float prevScaleY, - int newScreen, float scaleX, float scaleY); + void WmDPIChanged(const LPARAM &lParam); Type m_windowType; void InitType(JNIEnv *env, jobject peer);
diff --git a/src/java.desktop/windows/native/libawt/windows/awtmsg.h b/src/java.desktop/windows/native/libawt/windows/awtmsg.h index ba8a449..c4f85fa 100644 --- a/src/java.desktop/windows/native/libawt/windows/awtmsg.h +++ b/src/java.desktop/windows/native/libawt/windows/awtmsg.h
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,10 @@ * See winuser.h for details. */ +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 +#endif //WM_DPICHANGED + #ifndef WM_MOUSEWHEEL #define WM_MOUSEWHEEL 0x020A #endif //WM_MOUSEWHEEL
diff --git a/src/java.instrument/share/native/libinstrument/InvocationAdapter.c b/src/java.instrument/share/native/libinstrument/InvocationAdapter.c index af373e8..f22a08f 100644 --- a/src/java.instrument/share/native/libinstrument/InvocationAdapter.c +++ b/src/java.instrument/share/native/libinstrument/InvocationAdapter.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -956,6 +956,7 @@ resolved = resolve(parent, path); jvmtierr = (*jvmtienv)->AddToBootstrapClassLoaderSearch(jvmtienv, resolved); + free(resolved); } /* print warning if boot class path not updated */ @@ -981,4 +982,5 @@ if (haveBasePath && parent != canonicalPath) { free(parent); } + free(paths); }
diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java index c3b9a9f..6f16ba9 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java
@@ -152,7 +152,7 @@ * the serial form of any deserialized object. * The pattern must be in same format as used in * {@link java.io.ObjectInputFilter.Config#createFilter}. - * It may define a white list of permitted classes, a black list of + * It may define an allow-list of permitted classes, a reject-list of * rejected classes, a maximum depth for the deserialized objects, * etc. * <p> @@ -169,7 +169,7 @@ * classes they use in their serial form. * <p> * Care must be taken when defining such a filter, as defining - * a white list too restrictive or a too wide a black list may + * an allow-list that is too narrow or a reject-list that is too wide may * prevent legitimate clients from interoperating with the * {@code JMXConnectorServer}. */
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java index 1775571..dbb5340 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java
@@ -65,7 +65,23 @@ connTimeout, readTimeout, trace, pcb); } + public PooledConnection createPooledConnection(PoolCallback pcb, long timeout) + throws NamingException { + return new LdapClient(host, port, socketFactory, + guardedIntegerCast(timeout), + readTimeout, trace, pcb); + } + public String toString() { return host + ":" + port; } + + private int guardedIntegerCast(long timeout) { + if (timeout < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } else if (timeout > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + return (int) timeout; + } }
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java index 5abbc9d..769bc3f 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,10 @@ import javax.naming.*; import java.net.MalformedURLException; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Locale; import java.util.StringTokenizer; import com.sun.jndi.toolkit.url.Uri; import com.sun.jndi.toolkit.url.UrlUtil; @@ -64,6 +68,25 @@ final public class LdapURL extends Uri { + private static final String PARSE_MODE_PROP = "com.sun.jndi.ldapURLParsing"; + private static final ParseMode DEFAULT_PARSE_MODE = ParseMode.COMPAT; + + public static final ParseMode PARSE_MODE; + static { + PrivilegedAction<String> action = () -> + System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString()); + ParseMode parseMode = DEFAULT_PARSE_MODE; + try { + @SuppressWarnings("removal") + String mode = AccessController.doPrivileged(action); + parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT)); + } catch (Throwable t) { + parseMode = DEFAULT_PARSE_MODE; + } finally { + PARSE_MODE = parseMode; + } + } + private boolean useSsl = false; private String DN = null; private String attributes = null; @@ -83,7 +106,7 @@ useSsl = scheme.equalsIgnoreCase("ldaps"); if (! (scheme.equalsIgnoreCase("ldap") || useSsl)) { - throw new MalformedURLException("Not an LDAP URL: " + url); + throw newInvalidURISchemeException(url); } parsePathAndQuery(); // DN, attributes, scope, filter, extensions @@ -99,6 +122,21 @@ } } + @Override + protected MalformedURLException newInvalidURISchemeException(String uri) { + return new MalformedURLException("Not an LDAP URL: " + uri); + } + + @Override + protected boolean isSchemeOnly(String uri) { + return isLdapSchemeOnly(uri); + } + + @Override + protected ParseMode parseMode() { + return PARSE_MODE; + } + /** * Returns true if the URL is an LDAPS URL. */ @@ -151,13 +189,33 @@ StringTokenizer st = new StringTokenizer(urlList, " "); while (st.hasMoreTokens()) { - urls[i++] = st.nextToken(); + // we don't accept scheme-only URLs here + urls[i++] = validateURI(st.nextToken()); } String[] trimmed = new String[i]; System.arraycopy(urls, 0, trimmed, 0, i); return trimmed; } + public static boolean isLdapSchemeOnly(String uri) { + return "ldap:".equals(uri) || "ldaps:".equals(uri); + } + + public static String validateURI(String uri) { + // no validation in legacy mode parsing + if (PARSE_MODE == ParseMode.LEGACY) { + return uri; + } + + // special case of scheme-only URIs + if (isLdapSchemeOnly(uri)) { + return uri; + } + + // use java.net.URI to validate the uri syntax + return URI.create(uri).toString(); + } + /** * Determines whether an LDAP URL has query components. */ @@ -181,7 +239,8 @@ String p = (port != -1) ? (":" + port) : ""; String d = (dn != null) ? ("/" + UrlUtil.encode(dn, "UTF8")) : ""; - return useSsl ? "ldaps://" + h + p + d : "ldap://" + h + p + d; + String uri = useSsl ? "ldaps://" + h + p + d : "ldap://" + h + p + d; + return validateURI(uri); } catch (UnsupportedEncodingException e) { // UTF8 should always be supported throw new IllegalStateException("UTF-8 encoding unavailable");
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java index 510b688..316ecc3 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java
@@ -27,6 +27,9 @@ import java.util.ArrayList; // JDK 1.2 import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -68,13 +71,19 @@ com.sun.jndi.ldap.LdapPoolManager.trace; private static final int DEFAULT_SIZE = 10; + final private int initSize; final private int maxSize; final private int prefSize; final private List<ConnectionDesc> conns; + final private PooledConnectionFactory factory; private boolean closed = false; // Closed for business private Reference<Object> ref; // maintains reference to id to prevent premature GC + private boolean initialized = false; + private final ReentrantLock lock; + private final Condition connectionsAvailable; + /** * @param id the identity (connection request) of the connections in the list * @param initSize the number of connections to create initially @@ -87,105 +96,73 @@ * when one is removed. * @param factory The factory responsible for creating a connection */ - Connections(Object id, int initSize, int prefSize, int maxSize, - PooledConnectionFactory factory) throws NamingException { - + Connections(Object id, int initSize, int prefSize, int maxSize, PooledConnectionFactory factory, + ReentrantLock lock) throws NamingException { this.maxSize = maxSize; + this.lock = lock; + this.connectionsAvailable = lock.newCondition(); + this.factory = factory; + if (maxSize > 0) { // prefSize and initSize cannot exceed specified maxSize this.prefSize = Math.min(prefSize, maxSize); - initSize = Math.min(initSize, maxSize); + this.initSize = Math.min(initSize, maxSize); } else { this.prefSize = prefSize; + this.initSize = initSize; } - conns = new ArrayList<>(maxSize > 0 ? maxSize : DEFAULT_SIZE); + this.conns = new ArrayList<>(maxSize > 0 ? maxSize : DEFAULT_SIZE); + this.initialized = initSize <= 0; // Maintain soft ref to id so that this Connections' entry in // Pool doesn't get GC'ed prematurely - ref = new SoftReference<>(id); + this.ref = new SoftReference<>(id); d("init size=", initSize); d("max size=", maxSize); d("preferred size=", prefSize); + } - // Create initial connections - PooledConnection conn; - for (int i = 0; i < initSize; i++) { - conn = factory.createPooledConnection(this); - td("Create ", conn ,factory); - conns.add(new ConnectionDesc(conn)); // Add new idle conn to pool + void waitForAvailableConnection() throws InterruptedNamingException { + try { + d("get(): waiting"); + connectionsAvailable.await(); + } catch (InterruptedException e) { + throw new InterruptedNamingException( + "Interrupted while waiting for a connection"); } } - /** - * Retrieves a PooledConnection from this list of connections. - * Use an existing one if one is idle, or create one if the list's - * max size hasn't been reached. If max size has been reached, wait - * for a PooledConnection to be returned, or one to be removed (thus - * not reaching the max size any longer). - * - * @param timeout if > 0, msec to wait until connection is available - * @param factory creates the PooledConnection if one needs to be created - * - * @return A non-null PooledConnection - * @throws NamingException PooledConnection cannot be created, because this - * thread was interrupted while it waited for an available connection, - * or if it timed out while waiting, or the creation of a connection - * resulted in an error. - */ - synchronized PooledConnection get(long timeout, - PooledConnectionFactory factory) throws NamingException { - PooledConnection conn; - long start = (timeout > 0 ? System.currentTimeMillis() : 0); - long waittime = timeout; - - d("get(): before"); - while ((conn = getOrCreateConnection(factory)) == null) { - if (timeout > 0 && waittime <= 0) { - throw new CommunicationException( - "Timeout exceeded while waiting for a connection: " + - timeout + "ms"); - } - try { - d("get(): waiting"); - if (waittime > 0) { - wait(waittime); // Wait until one is released or removed - } else { - wait(); - } - } catch (InterruptedException e) { - throw new InterruptedNamingException( + void waitForAvailableConnection(long waitTime) throws InterruptedNamingException { + try { + d("get(): waiting"); + connectionsAvailable.await(waitTime, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + throw new InterruptedNamingException( "Interrupted while waiting for a connection"); - } - // Check whether we timed out - if (timeout > 0) { - long now = System.currentTimeMillis(); - waittime = timeout - (now - start); - } } - - d("get(): after"); - return conn; } /** * Retrieves an idle connection from this list if one is available. - * If none is available, create a new one if maxSize hasn't been reached. - * If maxSize has been reached, return null. - * Always called from a synchronized method. */ - private PooledConnection getOrCreateConnection( - PooledConnectionFactory factory) throws NamingException { - + PooledConnection getAvailableConnection(long timeout) throws NamingException { + if (!initialized) { + PooledConnection conn = createConnection(factory, timeout); + if (conns.size() >= initSize) { + this.initialized = true; + } + return conn; + } int size = conns.size(); // Current number of idle/nonidle conns - PooledConnection conn = null; if (prefSize <= 0 || size >= prefSize) { // If no prefSize specified, or list size already meets or // exceeds prefSize, then first look for an idle connection ConnectionDesc entry; - for (int i = 0; i < size; i++) { - entry = conns.get(i); + for (ConnectionDesc connectionDesc : conns) { + PooledConnection conn; + entry = connectionDesc; if ((conn = entry.tryUse()) != null) { d("get(): use ", conn); td("Use ", conn); @@ -193,17 +170,25 @@ } } } + return null; + } - // Check if list size already at maxSize specified - if (maxSize > 0 && size >= maxSize) { - return null; // List size is at limit; cannot create any more + /* + * Creates a new Connection if maxSize hasn't been reached. + * If maxSize has been reached, return null. + * Caller must hold the ReentrantLock. + */ + PooledConnection createConnection(PooledConnectionFactory factory, long timeout) + throws NamingException { + int size = conns.size(); // Current number of idle/non-idle connections + if (maxSize == 0 || size < maxSize) { + PooledConnection conn = factory.createPooledConnection(this, timeout); + td("Create and use ", conn, factory); + conns.add(new ConnectionDesc(conn, true)); // Add new conn to pool + return conn; } - conn = factory.createPooledConnection(this); - td("Create and use ", conn, factory); - conns.add(new ConnectionDesc(conn, true)); // Add new conn to pool - - return conn; + return null; } /** @@ -211,43 +196,45 @@ * If the list size is below prefSize, the connection may be reused. * If the list size exceeds prefSize, then the connection is closed * and removed from the list. - * + * <p> * public because implemented as part of PoolCallback. */ - public synchronized boolean releasePooledConnection(PooledConnection conn) { - ConnectionDesc entry; - int loc = conns.indexOf(entry=new ConnectionDesc(conn)); + public boolean releasePooledConnection(PooledConnection conn) { + lock.lock(); + try { + ConnectionDesc entry; + int loc = conns.indexOf(entry = new ConnectionDesc(conn)); - d("release(): ", conn); + d("release(): ", conn); - if (loc >= 0) { - // Found entry + if (loc >= 0) { + // Found entry - if (closed || (prefSize > 0 && conns.size() > prefSize)) { - // If list size exceeds prefSize, close connection + if (closed || (prefSize > 0 && conns.size() > prefSize)) { + // If list size exceeds prefSize, close connection - d("release(): closing ", conn); - td("Close ", conn); + d("release(): closing ", conn); + td("Close ", conn); - // size must be >= 2 so don't worry about empty list - conns.remove(entry); - conn.closeConnection(); - - } else { - d("release(): release ", conn); - td("Release ", conn); - - // Get ConnectionDesc from list to get correct state info - entry = conns.get(loc); - // Return connection to list, ready for reuse - entry.release(); + // size must be >= 2 so don't worry about empty list + conns.remove(entry); + conn.closeConnection(); + } else { + d("release(): release ", conn); + td("Release ", conn); + // Get ConnectionDesc from list to get correct state info + entry = conns.get(loc); + // Return connection to list, ready for reuse + entry.release(); + } + connectionsAvailable.signalAll(); + d("release(): notify"); + return true; } - notifyAll(); - d("release(): notify"); - return true; - } else { - return false; + } finally { + lock.unlock(); } + return false; } /** @@ -257,29 +244,34 @@ * when using the connection and wants it removed from the pool. * * @return true if conn removed; false if it was not in pool - * + * <p> * public because implemented as part of PoolCallback. */ - public synchronized boolean removePooledConnection(PooledConnection conn) { - if (conns.remove(new ConnectionDesc(conn))) { - d("remove(): ", conn); + public boolean removePooledConnection(PooledConnection conn) { + lock.lock(); + try { + if (conns.remove(new ConnectionDesc(conn))) { + d("remove(): ", conn); - notifyAll(); + connectionsAvailable.signalAll(); - d("remove(): notify"); - td("Remove ", conn); + d("remove(): notify"); + td("Remove ", conn); - if (conns.isEmpty()) { - // Remove softref to make pool entry eligible for GC. - // Once ref has been removed, it cannot be reinstated. - ref = null; + if (conns.isEmpty()) { + // Remove softref to make pool entry eligible for GC. + // Once ref has been removed, it cannot be reinstated. + ref = null; + } + + return true; + } else { + d("remove(): not found ", conn); } - - return true; - } else { - d("remove(): not found ", conn); - return false; + } finally { + lock.unlock(); } + return false; } /** @@ -291,8 +283,11 @@ */ boolean expire(long threshold) { List<ConnectionDesc> clonedConns; - synchronized(this) { + lock.lock(); + try { clonedConns = new ArrayList<>(conns); + } finally { + lock.unlock(); } List<ConnectionDesc> expired = new ArrayList<>(); @@ -304,12 +299,15 @@ } } - synchronized (this) { + lock.lock(); + try { conns.removeAll(expired); // Don't need to call notify() because we're // removing only idle connections. If there were // idle connections, then there should be no waiters. return conns.isEmpty(); // whether whole list has 'expired' + } finally { + lock.unlock(); } } @@ -355,6 +353,29 @@ + "; idle=" + idle + "; expired=" + expired; } + boolean grabLock(long timeout) throws InterruptedNamingException { + final long start = System.nanoTime(); + long current = start; + long remaining = timeout; + boolean locked = false; + while (!locked && remaining > 0) { + try { + locked = lock.tryLock(remaining, TimeUnit.MILLISECONDS); + remaining -= TimeUnit.NANOSECONDS.toMillis(current - start); + } catch (InterruptedException ignore) { + throw new InterruptedNamingException( + "Interrupted while waiting for the connection pool lock"); + } + current = System.nanoTime(); + remaining -= TimeUnit.NANOSECONDS.toMillis(current - start); + } + return locked; + } + + void unlock() { + lock.unlock(); + } + private void d(String msg, Object o1) { if (debug) { d(msg + o1);
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java index 504c87d..bc63c93 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java
@@ -31,10 +31,13 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedList; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import java.io.PrintStream; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; +import javax.naming.CommunicationException; import javax.naming.NamingException; /** @@ -117,45 +120,109 @@ public PooledConnection getPooledConnection(Object id, long timeout, PooledConnectionFactory factory) throws NamingException { + final long start = System.nanoTime(); + long remaining = timeout; + d("get(): ", id); if (debug) { synchronized (map) { d("size: ", map.size()); } + remaining = checkRemaining(start, remaining); } expungeStaleConnections(); - Connections conns; - synchronized (map) { - conns = getConnections(id); - if (conns == null) { - d("get(): creating new connections list for ", id); + Connections conns = getOrCreateConnections(factory, id); + d("get(): size after: ", map.size()); + remaining = checkRemaining(start, remaining); - // No connections for this id so create a new list - conns = new Connections(id, initSize, prefSize, maxSize, - factory); - ConnectionsRef connsRef = new ConnectionsRef(conns); - map.put(id, connsRef); - - // Create a weak reference to ConnectionsRef - Reference<ConnectionsRef> weakRef = - new ConnectionsWeakRef(connsRef, queue); - - // Keep the weak reference through the element of a linked list - weakRefs.add(weakRef); - } - d("get(): size after: ", map.size()); + if (!conns.grabLock(remaining)) { + throw new CommunicationException("Timed out waiting for lock"); } - return conns.get(timeout, factory); // get one connection from list + try { + remaining = checkRemaining(start, remaining); + PooledConnection conn = null; + while (remaining > 0 && conn == null) { + conn = getOrCreatePooledConnection(factory, conns, start, remaining); + // don't loop if the timeout has expired + remaining = checkRemaining(start, timeout); + } + return conn; + } finally { + conns.unlock(); + } } - private Connections getConnections(Object id) { - ConnectionsRef ref = map.get(id); - return (ref != null) ? ref.getConnections() : null; + private Connections getOrCreateConnections(PooledConnectionFactory factory, Object id) + throws NamingException { + + Connections conns; + synchronized (map) { + ConnectionsRef ref = map.get(id); + if (ref != null) { + return ref.getConnections(); + } + + d("get(): creating new connections list for ", id); + + // No connections for this id so create a new list + conns = new Connections(id, initSize, prefSize, maxSize, + factory, new ReentrantLock()); + + ConnectionsRef connsRef = new ConnectionsRef(conns); + map.put(id, connsRef); + + // Create a weak reference to ConnectionsRef + Reference<ConnectionsRef> weakRef = new ConnectionsWeakRef(connsRef, queue); + + // Keep the weak reference through the element of a linked list + weakRefs.add(weakRef); + } + return conns; } + private PooledConnection getOrCreatePooledConnection( + PooledConnectionFactory factory, Connections conns, long start, long timeout) + throws NamingException { + PooledConnection conn = conns.getAvailableConnection(timeout); + if (conn != null) { + return conn; + } + // no available cached connection + // check if list size already at maxSize before creating a new one + conn = conns.createConnection(factory, timeout); + if (conn != null) { + return conn; + } + // max number of connections already created, + // try waiting around for one to become available + if (timeout <= 0) { + conns.waitForAvailableConnection(); + } else { + long remaining = checkRemaining(start, timeout); + conns.waitForAvailableConnection(remaining); + } + return null; + } + + // Check whether we timed out + private long checkRemaining(long start, long timeout) throws CommunicationException { + if (timeout > 0) { + long current = System.nanoTime(); + long remaining = timeout - TimeUnit.NANOSECONDS.toMillis(current - start); + if (remaining <= 0) { + throw new CommunicationException( + "Timeout exceeded while waiting for a connection: " + + timeout + "ms"); + } + return remaining; + } + return Long.MAX_VALUE; + } + + /** * Goes through the connections in this Pool and expires ones that * have been idle before 'threshold'. An expired connection is closed
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java index 3aa4176..3f29449 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java
@@ -44,4 +44,13 @@ */ public abstract PooledConnection createPooledConnection(PoolCallback pcb) throws NamingException; + + /** + * Creates a pooled connection. + * @param pcb callback responsible for removing and releasing the pooled + * connection from the pool. + * @param timeout the connection timeout + */ + public abstract PooledConnection createPooledConnection(PoolCallback pcb, long timeout) + throws NamingException; };
diff --git a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java index 3fbd5eb..315d216 100644 --- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java +++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/GenericURLContext.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ import java.util.Hashtable; import java.net.MalformedURLException; +import com.sun.jndi.toolkit.url.Uri.ParseMode; + /** * This abstract class is a generic URL context that accepts as the * name argument either a string URL or a Name whose first component @@ -48,6 +50,7 @@ * @author Rosanna Lee */ abstract public class GenericURLContext implements Context { + protected Hashtable<String, Object> myEnv = null; @SuppressWarnings("unchecked") // Expect Hashtable<String, Object> @@ -161,8 +164,18 @@ if (url.startsWith("//", start)) { start += 2; // skip double slash - // find last slash - int posn = url.indexOf('/', start); + // find where the authority component ends + // and the rest of the URL starts + int slash = url.indexOf('/', start); + int qmark = url.indexOf('?', start); + int fmark = url.indexOf('#', start); + if (fmark > -1 && qmark > fmark) qmark = -1; + if (fmark > -1 && slash > fmark) slash = -1; + if (qmark > -1 && slash > qmark) slash = -1; + int posn = slash > -1 ? slash + : (qmark > -1 ? qmark + : (fmark > -1 ? fmark + : url.length())); if (posn >= 0) { start = posn; } else {
diff --git a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java index aaeb0ea..46b3fa1 100644 --- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java +++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; /** @@ -36,15 +38,17 @@ * * <p> The java.net.URL class cannot be used to parse URIs since it * requires the installation of URL stream handlers that may not be - * available. The hack of getting around this by temporarily - * replacing the scheme part of a URI is not appropriate here: JNDI - * service providers must work on older Java platforms, and we want - * new features and bug fixes that are not available in old versions - * of the URL class. + * available. * - * <p> It may be appropriate to drop this code in favor of the - * java.net.URI class. The changes would need to be written so as to - * still run on pre-1.4 platforms not containing that class. + * <p> The {@linkplain ParseMode#STRICT strict} parsing mode uses + * the java.net.URI class to syntactically validate URI strings. + * The {@linkplain ParseMode#COMPAT compat} mode validate the + * URI authority and rejects URI fragments, but doesn't perform any + * additional validation on path and query, other than that + * which may be implemented in the concrete the Uri subclasses. + * The {@linkplain ParseMode#LEGACY legacy} mode should not be + * used unless the application is capable of validating all URI + * strings before any constructors of this class is invoked. * * <p> The format of an absolute URI (see the RFCs mentioned above) is: * <blockquote><pre>{@code @@ -105,6 +109,28 @@ public class Uri { + // three parsing modes + public enum ParseMode { + /** + * Strict validation mode. + * Validate the URI syntactically using {@link java.net.URI}. + * Rejects URI fragments unless explicitly supported by the + * subclass. + */ + STRICT, + /** + * Compatibility mode. The URI authority is syntactically validated. + * Rejects URI fragments unless explicitly supported by the + * subclass. + * This is the default. + */ + COMPAT, + /** + * Legacy mode. In this mode, no validation is performed. + */ + LEGACY + } + protected String uri; protected String scheme; protected String host = null; @@ -112,6 +138,7 @@ protected boolean hasAuthority; protected String path; protected String query = null; + protected String fragment; /** @@ -129,13 +156,22 @@ } /** + * The parse mode for parsing this URI. + * The default is {@link ParseMode#COMPAT}. + * @return the parse mode for parsing this URI. + */ + protected ParseMode parseMode() { + return ParseMode.COMPAT; + } + + /** * Initializes a Uri object given a URI string. * This method must be called exactly once, and before any other Uri * methods. */ protected void init(String uri) throws MalformedURLException { this.uri = uri; - parse(uri); + parse(uri, parseMode()); } /** @@ -188,10 +224,235 @@ return uri; } + private void parse(String uri, ParseMode mode) throws MalformedURLException { + switch (mode) { + case STRICT: + parseStrict(uri); + break; + case COMPAT: + parseCompat(uri); + break; + case LEGACY: + parseLegacy(uri); + break; + } + } + /* * Parses a URI string and sets this object's fields accordingly. + * Use java.net.URI to validate the uri string syntax */ - private void parse(String uri) throws MalformedURLException { + private void parseStrict(String uri) throws MalformedURLException { + try { + if (!isSchemeOnly(uri)) { + URI u = new URI(uri); + scheme = u.getScheme(); + if (scheme == null) throw new MalformedURLException("Invalid URI: " + uri); + var auth = u.getRawAuthority(); + hasAuthority = auth != null; + if (hasAuthority) { + var host = u.getHost(); + var port = u.getPort(); + if (host != null) this.host = host; + if (port != -1) this.port = port; + String hostport = (host == null ? "" : host) + + (port == -1 ? "" : (":" + port)); + if (!hostport.equals(auth)) { + // throw if we have user info or regname + throw new MalformedURLException("unsupported authority: " + auth); + } + } + path = u.getRawPath(); + if (u.getRawQuery() != null) { + query = "?" + u.getRawQuery(); + } + if (u.getRawFragment() != null) { + if (!acceptsFragment()) { + throw new MalformedURLException("URI fragments not supported: " + uri); + } + fragment = "#" + u.getRawFragment(); + } + } else { + // scheme-only URIs are not supported by java.net.URI + // validate the URI by appending "/" to the uri string. + var s = uri.substring(0, uri.indexOf(':')); + URI u = new URI(uri + "/"); + if (!s.equals(u.getScheme()) + || !checkSchemeOnly(uri, u.getScheme())) { + throw newInvalidURISchemeException(uri); + } + scheme = s; + path = ""; + } + } catch (URISyntaxException e) { + var mue = new MalformedURLException(e.getMessage()); + mue.initCause(e); + throw mue; + } + } + + + /* + * Parses a URI string and sets this object's fields accordingly. + * Compatibility mode. Use java.net.URI to validate the syntax of + * the uri string authority. + */ + private void parseCompat(String uri) throws MalformedURLException { + int i; // index into URI + + i = uri.indexOf(':'); // parse scheme + int slash = uri.indexOf('/'); + int qmark = uri.indexOf('?'); + int fmark = uri.indexOf('#'); + if (i < 0 || slash > 0 && i > slash || qmark > 0 && i > qmark || fmark > 0 && i > fmark) { + throw new MalformedURLException("Invalid URI: " + uri); + } + if (fmark > -1) { + if (!acceptsFragment()) { + throw new MalformedURLException("URI fragments not supported: " + uri); + } + } + if (i == uri.length() - 1) { + if (!isSchemeOnly(uri)) { + throw newInvalidURISchemeException(uri); + } + } + scheme = uri.substring(0, i); + i++; // skip past ":" + + hasAuthority = uri.startsWith("//", i); + if (fmark > -1 && qmark > fmark) qmark = -1; + int endp = qmark > -1 ? qmark : fmark > -1 ? fmark : uri.length(); + if (hasAuthority) { // parse "//host:port" + i += 2; // skip past "//" + int starta = i; + // authority ends at the first appearance of /, ?, or # + int enda = uri.indexOf('/', i); + if (enda == -1 || qmark > -1 && qmark < enda) enda = qmark; + if (enda == -1 || fmark > -1 && fmark < enda) enda = fmark; + if (enda < 0) { + enda = uri.length(); + } + if (uri.startsWith(":", i)) { + // LdapURL supports empty host. + i++; + host = ""; + if (enda > i) { + port = Integer.parseInt(uri.substring(i, enda)); + } + } else { + // Use URI to parse authority + try { + // URI requires at least one char after authority: + // we use "/" and expect that the resulting URI path + // will be exactly "/". + URI u = new URI(uri.substring(0, enda) + "/"); + String auth = uri.substring(starta, enda); + host = u.getHost(); + port = u.getPort(); + String p = u.getRawPath(); + String q = u.getRawQuery(); + String f = u.getRawFragment(); + String ui = u.getRawUserInfo(); + if (ui != null) { + throw new MalformedURLException("user info not supported in authority: " + ui); + } + if (!"/".equals(p)) { + throw new MalformedURLException("invalid authority: " + auth); + } + if (q != null) { + throw new MalformedURLException("invalid trailing characters in authority: ?" + q); + } + if (f != null) { + throw new MalformedURLException("invalid trailing characters in authority: #" + f); + } + String hostport = (host == null ? "" : host) + + (port == -1?"":(":" + port)); + if (!auth.equals(hostport)) { + // throw if we have user info or regname + throw new MalformedURLException("unsupported authority: " + auth); + } + } catch (URISyntaxException e) { + var mue = new MalformedURLException(e.getMessage()); + mue.initCause(e); + throw mue; + } + } + i = enda; + } + path = uri.substring(i, endp); + // look for query + if (qmark > -1) { + if (fmark > -1) { + query = uri.substring(qmark, fmark); + } else { + query = uri.substring(qmark); + } + } + if (fmark > -1) { + fragment = uri.substring(fmark); + } + } + + /** + * A subclass of {@code Uri} that supports scheme only + * URIs can override this method and return true in the + * case where the URI string is a scheme-only URI that + * the subclass supports. + * @implSpec + * The default implementation of this method returns false, + * always. + * @param uri An URI string + * @return if this is a scheme-only URI supported by the subclass + */ + protected boolean isSchemeOnly(String uri) { + return false; + } + + /** + * Checks whether the given uri string should be considered + * as a scheme-only URI. For some protocols - e.g. DNS, we + * might accept "dns://" as a valid URL denoting default DNS. + * For others - we might only accept "scheme:". + * @implSpec + * The default implementation of this method returns true if + * the URI is of the form {@code "<scheme>:"} with nothing + * after the scheme delimiter. + * @param uri the URI + * @param scheme the scheme + * @return true if the URI should be considered as a scheme-only + * URI supported by this URI scheme. + */ + protected boolean checkSchemeOnly(String uri, String scheme) { + return uri.equals(scheme + ":"); + } + + /** + * Creates a {@code MalformedURLException} to be thrown when the + * URI scheme is not supported. + * + * @param uri the URI string + * @return a {@link MalformedURLException} + */ + protected MalformedURLException newInvalidURISchemeException(String uri) { + return new MalformedURLException("Invalid URI scheme: " + uri); + } + + /** + * Whether fragments are supported. + * @implSpec + * The default implementation of this method retturns false, always. + * @return true if fragments are supported. + */ + protected boolean acceptsFragment() { + return parseMode() == ParseMode.LEGACY; + } + + /* + * Parses a URI string and sets this object's fields accordingly. + * Legacy parsing mode. + */ + private void parseLegacy(String uri) throws MalformedURLException { int i; // index into URI i = uri.indexOf(':'); // parse scheme
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java index e21b7e4..575ba46 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java
@@ -598,6 +598,19 @@ } catch (SecurityException e) { return e; } + String hostHeader = userHeaders.firstValue("Host").orElse(null); + if (hostHeader != null && !hostHeader.equalsIgnoreCase(u.getHost())) { + // user has set a Host header different to request URI + // must check that for URLPermission also + URI u1 = replaceHostInURI(u, hostHeader); + URLPermission p1 = permissionForServer(u1, method, userHeaders.map()); + try { + assert acc != null; + sm.checkPermission(p1, acc); + } catch (SecurityException e) { + return e; + } + } ProxySelector ps = client.proxySelector(); if (ps != null) { if (!method.equals("CONNECT")) { @@ -615,6 +628,15 @@ return null; } + private static URI replaceHostInURI(URI u, String hostPort) { + StringBuilder sb = new StringBuilder(); + sb.append(u.getScheme()) + .append("://") + .append(hostPort) + .append(u.getRawPath()); + return URI.create(sb.toString()); + } + HttpClient.Version version() { return multi.version(); }
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java index 92ce410..e8b3f0b 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java
@@ -26,6 +26,7 @@ package jdk.internal.net.http; import java.io.IOException; +import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; @@ -65,6 +66,9 @@ return exchange; } + HttpClient client() { + return exchange.client(); + } /** * Returns the {@link HttpConnection} instance to which this exchange is
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java index f5f8043..78462aa 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java
@@ -27,6 +27,7 @@ import java.io.IOException; import java.net.InetSocketAddress; +import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodySubscriber; @@ -714,6 +715,10 @@ } } + HttpClient client() { + return client; + } + String dbgString() { return "Http1Exchange"; }
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java index b017311..8a03e99 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java
@@ -27,6 +27,7 @@ import java.io.IOException; import java.net.URI; +import java.net.http.HttpClient; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -59,7 +60,7 @@ private final Http1Exchange<?> http1Exchange; private final HttpConnection connection; private final HttpRequest.BodyPublisher requestPublisher; - private final HttpHeaders userHeaders; + private volatile HttpHeaders userHeaders; private final HttpHeadersBuilder systemHeadersBuilder; private volatile boolean streaming; private volatile long contentLength; @@ -91,7 +92,7 @@ } - private void collectHeaders0(StringBuilder sb) { + public void collectHeaders0(StringBuilder sb) { BiPredicate<String,String> filter = connection.headerFilter(request); @@ -99,20 +100,30 @@ BiPredicate<String,String> nocookies = NOCOOKIES.and(filter); HttpHeaders systemHeaders = systemHeadersBuilder.build(); + HttpClient client = http1Exchange.client(); + + // Filter overridable headers from userHeaders + userHeaders = HttpHeaders.of(userHeaders.map(), Utils.CONTEXT_RESTRICTED(client)); + + final HttpHeaders uh = userHeaders; + + // Filter any headers from systemHeaders that are set in userHeaders + final HttpHeaders sh = HttpHeaders.of(systemHeaders.map(), + (k,v) -> uh.firstValue(k).isEmpty()); // If we're sending this request through a tunnel, // then don't send any preemptive proxy-* headers that // the authentication filter may have saved in its // cache. - collectHeaders1(sb, systemHeaders, nocookies); + collectHeaders1(sb, sh, nocookies); // If we're sending this request through a tunnel, // don't send any user-supplied proxy-* headers // to the target server. - collectHeaders1(sb, userHeaders, nocookies); + collectHeaders1(sb, uh, nocookies); - // Gather all 'Cookie:' headers and concatenate their - // values in a single line. + // Gather all 'Cookie:' headers from the unfiltered system headers, + // and the user headers, and concatenate their values in a single line collectCookies(sb, systemHeaders, userHeaders); // terminate headers
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java index d40e11c..6bd9bad 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java
@@ -25,6 +25,7 @@ package jdk.internal.net.http; +import java.io.EOFException; import java.io.IOException; import java.io.UncheckedIOException; import java.net.ConnectException; @@ -186,14 +187,18 @@ } } + private EOFException STOPPED; void stop() { if (debug.on()) debug.log("stopping"); + STOPPED = new EOFException("HTTP/2 client stopped"); + STOPPED.setStackTrace(new StackTraceElement[0]); connections.values().forEach(this::close); connections.clear(); } private void close(Http2Connection h2c) { try { h2c.close(); } catch (Throwable t) {} + try { h2c.shutdown(STOPPED); } catch (Throwable t) {} } HttpClientImpl client() {
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java index 3447f44..fb4a4da 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,6 +96,7 @@ */ class Stream<T> extends ExchangeImpl<T> { + private static final String COOKIE_HEADER = "Cookie"; final Logger debug = Utils.getDebugLogger(this::dbgString, Utils.DEBUG); final ConcurrentLinkedQueue<Http2Frame> inputQ = new ConcurrentLinkedQueue<>(); @@ -238,7 +239,7 @@ debug.log("already completed: dropping error %s", (Object) t); } } catch (Throwable x) { - Log.logError("Subscriber::onError threw exception: {0}", (Object) t); + Log.logError("Subscriber::onError threw exception: {0}", t); } finally { cancelImpl(t); drainInputQueue(); @@ -321,10 +322,7 @@ @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("streamid: ") - .append(streamid); - return sb.toString(); + return "streamid: " + streamid; } private void receiveDataFrame(DataFrame df) { @@ -372,7 +370,6 @@ return sendBodyImpl().thenApply( v -> this); } - @SuppressWarnings("unchecked") Stream(Http2Connection connection, Exchange<T> e, WindowController windowController) @@ -424,7 +421,7 @@ incoming_priority((PriorityFrame) frame); break; default: - String msg = "Unexpected frame: " + frame.toString(); + String msg = "Unexpected frame: " + frame; throw new IOException(msg); } } @@ -619,6 +616,20 @@ } HttpHeaders sysh = filterHeaders(h.build()); HttpHeaders userh = filterHeaders(request.getUserHeaders()); + // Filter context restricted from userHeaders + userh = HttpHeaders.of(userh.map(), Utils.CONTEXT_RESTRICTED(client())); + + // Don't override Cookie values that have been set by the CookieHandler. + final HttpHeaders uh = userh; + BiPredicate<String, String> overrides = + (k, v) -> COOKIE_HEADER.equalsIgnoreCase(k) + || uh.firstValue(k).isEmpty(); + + // Filter any headers from systemHeaders that are set in userHeaders + // except for "Cookie:" - user cookies will be appended to system + // cookies + sysh = HttpHeaders.of(sysh.map(), overrides); + OutgoingHeaders<Stream<T>> f = new OutgoingHeaders<>(sysh, userh, this); if (contentLength == 0) { f.setFlag(HeadersFrame.END_STREAM); @@ -870,7 +881,6 @@ // handle bytes to send downstream while (item.hasRemaining()) { if (debug.on()) debug.log("trySend: %d", item.remaining()); - assert !endStreamSent : "internal error, send data after END_STREAM flag"; DataFrame df = getDataFrame(item); if (df == null) { if (debug.on()) @@ -890,9 +900,12 @@ connection.resetStream(streamid, ResetFrame.PROTOCOL_ERROR); throw new IOException(msg); } else if (remainingContentLength == 0) { + assert !endStreamSent : "internal error, send data after END_STREAM flag"; df.setFlag(DataFrame.END_STREAM); endStreamSent = true; } + } else { + assert !endStreamSent : "internal error, send data after END_STREAM flag"; } if (debug.on()) debug.log("trySend: sending: %d", df.getDataLength());
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java index ac2ef03..b4e4010 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java
@@ -44,6 +44,7 @@ import java.net.InetSocketAddress; import java.net.URI; import java.net.URLPermission; +import java.net.http.HttpClient; import java.net.http.HttpHeaders; import java.net.http.HttpTimeoutException; import java.nio.ByteBuffer; @@ -128,14 +129,23 @@ public static final BiPredicate<String,String> ACCEPT_ALL = (x,y) -> true; - private static final Set<String> DISALLOWED_HEADERS_SET; + private static final Set<String> DISALLOWED_HEADERS_SET = getDisallowedHeaders(); - static { - // A case insensitive TreeSet of strings. - TreeSet<String> treeSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - treeSet.addAll(Set.of("connection", "content-length", - "date", "expect", "from", "host", "upgrade", "via", "warning")); - DISALLOWED_HEADERS_SET = Collections.unmodifiableSet(treeSet); + private static Set<String> getDisallowedHeaders() { + Set<String> headers = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + headers.addAll(Set.of("connection", "content-length", "expect", "host", "upgrade")); + + String v = getNetProperty("jdk.httpclient.allowRestrictedHeaders"); + if (v != null) { + // any headers found are removed from set. + String[] tokens = v.trim().split(","); + for (String token : tokens) { + headers.remove(token); + } + return Collections.unmodifiableSet(headers); + } else { + return Collections.unmodifiableSet(headers); + } } public static final BiPredicate<String, String> @@ -158,6 +168,20 @@ }; private static final Predicate<String> IS_HOST = "host"::equalsIgnoreCase; + + // Headers that are not generally restricted, and can therefore be set by users, + // but can in some contexts be overridden by the implementation. + // Currently, only contains "Authorization" which will + // be overridden, when an Authenticator is set on the HttpClient. + // Needs to be BiPred<String,String> to fit with general form of predicates + // used by caller. + + public static final BiPredicate<String, String> CONTEXT_RESTRICTED(HttpClient client) { + return (k, v) -> client.authenticator() == null || + ! (k.equalsIgnoreCase("Authorization") + && k.equalsIgnoreCase("Proxy-Authorization")); + } + private static final Predicate<String> IS_PROXY_HEADER = (k) -> k != null && k.length() > 6 && "proxy-".equalsIgnoreCase(k.substring(0,6)); private static final Predicate<String> NO_PROXY_HEADER = @@ -335,8 +359,8 @@ Stream<String> headers) { String urlString = new StringBuilder() .append(uri.getScheme()).append("://") - .append(uri.getAuthority()) - .append(uri.getPath()).toString(); + .append(uri.getRawAuthority()) + .append(uri.getRawPath()).toString(); StringBuilder actionStringBuilder = new StringBuilder(method); String collected = headers.collect(joining(",")); @@ -801,6 +825,33 @@ } /** + * Return the host string from a HttpRequestImpl + * + * @param request + * @return + */ + public static String hostString(HttpRequestImpl request) { + URI uri = request.uri(); + int port = uri.getPort(); + String host = uri.getHost(); + + boolean defaultPort; + if (port == -1) { + defaultPort = true; + } else if (uri.getScheme().equalsIgnoreCase("https")) { + defaultPort = port == 443; + } else { + defaultPort = port == 80; + } + + if (defaultPort) { + return host; + } else { + return host + ":" + Integer.toString(port); + } + } + + /** * Get a logger for debug HPACK traces.The logger should only be used * with levels whose severity is {@code <= DEBUG}. *
diff --git a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java index 768c89f..506f7eb 100644 --- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java
@@ -440,7 +440,7 @@ if (registryFilter != null) { ObjectInputFilter.Status status = registryFilter.checkInput(filterInfo); if (status != ObjectInputFilter.Status.UNDECIDED) { - // The Registry filter can override the built-in white-list + // The Registry filter can override the built-in allow-list return status; } }
diff --git a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java index b1c9e6e..f2c1115 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -382,7 +382,7 @@ if (dgcFilter != null) { ObjectInputFilter.Status status = dgcFilter.checkInput(filterInfo); if (status != ObjectInputFilter.Status.UNDECIDED) { - // The DGC filter can override the built-in white-list + // The DGC filter can override the built-in allow-list return status; } }
diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java index 1482ccb..ca29c88 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1332,7 +1332,7 @@ /** * Locate KDC using DNS * - * @param realm the realm for which the master KDC is desired + * @param realm the realm for which the primary KDC is desired * @return the KDC */ private String getKDCFromDNS(String realm) throws KrbException {
diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java b/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java index a4dbf29..cabaf0b 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -492,12 +492,12 @@ /** * Maintains a KDC accessible list. Unavailable KDCs are put into a - * blacklist, when a KDC in the blacklist is available, it's removed - * from there. No insertion order in the blacklist. + * secondary KDC list. When a KDC in the secondary list is available, + * it is removed from there. No insertion order in the secondary KDC list. * - * There are two methods to deal with KDCs in the blacklist. 1. Only try - * them when there's no KDC not on the blacklist. 2. Still try them, but - * with lesser number of retries and smaller timeout value. + * There are two methods to deal with KDCs in the secondary KDC list. + * 1. Only try them when they are the only known KDCs. + * 2. Still try them, but with fewer retries and a smaller timeout value. */ static class KdcAccessibility { // Known bad KDCs
diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAData.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAData.java index 830e192..98f4f6b 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAData.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAData.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReferralsCache.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReferralsCache.java index 3c88e53..3e0df31 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReferralsCache.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReferralsCache.java
@@ -28,6 +28,7 @@ import java.util.Arrays; import java.util.Date; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -174,10 +175,11 @@ Date now = new Date(); Map<String, ReferralCacheEntry> entries = referralsMap.get(k); if (entries != null) { - for (Entry<String, ReferralCacheEntry> mapEntry : - entries.entrySet()) { + Iterator<Entry<String, ReferralCacheEntry>> it = entries.entrySet().iterator(); + while (it.hasNext()) { + Entry<String, ReferralCacheEntry> mapEntry = it.next(); if (mapEntry.getValue().getCreds().getEndTime().before(now)) { - entries.remove(mapEntry.getKey()); + it.remove(); } } }
diff --git a/src/java.security.jgss/share/native/libj2gss/gssapi.h b/src/java.security.jgss/share/native/libj2gss/gssapi.h index 932742c..44ea62d 100644 --- a/src/java.security.jgss/share/native/libj2gss/gssapi.h +++ b/src/java.security.jgss/share/native/libj2gss/gssapi.h
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,9 @@ extern "C" { #endif /* __cplusplus */ -#if TARGET_OS_MAC +// Condition was copied from +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/gssapi/gssapi.h +#if TARGET_OS_MAC && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)) # pragma pack(push,2) #endif @@ -695,7 +697,7 @@ gss_name_t * /* output_name */ ); -#if TARGET_OS_MAC +#if TARGET_OS_MAC && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)) # pragma pack(pop) #endif
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java index 6d386c6..624eae2 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java
@@ -349,6 +349,9 @@ * @param callingClass The Class object of the calling object */ public static URL getResource(String resourceName, Class<?> callingClass) { + if (resourceName == null) { + throw new NullPointerException(); + } URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName); if (url == null && resourceName.charAt(0) == '/') { //certain classloaders need it without the leading / @@ -402,6 +405,9 @@ * @param callingClass The Class object of the calling object */ private static List<URL> getResources(String resourceName, Class<?> callingClass) { + if (resourceName == null) { + throw new NullPointerException(); + } List<URL> ret = new ArrayList<>(); Enumeration<URL> urls = new Enumeration<URL>() { public boolean hasMoreElements() { @@ -477,7 +483,7 @@ } - if (ret.isEmpty() && resourceName != null && resourceName.charAt(0) != '/') { + if (ret.isEmpty() && resourceName.charAt(0) != '/') { return getResources('/' + resourceName, callingClass); } return ret;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index 90302d4..fdaf864 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java
@@ -309,7 +309,7 @@ Node n = XMLUtils.selectDsNode(element.getFirstChild(), Constants._TAG_HMACOUTPUTLENGTH, 0); if (n != null) { String hmacLength = XMLUtils.getFullTextChildrenFromNode(n); - if (hmacLength != null && !"".equals(hmacLength)) { + if (hmacLength != null && hmacLength.length() != 0) { this.hmacOutputLength = new HMACOutputLength(Integer.parseInt(hmacLength)); } }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java index 1ed26fe..f0cd610 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java
@@ -125,7 +125,7 @@ * Output the Attr[]s for the given element. * <br> * The code of this method is a copy of - * {@link #outputAttributes(Element, NameSpaceSymbTable, Map)}, + * {@link #outputAttributes(Element, NameSpaceSymbTable, Map, OutputStream)}, * whereas it takes into account that subtree-c14n is -- well -- subtree-based. * So if the element in question isRoot of c14n, it's parent is not in the * node set, as well as all other ancestors.
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java index d3b972c..ce971a4 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java
@@ -211,7 +211,7 @@ Node sibling = null; Node parentNode = null; Map<String, byte[]> cache = new HashMap<>(); - do { + do { //NOPMD switch (currentNode.getNodeType()) { case Node.ENTITY_NODE : @@ -338,7 +338,7 @@ Node parentNode = null; int documentLevel = NODE_BEFORE_DOCUMENT_ELEMENT; Map<String, byte[]> cache = new HashMap<>(); - do { + do { //NOPMD switch (currentNode.getNodeType()) { case Node.ENTITY_NODE : @@ -560,7 +560,7 @@ } parents.clear(); Attr nsprefix = ns.getMappingWithoutRendered(XMLNS); - if (nsprefix != null && "".equals(nsprefix.getValue())) { + if (nsprefix != null && nsprefix.getValue().length() == 0) { ns.addMappingAndRender( XMLNS, "", getNullNode(nsprefix.getOwnerDocument())); }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java index 4b23339..66ad120 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java
@@ -110,7 +110,7 @@ * Output the Attr[]s for the given element. * <br> * The code of this method is a copy of - * {@link #outputAttributes(Element, NameSpaceSymbTable, Map)}, + * {@link #outputAttributes(Element, NameSpaceSymbTable, Map, OutputStream)}, * whereas it takes into account that subtree-c14n is -- well -- subtree-based. * So if the element in question isRoot of c14n, it's parent is not in the * node set, as well as all other ancestors.
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java index 2fc853f..f0b1903 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java
@@ -348,7 +348,7 @@ List<NameSpaceSymbEntry> entrySet() { List<NameSpaceSymbEntry> a = new ArrayList<>(); for (int i = 0;i < entries.length;i++) { - if (entries[i] != null && !"".equals(entries[i].uri)) { + if (entries[i] != null && entries[i].uri.length() != 0) { a.add(entries[i]); } }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java deleted file mode 100644 index 7d17fe8..0000000 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityRuntimeException.java +++ /dev/null
@@ -1,181 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package com.sun.org.apache.xml.internal.security.exceptions; - -import java.text.MessageFormat; - -import com.sun.org.apache.xml.internal.security.utils.Constants; -import com.sun.org.apache.xml.internal.security.utils.I18n; - -/** - * The mother of all runtime Exceptions in this bundle. It allows exceptions to have - * their messages translated to the different locales. - * - * The {@code xmlsecurity_en.properties} file contains this line: - * <pre> - * xml.WrongElement = Can't create a {0} from a {1} element - * </pre> - * - * Usage in the Java source is: - * <pre> - * { - * Object[] exArgs = { Constants._TAG_TRANSFORMS, "BadElement" }; - * - * throw new XMLSecurityException("xml.WrongElement", exArgs); - * } - * </pre> - * - * Additionally, if another Exception has been caught, we can supply it, too - * <pre> - * try { - * ... - * } catch (Exception oldEx) { - * Object[] exArgs = { Constants._TAG_TRANSFORMS, "BadElement" }; - * - * throw new XMLSecurityException("xml.WrongElement", exArgs, oldEx); - * } - * </pre> - * - * - */ -public class XMLSecurityRuntimeException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - /** Field msgID */ - protected String msgID; - - /** - * Constructor XMLSecurityRuntimeException - * - */ - public XMLSecurityRuntimeException() { - super("Missing message string"); - - this.msgID = null; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - */ - public XMLSecurityRuntimeException(String msgID) { - super(I18n.getExceptionMessage(msgID)); - - this.msgID = msgID; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - * @param exArgs - */ - public XMLSecurityRuntimeException(String msgID, Object[] exArgs) { - super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs)); - - this.msgID = msgID; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param originalException - */ - public XMLSecurityRuntimeException(Exception originalException) { - super("Missing message ID to locate message string in resource bundle \"" - + Constants.exceptionMessagesResourceBundleBase - + "\". Original Exception was a " - + originalException.getClass().getName() + " and message " - + originalException.getMessage(), originalException); - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - * @param originalException - */ - public XMLSecurityRuntimeException(String msgID, Exception originalException) { - super(I18n.getExceptionMessage(msgID, originalException), originalException); - - this.msgID = msgID; - } - - /** - * Constructor XMLSecurityRuntimeException - * - * @param msgID - * @param exArgs - * @param originalException - */ - public XMLSecurityRuntimeException(String msgID, Object[] exArgs, Exception originalException) { - super(MessageFormat.format(I18n.getExceptionMessage(msgID), exArgs), originalException); - - this.msgID = msgID; - } - - /** - * Method getMsgID - * - * @return the messageId - */ - public String getMsgID() { - if (msgID == null) { - return "Missing message ID"; - } - return msgID; - } - - /** {@inheritDoc} */ - public String toString() { - String s = this.getClass().getName(); - String message = super.getLocalizedMessage(); - - if (message != null) { - message = s + ": " + message; - } else { - message = s; - } - - if (this.getCause() != null) { - message = message + "\nOriginal Exception was " + this.getCause().toString(); - } - - return message; - } - - /** - * Method getOriginalException - * - * @return the original exception - */ - public Exception getOriginalException() { - if (this.getCause() instanceof Exception) { - return (Exception)this.getCause(); - } - return null; - } - -}
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java index 7aa9a30..7445013 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
@@ -170,8 +170,8 @@ ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException { JavaUtils.checkRegisterPermission(); - KeyResolverSpi keyResolverSpi = - (KeyResolverSpi) JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); + KeyResolverSpi keyResolverSpi = (KeyResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); register(keyResolverSpi, false); } @@ -193,8 +193,8 @@ KeyResolverSpi keyResolverSpi = null; Exception ex = null; try { - keyResolverSpi = (KeyResolverSpi) JavaUtils.newInstanceWithEmptyConstructor( - ClassLoaderUtils.loadClass(className, KeyResolver.class)); + keyResolverSpi = (KeyResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); register(keyResolverSpi, true); } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e) { ex = e; @@ -253,8 +253,8 @@ JavaUtils.checkRegisterPermission(); List<KeyResolverSpi> keyResolverList = new ArrayList<>(classNames.size()); for (String className : classNames) { - KeyResolverSpi keyResolverSpi = (KeyResolverSpi)JavaUtils - .newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); + KeyResolverSpi keyResolverSpi = (KeyResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, KeyResolver.class)); keyResolverList.add(keyResolverSpi); } resolverList.addAll(keyResolverList);
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java index fb32875..101fd2d 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java
@@ -162,6 +162,7 @@ validateReference(referentElement, secureValidation); KeyInfo referent = new KeyInfo(referentElement, baseURI); + referent.setSecureValidation(secureValidation); referent.addStorageResolver(storage); return referent; } @@ -181,7 +182,7 @@ } KeyInfo referent = new KeyInfo(referentElement, ""); - if (referent.containsKeyInfoReference()) { + if (referent.containsKeyInfoReference() || referent.containsRetrievalMethod()) { if (secureValidation) { throw new XMLSecurityException("KeyInfoReferenceResolver.InvalidReferentElement.ReferenceWithSecure"); } else {
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml index 603d49e..bbd26a3 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml
@@ -96,8 +96,6 @@ <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA512" /> - <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#ripemd160-rsa-MGF1" - JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSARIPEMD160MGF1" /> <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1" JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA$SignatureRSASHA1MGF1" /> <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#sha224-rsa-MGF1"
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties index adb3146..0543720 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties
@@ -126,6 +126,7 @@ signature.Transform.NotYetImplemented = Transform {0} not yet implemented signature.Transform.NullPointerTransform = Null pointer as URI. Programming bug? signature.Transform.UnknownTransform = Unknown transformation. No handler installed for URI {0} +signature.Transform.XPathError = Error evaluating XPath expression signature.Transform.node = Current Node: {0} signature.Transform.nodeAndType = Current Node: {0}, type: {1} signature.Util.BignumNonPositive = bigInteger.signum() must be positive @@ -196,4 +197,4 @@ stax.keyNotFoundForName = No key configured for KeyName: {0} stax.keyTypeNotSupported = Key of type {0} not supported for a KeyName lookup stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled -stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing \ No newline at end of file +stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java index a6b1c6c..165bc98 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java
@@ -36,7 +36,6 @@ import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments; import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315OmitComments; import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerBase; -import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityRuntimeException; import com.sun.org.apache.xml.internal.security.parser.XMLParserException; import com.sun.org.apache.xml.internal.security.utils.JavaUtils; import com.sun.org.apache.xml.internal.security.utils.XMLUtils; @@ -141,7 +140,7 @@ /** * Construct a XMLSignatureInput from a subtree rooted by rootNode. This - * method included the node and <I>all</I> his descendants in the output. + * method included the node and <I>all</I> its descendants in the output. * * @param rootNode */ @@ -528,7 +527,7 @@ if (inputOctetStreamProxy == null) { return null; } - try { + try { //NOPMD bytes = JavaUtils.getBytesFromStream(inputOctetStreamProxy); } finally { inputOctetStreamProxy.close(); @@ -539,15 +538,9 @@ /** * @param filter */ - public void addNodeFilter(NodeFilter filter) { + public void addNodeFilter(NodeFilter filter) throws XMLParserException, IOException { if (isOctetStream()) { - try { - convertToNodes(); - } catch (Exception e) { - throw new XMLSecurityRuntimeException( - "signature.XMLSignatureInput.nodesetReference", e - ); - } + convertToNodes(); } nodeFilters.add(filter); }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java index e0f9b4f..6337bc2 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14N.java
@@ -60,7 +60,7 @@ Canonicalizer20010315 c14n = getCanonicalizer(); - if (os == null) { + if (os == null && (input.isOctetStream() || input.isElement() || input.isNodeSet())) { try (ByteArrayOutputStream writer = new ByteArrayOutputStream()) { c14n.engineCanonicalize(input, writer, secureValidation); writer.flush();
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java index 5393fa9..eca6482 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformC14NExclusive.java
@@ -82,7 +82,7 @@ Canonicalizer20010315Excl c14n = getCanonicalizer(); - if (os == null) { + if (os == null && (input.isOctetStream() || input.isElement() || input.isNodeSet())) { try (ByteArrayOutputStream writer = new ByteArrayOutputStream()) { c14n.engineCanonicalize(input, inclusiveNamespaces, writer, secureValidation); writer.flush();
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java index 539590c..030d706 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformEnvelopedSignature.java
@@ -22,8 +22,10 @@ */ package com.sun.org.apache.xml.internal.security.transforms.implementations; +import java.io.IOException; import java.io.OutputStream; +import com.sun.org.apache.xml.internal.security.parser.XMLParserException; import com.sun.org.apache.xml.internal.security.signature.NodeFilter; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.transforms.TransformSpi; @@ -71,7 +73,11 @@ Node signatureElement = searchSignatureElement(transformElement); input.setExcludeNode(signatureElement); - input.addNodeFilter(new EnvelopedNodeFilter(signatureElement)); + try { + input.addNodeFilter(new EnvelopedNodeFilter(signatureElement)); + } catch (XMLParserException | IOException ex) { + throw new TransformationException(ex); + } return input; }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java index cdde27c..ca844c0 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java
@@ -22,11 +22,12 @@ */ package com.sun.org.apache.xml.internal.security.transforms.implementations; +import java.io.IOException; import java.io.OutputStream; import javax.xml.transform.TransformerException; -import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityRuntimeException; +import com.sun.org.apache.xml.internal.security.parser.XMLParserException; import com.sun.org.apache.xml.internal.security.signature.NodeFilter; import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; import com.sun.org.apache.xml.internal.security.transforms.TransformSpi; @@ -51,6 +52,9 @@ */ public class TransformXPath extends TransformSpi { + private static final com.sun.org.slf4j.internal.Logger LOG = + com.sun.org.slf4j.internal.LoggerFactory.getLogger(TransformXPath.class); + /** * {@inheritDoc} */ @@ -102,7 +106,7 @@ input.addNodeFilter(new XPathNodeFilter(xpathElement, xpathnode, str, xpathAPIInstance)); input.setNodeSet(true); return input; - } catch (DOMException ex) { + } catch (XMLParserException | IOException | DOMException ex) { throw new TransformationException(ex); } } @@ -144,11 +148,8 @@ } return 0; } catch (TransformerException e) { - Object[] eArgs = {currentNode}; - throw new XMLSecurityRuntimeException("signature.Transform.node", eArgs, e); - } catch (Exception e) { - Object[] eArgs = {currentNode, currentNode.getNodeType()}; - throw new XMLSecurityRuntimeException("signature.Transform.nodeAndType",eArgs, e); + LOG.debug("Error evaluating XPath expression", e); + return 0; } }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java index d9d0e76..0534fff 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
@@ -43,6 +43,7 @@ * @see com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode */ @Deprecated +@SuppressWarnings("PMD") public final class Base64 { /** Field BASE64DEFAULTLENGTH */
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java index 116e868..6a2f5d5 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java
@@ -127,11 +127,11 @@ return DEFAULT_NS_PREFIX; } } - if (namespaceURI == null) { + if (namespaceURI == null && context != null) { return context.lookupNamespaceURI(null) != null ? null : DEFAULT_NS_PREFIX; - } else if (namespaceURI.equals(XML_NS_URI)) { + } else if (XML_NS_URI.equals(namespaceURI)) { return XML_NS_PREFIX; - } else if (namespaceURI.equals(XMLNS_ATTRIBUTE_NS_URI)) { + } else if (XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)) { return XMLNS_ATTRIBUTE; } return null;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java index 73483b0..552d133 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java
@@ -190,20 +190,21 @@ if (value.startsWith("\"")) { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(value.substring(1, value.length() - 1)); - int i = 0; - char c; + try (StringReader sr = new StringReader(value.substring(1, value.length() - 1))) { + int i = 0; + char c; - while ((i = sr.read()) > -1) { - c = (char) i; + while ((i = sr.read()) > -1) { + c = (char) i; - //the following char is defined at 4.Relationship with RFC1779 and LDAPv2 inrfc2253 - if (c == ',' || c == '=' || c == '+' || c == '<' - || c == '>' || c == '#' || c == ';') { - sb.append('\\'); + //the following char is defined at 4.Relationship with RFC1779 and LDAPv2 inrfc2253 + if (c == ',' || c == '=' || c == '+' || c == '<' + || c == '>' || c == '#' || c == ';') { + sb.append('\\'); + } + + sb.append(c); } - - sb.append(c); } value = trim(sb.toString()); @@ -263,33 +264,38 @@ */ static String changeLess32toRFC(String string) throws IOException { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(string); int i = 0; char c; - while ((i = sr.read()) > -1) { - c = (char) i; + try (StringReader sr = new StringReader(string)) { + while ((i = sr.read()) > -1) { + c = (char) i; - if (c == '\\') { - sb.append(c); + if (c == '\\') { + sb.append(c); - char c1 = (char) sr.read(); - char c2 = (char) sr.read(); + char c1 = (char) sr.read(); + char c2 = (char) sr.read(); - //65 (A) 97 (a) - if ((c1 >= 48 && c1 <= 57 || c1 >= 65 && c1 <= 70 || c1 >= 97 && c1 <= 102) - && (c2 >= 48 && c2 <= 57 - || c2 >= 65 && c2 <= 70 - || c2 >= 97 && c2 <= 102)) { - char ch = (char) Byte.parseByte("" + c1 + c2, 16); + //65 (A) 97 (a) + if ((c1 >= 48 && c1 <= 57 || c1 >= 65 && c1 <= 70 || c1 >= 97 && c1 <= 102) + && (c2 >= 48 && c2 <= 57 + || c2 >= 65 && c2 <= 70 + || c2 >= 97 && c2 <= 102)) { + try { + char ch = (char) Byte.parseByte("" + c1 + c2, 16); - sb.append(ch); + sb.append(ch); + } catch (NumberFormatException ex) { + throw new IOException(ex); + } + } else { + sb.append(c1); + sb.append(c2); + } } else { - sb.append(c1); - sb.append(c2); + sb.append(c); } - } else { - sb.append(c); } } @@ -305,15 +311,16 @@ */ static String changeLess32toXML(String string) throws IOException { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(string); int i = 0; - while ((i = sr.read()) > -1) { - if (i < 32) { - sb.append('\\'); - sb.append(Integer.toHexString(i)); - } else { - sb.append((char) i); + try (StringReader sr = new StringReader(string)) { + while ((i = sr.read()) > -1) { + if (i < 32) { + sb.append('\\'); + sb.append(Integer.toHexString(i)); + } else { + sb.append((char) i); + } } } @@ -329,28 +336,29 @@ */ static String changeWStoXML(String string) throws IOException { StringBuilder sb = new StringBuilder(); - StringReader sr = new StringReader(string); int i = 0; char c; - while ((i = sr.read()) > -1) { - c = (char) i; + try (StringReader sr = new StringReader(string)) { + while ((i = sr.read()) > -1) { + c = (char) i; - if (c == '\\') { - char c1 = (char) sr.read(); + if (c == '\\') { + char c1 = (char) sr.read(); - if (c1 == ' ') { - sb.append('\\'); + if (c1 == ' ') { + sb.append('\\'); - String s = "20"; + String s = "20"; - sb.append(s); + sb.append(s); + } else { + sb.append('\\'); + sb.append(c1); + } } else { - sb.append('\\'); - sb.append(c1); + sb.append(c); } - } else { - sb.append(c); } }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java index 98a5675..9974089 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
@@ -581,7 +581,7 @@ Node parent = null; Node sibling = null; final String namespaceNs = Constants.NamespaceSpecNS; - do { + do { //NOPMD switch (node.getNodeType()) { case Node.ELEMENT_NODE : Element element = (Element) node;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java index 1b3f2be..42271aa 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java
@@ -122,8 +122,8 @@ List<ResourceResolverSpi> resourceResolversToAdd = new ArrayList<>(classNames.size()); for (String className : classNames) { - ResourceResolverSpi resourceResolverSpi = (ResourceResolverSpi)JavaUtils - .newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, ResourceResolver.class)); + ResourceResolverSpi resourceResolverSpi = (ResourceResolverSpi) + JavaUtils.newInstanceWithEmptyConstructor(ClassLoaderUtils.loadClass(className, ResourceResolver.class)); resourceResolversToAdd.add(resourceResolverSpi); } resolverList.addAll(resourceResolversToAdd); @@ -159,15 +159,6 @@ LOG.debug("check resolvability by class {}", resolver.getClass().getName()); if (resolver.engineCanResolveURI(context)) { - // Check to see whether the Resolver is allowed - if (context.secureValidation - && (resolver instanceof ResolverLocalFilesystem - || resolver instanceof ResolverDirectHTTP)) { - Object[] exArgs = { resolver.getClass().getName() }; - throw new ResourceResolverException( - "signature.Reference.ForbiddenResolver", exArgs, context.uriToResolve, context.baseUri - ); - } return resolver.engineResolveURI(context); } }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java index 47d0dbb..ef56d43 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolverContext.java
@@ -54,5 +54,4 @@ public Map<String, String> getProperties() { return properties; } - }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java index 955a42a..c1f9e19 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java
@@ -219,7 +219,8 @@ LOG.debug("I was asked whether I can resolve {}", context.uriToResolve); if (context.uriToResolve.startsWith("http:") || - context.baseUri != null && context.baseUri.startsWith("http:")) { + context.uriToResolve.startsWith("https:") || + context.baseUri != null && (context.baseUri.startsWith("http:") || context.baseUri.startsWith("https:"))) { LOG.debug("I state that I can resolve {}", context.uriToResolve); return true; } @@ -231,7 +232,7 @@ private static URI getNewURI(String uri, String baseURI) throws URISyntaxException { URI newUri = null; - if (baseURI == null || "".equals(baseURI)) { + if (baseURI == null || baseURI.length() == 0) { newUri = new URI(uri); } else { newUri = new URI(baseURI).resolve(uri);
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java index 7e73ace..9d7e00b 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java
@@ -38,8 +38,6 @@ */ public class ResolverLocalFilesystem extends ResourceResolverSpi { - private static final int FILE_URI_LENGTH = "file:/".length(); - private static final com.sun.org.slf4j.internal.Logger LOG = com.sun.org.slf4j.internal.LoggerFactory.getLogger(ResolverLocalFilesystem.class); @@ -53,9 +51,7 @@ // calculate new URI URI uriNew = getNewURI(context.uriToResolve, context.baseUri); - String fileName = - ResolverLocalFilesystem.translateUriToFilename(uriNew.toString()); - InputStream inputStream = Files.newInputStream(Paths.get(fileName)); + InputStream inputStream = Files.newInputStream(Paths.get(uriNew)); //NOPMD XMLSignatureInput result = new XMLSignatureInput(inputStream); result.setSecureValidation(context.secureValidation); @@ -68,41 +64,6 @@ } /** - * Method translateUriToFilename - * - * @param uri - * @return the string of the filename - */ - private static String translateUriToFilename(String uri) { - - String subStr = uri.substring(FILE_URI_LENGTH); - - if (subStr.indexOf("%20") > -1) { - int offset = 0; - int index = 0; - StringBuilder temp = new StringBuilder(subStr.length()); - do { - index = subStr.indexOf("%20",offset); - if (index == -1) { - temp.append(subStr.substring(offset)); - } else { - temp.append(subStr.substring(offset, index)); - temp.append(' '); - offset = index + 3; - } - } while(index != -1); - subStr = temp.toString(); - } - - if (subStr.charAt(1) == ':') { - // we're running M$ Windows, so this works fine - return subStr; - } - // we're running some UNIX, so we have to prepend a slash - return "/" + subStr; - } - - /** * {@inheritDoc} */ public boolean engineCanResolveURI(ResourceResolverContext context) { @@ -111,7 +72,7 @@ } if (context.uriToResolve.isEmpty() || context.uriToResolve.charAt(0) == '#' || - context.uriToResolve.startsWith("http:")) { + context.uriToResolve.startsWith("http:") || context.uriToResolve.startsWith("https:")) { return false; } @@ -133,7 +94,7 @@ private static URI getNewURI(String uri, String baseURI) throws URISyntaxException { URI newUri = null; - if (baseURI == null || "".equals(baseURI)) { + if (baseURI == null || baseURI.length() == 0) { newUri = new URI(uri); } else { newUri = new URI(baseURI).resolve(uri);
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java index bb279ec..7655866 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java
@@ -239,9 +239,6 @@ try { in = apacheTransform.performTransform(in, os, secVal); - if (!in.isNodeSet() && !in.isElement()) { - return null; - } if (in.isOctetStream()) { return new ApacheOctetStreamData(in); } else {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java index 401ca69..40bb99c 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java
@@ -125,7 +125,11 @@ SignatureMethodParameterSpec unmarshalParams(Element paramsElem) throws MarshalException { - outputLength = Integer.parseInt(paramsElem.getFirstChild().getNodeValue()); + try { + outputLength = Integer.parseInt(paramsElem.getFirstChild().getNodeValue()); + } catch (NumberFormatException ex) { + throw new MarshalException("Invalid output length supplied: " + paramsElem.getFirstChild().getNodeValue()); + } outputLengthSet = true; LOG.debug("unmarshalled outputLength: {}", outputLength); return new HMACParameterSpec(outputLength);
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java index 736c3f9..446029a 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java
@@ -446,7 +446,7 @@ } Data data = dereferencedData; XMLSignatureInput xi = null; - try (OutputStream os = new UnsyncBufferedOutputStream(dos)) { + try (OutputStream os = new UnsyncBufferedOutputStream(dos)) { //NOPMD for (int i = 0, size = transforms.size(); i < size; i++) { DOMTransform transform = (DOMTransform)transforms.get(i); if (i < size - 1) {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java index a18b76e..fd6a892 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java
@@ -116,7 +116,7 @@ Document ownerDoc = DOMUtils.getOwnerDocument(parent); Element transformElem = null; - if (parent.getLocalName().equals("Transforms")) { + if ("Transforms".equals(parent.getLocalName())) { transformElem = DOMUtils.createElement(ownerDoc, "Transform", XMLSignature.XMLNS, dsPrefix);
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java index 6b728e2..b741273 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
@@ -138,7 +138,7 @@ } try { - ResourceResolverContext resContext = new ResourceResolverContext(uriAttr, baseURI, false); + ResourceResolverContext resContext = new ResourceResolverContext(uriAttr, baseURI, secVal); XMLSignatureInput in = ResourceResolver.resolve(resContext); if (in.isOctetStream()) { return new ApacheOctetStreamData(in);
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java index 1608ad8..7d5e15e 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java
@@ -43,14 +43,13 @@ */ public final class Policy { - // all restrictions are initialized to be unconstrained - private static Set<URI> disallowedAlgs = new HashSet<>(); - private static int maxTrans = Integer.MAX_VALUE; - private static int maxRefs = Integer.MAX_VALUE; - private static Set<String> disallowedRefUriSchemes = new HashSet<>(); - private static Map<String, Integer> minKeyMap = new HashMap<>(); - private static boolean noDuplicateIds = false; - private static boolean noRMLoops = false; + private static Set<URI> disallowedAlgs; + private static int maxTrans; + private static int maxRefs; + private static Set<String> disallowedRefUriSchemes; + private static Map<String, Integer> minKeyMap; + private static boolean noDuplicateIds; + private static boolean noRMLoops; static { try { @@ -64,6 +63,16 @@ private Policy() {} private static void initialize() { + // First initialized to be unconstrained and then parse the + // security property "jdk.xml.dsig.secureValidationPolicy" + disallowedAlgs = new HashSet<>(); + maxTrans = Integer.MAX_VALUE; + maxRefs = Integer.MAX_VALUE; + disallowedRefUriSchemes = new HashSet<>(); + minKeyMap = new HashMap<>(); + noDuplicateIds = false; + noRMLoops = false; + String prop = AccessController.doPrivileged((PrivilegedAction<String>) () -> Security.getProperty("jdk.xml.dsig.secureValidationPolicy"));
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java index 0edb5dd..72c34c6 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java
@@ -114,7 +114,7 @@ } private static boolean getBoolean(XMLCryptoContext xc, String name) { - Boolean value = (Boolean)xc.getProperty(name); + Boolean value = (Boolean) xc.getProperty(name); return value != null && value; } }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java index ced2136..ce42cdc 100644 --- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java +++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java
@@ -132,7 +132,7 @@ public XMLDSigRI() { // This is the JDK XMLDSig provider, synced from - // Apache Santuario XML Security for Java, version 2.2.1 + // Apache Santuario XML Security for Java, version 2.3.0 super("XMLDSig", VER, INFO); final Provider p = this;
diff --git a/src/java.xml.crypto/share/legal/santuario.md b/src/java.xml.crypto/share/legal/santuario.md index eba3a79..fa87128 100644 --- a/src/java.xml.crypto/share/legal/santuario.md +++ b/src/java.xml.crypto/share/legal/santuario.md
@@ -1,4 +1,4 @@ -## Apache Santuario v2.2.1 +## Apache Santuario v2.3.0 ### Apache Santuario Notice <pre>
diff --git a/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java b/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java index e0ceeda..dd430da 100644 --- a/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java +++ b/src/java.xml/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ package com.sun.java_cup.internal.runtime; +import com.sun.org.apache.xalan.internal.xsltc.compiler.sym; +import java.util.Arrays; import java.util.Stack; /** This class implements a skeleton table driven LR parser. In general, @@ -134,9 +136,19 @@ * @see com.sun.java_cup.internal.runtime.Symbol * @see com.sun.java_cup.internal.runtime.virtual_parse_stack * @author Frank Flannery + * + * @LastModified: Jan 2022 */ public abstract class lr_parser { + public static final int ID_GROUP = 1; + public static final int ID_OPERATOR = 2; + public static final int ID_TOTAL_OPERATOR = 3; + + private boolean isLiteral = false; + private int grpCount = 0; + private int opCount = 0; + private int totalOpCount = 0; /*-----------------------------------------------------------*/ /*--- Constructor(s) ----------------------------------------*/ @@ -355,8 +367,29 @@ * the "scan with" clause. Do not recycle objects; every call to * scan() should return a fresh object. */ - public Symbol scan() throws java.lang.Exception { - return getScanner().next_token(); + public Symbol scan() throws Exception { + Symbol s = getScanner().next_token(); + + if (s.sym == sym.LPAREN) { + if (!isLiteral) { + grpCount++; + } + opCount++; // function + isLiteral = false; + } else if (contains(sym.OPERATORS, s.sym)) { + opCount++; + isLiteral = false; + } + + if (s.sym == sym.Literal || s.sym == sym.QNAME) { + isLiteral = true; + } + + return s; + } + + private boolean contains(final int[] arr, final int key) { + return Arrays.stream(arr).anyMatch(i -> i == key); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ @@ -552,6 +585,9 @@ /* do user initialization */ user_init(); + isLiteral = false; + grpCount = 0; + opCount = 0; /* get the first token */ cur_token = scan(); @@ -630,9 +666,29 @@ } } } + + totalOpCount += opCount; return lhs_sym; } + /** + * Returns the count of operators in XPath expressions. + * + * @param id the ID of the count + * @return the count associated with the ID + */ + public int getCount(int id) { + switch (id) { + case ID_GROUP: + return grpCount; + case ID_OPERATOR: + return opCount; + case ID_TOTAL_OPERATOR: + return totalOpCount; + } + return 0; + } + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Write a debugging message to System.err for the debugging version
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java index 85ff602..c18553f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,14 +26,14 @@ * Constants for the project, mostly defined in the JVM specification. * * @since 6.0 (intended to replace the Constants interface) - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public final class Const { /** * Java class file format Magic number (0xCAFEBABE) * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1-200-A"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1-200-A"> * The ClassFile Structure in The Java Virtual Machine Specification</a> */ public static final int JVM_CLASSFILE_MAGIC = 0xCAFEBABE; @@ -211,13 +211,14 @@ public static final int MAX_BYTE = 255; // 2^8 - 1 /** One of the access flags for fields, methods, or classes. - * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1'> + * + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1"> * Flag definitions for Classes in the Java Virtual Machine Specification (Java SE 9 Edition).</a> - * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5'> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5"> * Flag definitions for Fields in the Java Virtual Machine Specification (Java SE 9 Edition).</a> - * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6'> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6"> * Flag definitions for Methods in the Java Virtual Machine Specification (Java SE 9 Edition).</a> - * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1'> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1"> * Flag definitions for Inner Classes in the Java Virtual Machine Specification (Java SE 9 Edition).</a> */ public static final short ACC_PUBLIC = 0x0001; @@ -381,87 +382,87 @@ /** * Marks a constant pool entry as type UTF-8. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.7"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.7"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Utf8 = 1; /** * Marks a constant pool entry as type Integer. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Integer = 3; /** * Marks a constant pool entry as type Float. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Float = 4; /** * Marks a constant pool entry as type Long. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Long = 5; /** * Marks a constant pool entry as type Double. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Double = 6; /** * Marks a constant pool entry as a Class - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.1"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.1"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Class = 7; /** * Marks a constant pool entry as a Field Reference. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Fieldref = 9; /** * Marks a constant pool entry as type String - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.3"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.3"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_String = 8; /** Marks a constant pool entry as a Method Reference. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_Methodref = 10; /** * Marks a constant pool entry as an Interface Method Reference. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_InterfaceMethodref = 11; /** Marks a constant pool entry as a name and type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.6"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.6"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_NameAndType = 12; /** * Marks a constant pool entry as a Method Handle. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.8"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.8"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_MethodHandle = 15; /** * Marks a constant pool entry as a Method Type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.9"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.9"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_MethodType = 16; @@ -476,7 +477,7 @@ /** * Marks a constant pool entry as an Invoke Dynamic - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10"> * The Constant Pool in The Java Virtual Machine Specification</a> */ public static final byte CONSTANT_InvokeDynamic = 18; @@ -546,7 +547,7 @@ /** * Maximum Constant Pool entries. * One of the limitations of the Java Virtual Machine. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.11-100-A"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.11-100-A"> * The Java Virtual Machine Specification, Java SE 8 Edition, page 330, chapter 4.11.</a> */ public static final int MAX_CP_ENTRIES = 65535; @@ -564,8 +565,8 @@ * The entry in the Limitations section has been removed from later versions of the spec; * it is not present in the Java SE 8 edition. * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3-300-E"> - * The Java Virtual Machine Specification, Java SE 8 Edition, page 104, chapter 4.7.3</a> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3-300-E"> + * The Java Virtual Machine Specification, Java SE 8 Edition, page 104, chapter 4.7.</a> */ public static final int MAX_CODE_SIZE = 65536; //bytes @@ -573,1228 +574,1228 @@ * The maximum number of dimensions in an array ({@value}). * One of the limitations of the Java Virtual Machine. * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2-150"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2-150"> * Field Descriptors in The Java Virtual Machine Specification</a> */ public static final int MAX_ARRAY_DIMENSIONS = 255; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.nop"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.nop"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short NOP = 0; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aconst_null"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aconst_null"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ACONST_NULL = 1; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ICONST_M1 = 2; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ICONST_0 = 3; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ICONST_1 = 4; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ICONST_2 = 5; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ICONST_3 = 6; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ICONST_4 = 7; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ICONST_5 = 8; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LCONST_0 = 9; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LCONST_1 = 10; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FCONST_0 = 11; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FCONST_1 = 12; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FCONST_2 = 13; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DCONST_0 = 14; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DCONST_1 = 15; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bipush"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bipush"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short BIPUSH = 16; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sipush"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sipush"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short SIPUSH = 17; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LDC = 18; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc_w"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc_w"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LDC_W = 19; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc2_w"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc2_w"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LDC2_W = 20; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ILOAD = 21; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LLOAD = 22; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FLOAD = 23; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DLOAD = 24; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ALOAD = 25; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ILOAD_0 = 26; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ILOAD_1 = 27; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ILOAD_2 = 28; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ILOAD_3 = 29; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LLOAD_0 = 30; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LLOAD_1 = 31; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LLOAD_2 = 32; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LLOAD_3 = 33; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FLOAD_0 = 34; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FLOAD_1 = 35; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FLOAD_2 = 36; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FLOAD_3 = 37; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DLOAD_0 = 38; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DLOAD_1 = 39; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DLOAD_2 = 40; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DLOAD_3 = 41; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ALOAD_0 = 42; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ALOAD_1 = 43; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ALOAD_2 = 44; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ALOAD_3 = 45; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iaload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iaload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IALOAD = 46; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.laload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.laload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LALOAD = 47; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.faload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.faload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FALOAD = 48; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.daload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.daload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DALOAD = 49; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aaload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aaload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short AALOAD = 50; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.baload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.baload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short BALOAD = 51; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.caload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.caload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short CALOAD = 52; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.saload"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.saload"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short SALOAD = 53; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISTORE = 54; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSTORE = 55; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FSTORE = 56; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DSTORE = 57; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ASTORE = 58; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISTORE_0 = 59; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISTORE_1 = 60; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISTORE_2 = 61; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISTORE_3 = 62; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSTORE_0 = 63; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSTORE_1 = 64; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSTORE_2 = 65; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSTORE_3 = 66; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FSTORE_0 = 67; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FSTORE_1 = 68; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FSTORE_2 = 69; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FSTORE_3 = 70; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DSTORE_0 = 71; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DSTORE_1 = 72; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DSTORE_2 = 73; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DSTORE_3 = 74; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ASTORE_0 = 75; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ASTORE_1 = 76; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ASTORE_2 = 77; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ASTORE_3 = 78; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iastore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iastore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IASTORE = 79; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lastore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lastore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LASTORE = 80; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fastore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fastore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FASTORE = 81; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dastore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dastore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DASTORE = 82; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aastore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aastore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short AASTORE = 83; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bastore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bastore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short BASTORE = 84; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.castore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.castore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short CASTORE = 85; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sastore"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sastore"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short SASTORE = 86; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short POP = 87; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop2"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short POP2 = 88; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DUP = 89; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x1"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x1"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DUP_X1 = 90; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x2"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DUP_X2 = 91; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DUP2 = 92; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x1"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x1"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DUP2_X1 = 93; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x2"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DUP2_X2 = 94; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.swap"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.swap"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short SWAP = 95; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iadd"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iadd"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IADD = 96; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ladd"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ladd"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LADD = 97; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fadd"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fadd"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FADD = 98; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dadd"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dadd"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DADD = 99; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.isub"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.isub"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISUB = 100; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lsub"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lsub"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSUB = 101; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fsub"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fsub"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FSUB = 102; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dsub"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dsub"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DSUB = 103; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.imul"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.imul"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IMUL = 104; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lmul"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lmul"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LMUL = 105; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fmul"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fmul"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FMUL = 106; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dmul"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dmul"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DMUL = 107; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.idiv"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.idiv"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IDIV = 108; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldiv"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldiv"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LDIV = 109; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fdiv"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fdiv"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FDIV = 110; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ddiv"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ddiv"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DDIV = 111; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.irem"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.irem"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IREM = 112; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lrem"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lrem"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LREM = 113; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.frem"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.frem"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FREM = 114; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.drem"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.drem"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DREM = 115; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ineg"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ineg"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INEG = 116; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lneg"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lneg"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LNEG = 117; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fneg"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fneg"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FNEG = 118; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dneg"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dneg"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DNEG = 119; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishl"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishl"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISHL = 120; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshl"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshl"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSHL = 121; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishr"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishr"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ISHR = 122; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshr"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshr"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LSHR = 123; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iushr"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iushr"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IUSHR = 124; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lushr"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lushr"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LUSHR = 125; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iand"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iand"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IAND = 126; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.land"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.land"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LAND = 127; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ior"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ior"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IOR = 128; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lor"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lor"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LOR = 129; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ixor"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ixor"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IXOR = 130; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lxor"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lxor"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LXOR = 131; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iinc"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iinc"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IINC = 132; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2l"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2l"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short I2L = 133; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2f"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2f"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short I2F = 134; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2d"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2d"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short I2D = 135; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short L2I = 136; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2f"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2f"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short L2F = 137; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2d"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2d"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short L2D = 138; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short F2I = 139; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2l"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2l"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short F2L = 140; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2d"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2d"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short F2D = 141; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2i"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2i"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short D2I = 142; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2l"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2l"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short D2L = 143; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2f"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2f"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short D2F = 144; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2b"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2b"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short I2B = 145; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INT2BYTE = 145; // Old notation /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2c"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2c"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short I2C = 146; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INT2CHAR = 146; // Old notation /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2s"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2s"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short I2S = 147; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INT2SHORT = 147; // Old notation /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lcmp"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lcmp"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LCMP = 148; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpl"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpl"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FCMPL = 149; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpg"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpg"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FCMPG = 150; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpl"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpl"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DCMPL = 151; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpg"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpg"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DCMPG = 152; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifeq"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifeq"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFEQ = 153; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifne"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifne"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFNE = 154; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iflt"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iflt"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFLT = 155; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifge"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifge"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFGE = 156; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifgt"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifgt"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFGT = 157; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifle"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifle"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFLE = 158; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ICMPEQ = 159; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ICMPNE = 160; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ICMPLT = 161; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ICMPGE = 162; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ICMPGT = 163; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ICMPLE = 164; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ACMPEQ = 165; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IF_ACMPNE = 166; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short GOTO = 167; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short JSR = 168; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ret"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ret"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short RET = 169; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.tableswitch"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.tableswitch"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short TABLESWITCH = 170; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lookupswitch"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lookupswitch"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LOOKUPSWITCH = 171; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ireturn"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ireturn"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IRETURN = 172; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lreturn"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lreturn"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short LRETURN = 173; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.freturn"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.freturn"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short FRETURN = 174; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dreturn"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dreturn"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short DRETURN = 175; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.areturn"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.areturn"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ARETURN = 176; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.return"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.return"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short RETURN = 177; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getstatic"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getstatic"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short GETSTATIC = 178; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putstatic"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putstatic"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short PUTSTATIC = 179; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getfield"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getfield"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short GETFIELD = 180; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putfield"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putfield"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short PUTFIELD = 181; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INVOKEVIRTUAL = 182; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INVOKESPECIAL = 183; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INVOKESTATIC = 184; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INVOKEINTERFACE = 185; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INVOKEDYNAMIC = 186; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.new"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.new"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short NEW = 187; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.newarray"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.newarray"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short NEWARRAY = 188; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.anewarray"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.anewarray"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ANEWARRAY = 189; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.arraylength"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.arraylength"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ARRAYLENGTH = 190; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.athrow"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.athrow"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short ATHROW = 191; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.checkcast"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.checkcast"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short CHECKCAST = 192; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.instanceof"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.instanceof"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short INSTANCEOF = 193; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorenter"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorenter"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short MONITORENTER = 194; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorexit"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorexit"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short MONITOREXIT = 195; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short WIDE = 196; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.multianewarray"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.multianewarray"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short MULTIANEWARRAY = 197; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnull"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnull"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFNULL = 198; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnonnull"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnonnull"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short IFNONNULL = 199; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto_w"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto_w"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short GOTO_W = 200; /** Java VM opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr_w"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr_w"> * Opcode definitions in The Java Virtual Machine Specification</a> */ public static final short JSR_W = 201; /** JVM internal opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2"> * Reserved opcodes in the Java Virtual Machine Specification</a> */ public static final short BREAKPOINT = 202; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short LDC_QUICK = 203; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short LDC_W_QUICK = 204; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short LDC2_W_QUICK = 205; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short GETFIELD_QUICK = 206; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short PUTFIELD_QUICK = 207; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short GETFIELD2_QUICK = 208; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short PUTFIELD2_QUICK = 209; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short GETSTATIC_QUICK = 210; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short PUTSTATIC_QUICK = 211; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short GETSTATIC2_QUICK = 212; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short PUTSTATIC2_QUICK = 213; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INVOKEVIRTUAL_QUICK = 214; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INVOKENONVIRTUAL_QUICK = 215; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INVOKESUPER_QUICK = 216; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INVOKESTATIC_QUICK = 217; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INVOKEINTERFACE_QUICK = 218; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INVOKEVIRTUALOBJECT_QUICK = 219; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short NEW_QUICK = 221; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short ANEWARRAY_QUICK = 222; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short MULTIANEWARRAY_QUICK = 223; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short CHECKCAST_QUICK = 224; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INSTANCEOF_QUICK = 225; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short INVOKEVIRTUAL_QUICK_W = 226; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short GETFIELD_QUICK_W = 227; /** JVM internal opcode. * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html"> * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a> - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885"> * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */ public static final short PUTFIELD_QUICK_W = 228; /** JVM internal opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2"> * Reserved opcodes in the Java Virtual Machine Specification</a> */ public static final short IMPDEP1 = 254; /** JVM internal opcode. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2"> * Reserved opcodes in the Java Virtual Machine Specification</a> */ public static final short IMPDEP2 = 255; @@ -1826,42 +1827,42 @@ public static final String ILLEGAL_TYPE = "<illegal type>"; /** Boolean data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_BOOLEAN = 4; /** Char data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_CHAR = 5; /** Float data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_FLOAT = 6; /** Double data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_DOUBLE = 7; /** Byte data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_BYTE = 8; /** Short data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_SHORT = 9; /** Int data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_INT = 10; /** Long data type. - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P"> * Static Constraints in the Java Virtual Machine Specification</a> */ public static final byte T_LONG = 11;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java index 5045dd2..14be14e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,20 +23,27 @@ /** * Exception constants. * @since 6.0 (intended to replace the InstructionConstant interface) - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public final class ExceptionConst { - /** The mother of all exceptions + /** + * The mother of all exceptions */ public static final Class<Throwable> THROWABLE = Throwable.class; - /** Super class of any run-time exception + + /** + * Super class of any run-time exception */ public static final Class<RuntimeException> RUNTIME_EXCEPTION = RuntimeException.class; - /** Super class of any linking exception (aka Linkage Error) + + /** + * Super class of any linking exception (aka Linkage Error) */ public static final Class<LinkageError> LINKING_EXCEPTION = LinkageError.class; - /** Linking Exceptions + + /** + * Linking Exceptions */ public static final Class<ClassCircularityError> CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; public static final Class<ClassFormatError> CLASS_FORMAT_ERROR = ClassFormatError.class; @@ -52,7 +59,9 @@ public static final Class<VerifyError> VERIFY_ERROR = VerifyError.class; /* UnsupportedClassVersionError is new in JDK 1.2 */ // public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; - /** Run-Time Exceptions + + /** + * Run-Time Exceptions */ public static final Class<NullPointerException> NULL_POINTER_EXCEPTION = NullPointerException.class; public static final Class<ArrayIndexOutOfBoundsException> ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java index fbdd548..dc9c8ca 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java
@@ -34,7 +34,7 @@ */ public class AnnotationDefault extends Attribute { - private ElementValue default_value; + private ElementValue defaultValue; /** * @param name_index Index pointing to the name <em>Code</em> @@ -44,7 +44,7 @@ */ AnnotationDefault(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { this(name_index, length, (ElementValue) null, constant_pool); - default_value = ElementValue.readElementValue(input, constant_pool); + defaultValue = ElementValue.readElementValue(input, constant_pool); } /** @@ -55,7 +55,7 @@ */ public AnnotationDefault(final int name_index, final int length, final ElementValue defaultValue, final ConstantPool constant_pool) { super(Const.ATTR_ANNOTATION_DEFAULT, name_index, length, constant_pool); - this.default_value = defaultValue; + this.defaultValue = defaultValue; } /** @@ -74,14 +74,14 @@ * @param defaultValue the default value of this methodinfo's annotation */ public final void setDefaultValue(final ElementValue defaultValue) { - default_value = defaultValue; + this.defaultValue = defaultValue; } /** * @return the default value */ public final ElementValue getDefaultValue() { - return default_value; + return defaultValue; } @Override @@ -92,6 +92,6 @@ @Override public final void dump(final DataOutputStream dos) throws IOException { super.dump(dos); - default_value.dump(dos); + defaultValue.dump(dos); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java index 5a5288c..79c7b25 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java
@@ -37,7 +37,7 @@ { super(type, cpool); if (type != ANNOTATION) { - throw new RuntimeException( + throw new IllegalArgumentException( "Only element values of type annotation can be built with this ctor - type specified: " + type); } this.annotationEntry = annotationEntry;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java index ab5f165..8344048 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java
@@ -37,17 +37,17 @@ */ public class AnnotationEntry implements Node { - private final int type_index; - private final ConstantPool constant_pool; + private final int typeIndex; + private final ConstantPool constantPool; private final boolean isRuntimeVisible; - private List<ElementValuePair> element_value_pairs; + private List<ElementValuePair> elementValuePairs; /* * Factory method to create an AnnotionEntry from a DataInput * * @param input - * @param constant_pool + * @param constantPool * @param isRuntimeVisible * @return the entry * @throws IOException @@ -56,9 +56,9 @@ final AnnotationEntry annotationEntry = new AnnotationEntry(input.readUnsignedShort(), constant_pool, isRuntimeVisible); final int num_element_value_pairs = input.readUnsignedShort(); - annotationEntry.element_value_pairs = new ArrayList<>(); + annotationEntry.elementValuePairs = new ArrayList<>(); for (int i = 0; i < num_element_value_pairs; i++) { - annotationEntry.element_value_pairs.add( + annotationEntry.elementValuePairs.add( new ElementValuePair(input.readUnsignedShort(), ElementValue.readElementValue(input, constant_pool), constant_pool)); } @@ -66,17 +66,17 @@ } public AnnotationEntry(final int type_index, final ConstantPool constant_pool, final boolean isRuntimeVisible) { - this.type_index = type_index; - this.constant_pool = constant_pool; + this.typeIndex = type_index; + this.constantPool = constant_pool; this.isRuntimeVisible = isRuntimeVisible; } public int getTypeIndex() { - return type_index; + return typeIndex; } public ConstantPool getConstantPool() { - return constant_pool; + return constantPool; } public boolean isRuntimeVisible() { @@ -98,7 +98,7 @@ * @return the annotation type name */ public String getAnnotationType() { - final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(type_index, Const.CONSTANT_Utf8); + final ConstantUtf8 c = (ConstantUtf8) constantPool.getConstant(typeIndex, Const.CONSTANT_Utf8); return c.getBytes(); } @@ -106,14 +106,14 @@ * @return the annotation type index */ public int getAnnotationTypeIndex() { - return type_index; + return typeIndex; } /** * @return the number of element value pairs in this annotation entry */ public final int getNumElementValuePairs() { - return element_value_pairs.size(); + return elementValuePairs.size(); } /** @@ -121,20 +121,20 @@ */ public ElementValuePair[] getElementValuePairs() { // TODO return List - return element_value_pairs.toArray(new ElementValuePair[element_value_pairs.size()]); + return elementValuePairs.toArray(new ElementValuePair[elementValuePairs.size()]); } public void dump(final DataOutputStream dos) throws IOException { - dos.writeShort(type_index); // u2 index of type name in cpool - dos.writeShort(element_value_pairs.size()); // u2 element_value pair + dos.writeShort(typeIndex); // u2 index of type name in cpool + dos.writeShort(elementValuePairs.size()); // u2 element_value pair // count - for (final ElementValuePair envp : element_value_pairs) { + for (final ElementValuePair envp : elementValuePairs) { envp.dump(dos); } } public void addElementNameValuePair(final ElementValuePair elementNameValuePair) { - element_value_pairs.add(elementNameValuePair); + elementValuePairs.add(elementNameValuePair); } public String toShortString() {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java index e93792e..5dc5f5c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java
@@ -32,7 +32,7 @@ */ public abstract class Annotations extends Attribute { - private AnnotationEntry[] annotation_table; + private AnnotationEntry[] annotationTable; private final boolean isRuntimeVisible; /** @@ -46,23 +46,23 @@ final ConstantPool constant_pool, final boolean isRuntimeVisible) throws IOException { this(annotation_type, name_index, length, (AnnotationEntry[]) null, constant_pool, isRuntimeVisible); final int annotation_table_length = input.readUnsignedShort(); - annotation_table = new AnnotationEntry[annotation_table_length]; + annotationTable = new AnnotationEntry[annotation_table_length]; for (int i = 0; i < annotation_table_length; i++) { - annotation_table[i] = AnnotationEntry.read(input, constant_pool, isRuntimeVisible); + annotationTable[i] = AnnotationEntry.read(input, constant_pool, isRuntimeVisible); } } /** - * @param annotation_type the subclass type of the annotation - * @param name_index Index pointing to the name <em>Code</em> + * @param annotationType the subclass type of the annotation + * @param nameIndex Index pointing to the name <em>Code</em> * @param length Content length in bytes - * @param annotation_table the actual annotations - * @param constant_pool Array of constants + * @param annotationTable the actual annotations + * @param constantPool Array of constants */ - public Annotations(final byte annotation_type, final int name_index, final int length, final AnnotationEntry[] annotation_table, - final ConstantPool constant_pool, final boolean isRuntimeVisible) { - super(annotation_type, name_index, length, constant_pool); - this.annotation_table = annotation_table; + public Annotations(final byte annotationType, final int nameIndex, final int length, final AnnotationEntry[] annotationTable, + final ConstantPool constantPool, final boolean isRuntimeVisible) { + super(annotationType, nameIndex, length, constantPool); + this.annotationTable = annotationTable; this.isRuntimeVisible = isRuntimeVisible; } @@ -78,27 +78,27 @@ } /** - * @param annotation_table the entries to set in this annotation + * @param annotationTable the entries to set in this annotation */ - public final void setAnnotationTable(final AnnotationEntry[] annotation_table) { - this.annotation_table = annotation_table; + public final void setAnnotationTable(final AnnotationEntry[] annotationTable) { + this.annotationTable = annotationTable; } /** * returns the array of annotation entries in this annotation */ public AnnotationEntry[] getAnnotationEntries() { - return annotation_table; + return annotationTable; } /** * @return the number of annotation entries in this annotation */ public final int getNumAnnotations() { - if (annotation_table == null) { + if (annotationTable == null) { return 0; } - return annotation_table.length; + return annotationTable.length; } public boolean isRuntimeVisible() { @@ -106,11 +106,11 @@ } protected void writeAnnotations(final DataOutputStream dos) throws IOException { - if (annotation_table == null) { + if (annotationTable == null) { return; } - dos.writeShort(annotation_table.length); - for (final AnnotationEntry element : annotation_table) { + dos.writeShort(annotationTable.length); + for (final AnnotationEntry element : annotationTable) { element.dump(dos); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java index c4293ff..1e15d77 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java
@@ -30,17 +30,17 @@ public class ArrayElementValue extends ElementValue { // For array types, this is the array - private final ElementValue[] evalues; + private final ElementValue[] elementValues; @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("{"); - for (int i = 0; i < evalues.length; i++) + for (int i = 0; i < elementValues.length; i++) { - sb.append(evalues[i]); - if ((i + 1) < evalues.length) { + sb.append(elementValues[i]); + if ((i + 1) < elementValues.length) { sb.append(","); } } @@ -52,18 +52,18 @@ { super(type, cpool); if (type != ARRAY) { - throw new RuntimeException( + throw new IllegalArgumentException( "Only element values of type array can be built with this ctor - type specified: " + type); } - this.evalues = datums; + this.elementValues = datums; } @Override public void dump(final DataOutputStream dos) throws IOException { dos.writeByte(super.getType()); // u1 type of value (ARRAY == '[') - dos.writeShort(evalues.length); - for (final ElementValue evalue : evalues) { + dos.writeShort(elementValues.length); + for (final ElementValue evalue : elementValues) { evalue.dump(dos); } } @@ -73,10 +73,10 @@ { final StringBuilder sb = new StringBuilder(); sb.append("["); - for (int i = 0; i < evalues.length; i++) + for (int i = 0; i < elementValues.length; i++) { - sb.append(evalues[i].stringifyValue()); - if ((i + 1) < evalues.length) { + sb.append(elementValues[i].stringifyValue()); + if ((i + 1) < elementValues.length) { sb.append(","); } } @@ -86,11 +86,11 @@ public ElementValue[] getElementValuesArray() { - return evalues; + return elementValues; } public int getElementValuesArraySize() { - return evalues.length; + return elementValues.length; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java index 2ec3e64..4b21e9c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -47,7 +47,7 @@ * @see Synthetic * @see Deprecated * @see Signature - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public abstract class Attribute implements Cloneable, Node { private static final boolean debug = false;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java index ef9b571..47e655e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java
@@ -33,17 +33,17 @@ * method ref, the number of bootstrap arguments and an array of the * bootstrap arguments. * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23"> * The class File Format : The BootstrapMethods Attribute</a> * @since 6.0 */ public class BootstrapMethod implements Cloneable { /** Index of the CONSTANT_MethodHandle_info structure in the constant_pool table */ - private int bootstrap_method_ref; + private int bootstrapMethodRef; /** Array of references to the constant_pool table */ - private int[] bootstrap_arguments; + private int[] bootstrapArguments; /** @@ -62,8 +62,8 @@ BootstrapMethod(final DataInput input) throws IOException { this(input.readUnsignedShort(), input.readUnsignedShort()); - for (int i = 0; i < bootstrap_arguments.length; i++) { - bootstrap_arguments[i] = input.readUnsignedShort(); + for (int i = 0; i < bootstrapArguments.length; i++) { + bootstrapArguments[i] = input.readUnsignedShort(); } } @@ -73,47 +73,47 @@ } /** - * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle - * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT_[type]_info + * @param bootstrapMethodRef int index into constant_pool of CONSTANT_MethodHandle + * @param bootstrapArguments int[] indices into constant_pool of CONSTANT_[type]_info */ - public BootstrapMethod(final int bootstrap_method_ref, final int[] bootstrap_arguments) { - this.bootstrap_method_ref = bootstrap_method_ref; - this.bootstrap_arguments = bootstrap_arguments; + public BootstrapMethod(final int bootstrapMethodRef, final int[] bootstrapArguments) { + this.bootstrapMethodRef = bootstrapMethodRef; + this.bootstrapArguments = bootstrapArguments; } /** * @return index into constant_pool of bootstrap_method */ public int getBootstrapMethodRef() { - return bootstrap_method_ref; + return bootstrapMethodRef; } /** - * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle + * @param bootstrapMethodRef int index into constant_pool of CONSTANT_MethodHandle */ - public void setBootstrapMethodRef(final int bootstrap_method_ref) { - this.bootstrap_method_ref = bootstrap_method_ref; + public void setBootstrapMethodRef(final int bootstrapMethodRef) { + this.bootstrapMethodRef = bootstrapMethodRef; } /** * @return int[] of bootstrap_method indices into constant_pool of CONSTANT_[type]_info */ public int[] getBootstrapArguments() { - return bootstrap_arguments; + return bootstrapArguments; } /** * @return count of number of boostrap arguments */ public int getNumBootstrapArguments() { - return bootstrap_arguments.length; + return bootstrapArguments.length; } /** - * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT_[type]_info + * @param bootstrapArguments int[] indices into constant_pool of CONSTANT_[type]_info */ - public void setBootstrapArguments(final int[] bootstrap_arguments) { - this.bootstrap_arguments = bootstrap_arguments; + public void setBootstrapArguments(final int[] bootstrapArguments) { + this.bootstrapArguments = bootstrapArguments; } /** @@ -121,25 +121,25 @@ */ @Override public final String toString() { - return "BootstrapMethod(" + bootstrap_method_ref + ", " + bootstrap_arguments.length + ", " - + Arrays.toString(bootstrap_arguments) + ")"; + return "BootstrapMethod(" + bootstrapMethodRef + ", " + bootstrapArguments.length + ", " + + Arrays.toString(bootstrapArguments) + ")"; } /** * @return Resolved string representation */ - public final String toString( final ConstantPool constant_pool ) { + public final String toString( final ConstantPool constantPool ) { final StringBuilder buf = new StringBuilder(); String bootstrap_method_name; - bootstrap_method_name = constant_pool.constantToString(bootstrap_method_ref, + bootstrap_method_name = constantPool.constantToString(bootstrapMethodRef, Const.CONSTANT_MethodHandle); buf.append(Utility.compactClassName(bootstrap_method_name, false)); - final int num_bootstrap_arguments = bootstrap_arguments.length; + final int num_bootstrap_arguments = bootstrapArguments.length; if (num_bootstrap_arguments > 0) { buf.append("\nMethod Arguments:"); for (int i = 0; i < num_bootstrap_arguments; i++) { buf.append("\n ").append(i).append(": "); - buf.append(constant_pool.constantToString(constant_pool.getConstant(bootstrap_arguments[i]))); + buf.append(constantPool.constantToString(constantPool.getConstant(bootstrapArguments[i]))); } } return buf.toString(); @@ -152,9 +152,9 @@ * @throws IOException */ public final void dump(final DataOutputStream file) throws IOException { - file.writeShort(bootstrap_method_ref); - file.writeShort(bootstrap_arguments.length); - for (final int bootstrap_argument : bootstrap_arguments) { + file.writeShort(bootstrapMethodRef); + file.writeShort(bootstrapArguments.length); + for (final int bootstrap_argument : bootstrapArguments) { file.writeShort(bootstrap_argument); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java index 6042f38..1a55a72 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java
@@ -30,13 +30,13 @@ /** * This class represents a BootstrapMethods attribute. * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23"> * The class File Format : The BootstrapMethods Attribute</a> * @since 6.0 */ public class BootstrapMethods extends Attribute { - private BootstrapMethod[] bootstrap_methods; // TODO this could be made final (setter is not used) + private BootstrapMethod[] bootstrapMethods; // TODO this could be made final (setter is not used) /** * Initialize from another object. Note that both objects use the same @@ -50,12 +50,12 @@ /** * @param name_index Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes - * @param bootstrap_methods array of bootstrap methods + * @param bootstrapMethods array of bootstrap methods * @param constant_pool Array of constants */ - public BootstrapMethods(final int name_index, final int length, final BootstrapMethod[] bootstrap_methods, final ConstantPool constant_pool) { + public BootstrapMethods(final int name_index, final int length, final BootstrapMethod[] bootstrapMethods, final ConstantPool constant_pool) { super(Const.ATTR_BOOTSTRAP_METHODS, name_index, length, constant_pool); - this.bootstrap_methods = bootstrap_methods; + this.bootstrapMethods = bootstrapMethods; } /** @@ -71,9 +71,9 @@ this(name_index, length, (BootstrapMethod[]) null, constant_pool); final int num_bootstrap_methods = input.readUnsignedShort(); - bootstrap_methods = new BootstrapMethod[num_bootstrap_methods]; + bootstrapMethods = new BootstrapMethod[num_bootstrap_methods]; for (int i = 0; i < num_bootstrap_methods; i++) { - bootstrap_methods[i] = new BootstrapMethod(input); + bootstrapMethods[i] = new BootstrapMethod(input); } } @@ -81,14 +81,14 @@ * @return array of bootstrap method "records" */ public final BootstrapMethod[] getBootstrapMethods() { - return bootstrap_methods; + return bootstrapMethods; } /** - * @param bootstrap_methods the array of bootstrap methods + * @param bootstrapMethods the array of bootstrap methods */ - public final void setBootstrapMethods(final BootstrapMethod[] bootstrap_methods) { - this.bootstrap_methods = bootstrap_methods; + public final void setBootstrapMethods(final BootstrapMethod[] bootstrapMethods) { + this.bootstrapMethods = bootstrapMethods; } /** @@ -105,10 +105,10 @@ @Override public BootstrapMethods copy(final ConstantPool _constant_pool) { final BootstrapMethods c = (BootstrapMethods) clone(); - c.bootstrap_methods = new BootstrapMethod[bootstrap_methods.length]; + c.bootstrapMethods = new BootstrapMethod[bootstrapMethods.length]; - for (int i = 0; i < bootstrap_methods.length; i++) { - c.bootstrap_methods[i] = bootstrap_methods[i].copy(); + for (int i = 0; i < bootstrapMethods.length; i++) { + c.bootstrapMethods[i] = bootstrapMethods[i].copy(); } c.setConstantPool(_constant_pool); return c; @@ -124,8 +124,8 @@ public final void dump(final DataOutputStream file) throws IOException { super.dump(file); - file.writeShort(bootstrap_methods.length); - for (final BootstrapMethod bootstrap_method : bootstrap_methods) { + file.writeShort(bootstrapMethods.length); + for (final BootstrapMethod bootstrap_method : bootstrapMethods) { bootstrap_method.dump(file); } } @@ -137,14 +137,14 @@ public final String toString() { final StringBuilder buf = new StringBuilder(); buf.append("BootstrapMethods("); - buf.append(bootstrap_methods.length); + buf.append(bootstrapMethods.length); buf.append("):"); - for (int i = 0; i < bootstrap_methods.length; i++) { + for (int i = 0; i < bootstrapMethods.length; i++) { buf.append("\n"); final int start = buf.length(); buf.append(" ").append(i).append(": "); final int indent_count = buf.length() - start; - final String[] lines = (bootstrap_methods[i].toString(super.getConstantPool())).split("\\r?\\n"); + final String[] lines = (bootstrapMethods[i].toString(super.getConstantPool())).split("\\r?\\n"); buf.append(lines[0]); for (int j = 1; j < lines.length; j++) { buf.append("\n").append(" ".substring(0,indent_count)).append(lines[j]);
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java index 4f26e4f..0ad2b78 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java
@@ -48,19 +48,19 @@ private DataInputStream dataInputStream; private final boolean fileOwned; - private final String file_name; - private String zip_file; - private int class_name_index; - private int superclass_name_index; + private final String fileName; + private String zipFile; + private int classNameIndex; + private int superclassNameIndex; private int major; // Compiler version private int minor; // Compiler version - private int access_flags; // Access rights of parsed class + private int accessFlags; // Access rights of parsed class private int[] interfaces; // Names of implemented interfaces - private ConstantPool constant_pool; // collection of constants + private ConstantPool constantPool; // collection of constants private Field[] fields; // class fields, i.e., its variables private Method[] methods; // methods defined in the class private Attribute[] attributes; // attributes defined in the class - private final boolean is_zip; // Loaded from zip file + private final boolean isZip; // Loaded from zip file private static final int BUFSIZE = 8192; @@ -68,13 +68,13 @@ * Parses class from the given stream. * * @param inputStream Input stream - * @param file_name File name + * @param fileName File name */ - public ClassParser(final InputStream inputStream, final String file_name) { - this.file_name = file_name; + public ClassParser(final InputStream inputStream, final String fileName) { + this.fileName = fileName; fileOwned = false; final String clazz = inputStream.getClass().getName(); // Not a very clean solution ... - is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); + isZip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); if (inputStream instanceof DataInputStream) { this.dataInputStream = (DataInputStream) inputStream; } else { @@ -85,25 +85,25 @@ /** Parses class from given .class file. * - * @param file_name file name + * @param fileName file name */ - public ClassParser(final String file_name) { - is_zip = false; - this.file_name = file_name; + public ClassParser(final String fileName) { + isZip = false; + this.fileName = fileName; fileOwned = true; } /** Parses class from given .class file in a ZIP-archive * - * @param zip_file zip file name - * @param file_name file name + * @param zipFile zip file name + * @param fileName file name */ - public ClassParser(final String zip_file, final String file_name) { - is_zip = true; + public ClassParser(final String zipFile, final String fileName) { + isZip = true; fileOwned = true; - this.zip_file = zip_file; - this.file_name = file_name; + this.zipFile = zipFile; + this.fileName = fileName; } @@ -122,19 +122,19 @@ ZipFile zip = null; try { if (fileOwned) { - if (is_zip) { - zip = new ZipFile(zip_file); - final ZipEntry entry = zip.getEntry(file_name); + if (isZip) { + zip = new ZipFile(zipFile); + final ZipEntry entry = zip.getEntry(fileName); if (entry == null) { - throw new IOException("File " + file_name + " not found"); + throw new IOException("File " + fileName + " not found"); } dataInputStream = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), BUFSIZE)); } else { dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream( - file_name), BUFSIZE)); + fileName), BUFSIZE)); } } /****************** Read headers ********************************/ @@ -165,8 +165,8 @@ // int bytes = file.available(); // byte[] buf = new byte[bytes]; // file.read(buf); - // if(!(is_zip && (buf.length == 1))) { - // System.err.println("WARNING: Trailing garbage at end of " + file_name); + // if(!(isZip && (buf.length == 1))) { + // System.err.println("WARNING: Trailing garbage at end of " + fileName); // System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf)); // } // } @@ -190,8 +190,8 @@ } } // Return the information we have gathered in a new object - return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, - access_flags, constant_pool, interfaces, fields, methods, attributes, is_zip + return new JavaClass(classNameIndex, superclassNameIndex, fileName, major, minor, + accessFlags, constantPool, interfaces, fields, methods, attributes, isZip ? JavaClass.ZIP : JavaClass.FILE); } @@ -206,7 +206,7 @@ final int attributes_count = dataInputStream.readUnsignedShort(); attributes = new Attribute[attributes_count]; for (int i = 0; i < attributes_count; i++) { - attributes[i] = Attribute.readAttribute(dataInputStream, constant_pool); + attributes[i] = Attribute.readAttribute(dataInputStream, constantPool); } } @@ -217,19 +217,19 @@ * @throws ClassFormatException */ private void readClassInfo() throws IOException, ClassFormatException { - access_flags = dataInputStream.readUnsignedShort(); + accessFlags = dataInputStream.readUnsignedShort(); /* Interfaces are implicitely abstract, the flag should be set * according to the JVM specification. */ - if ((access_flags & Const.ACC_INTERFACE) != 0) { - access_flags |= Const.ACC_ABSTRACT; + if ((accessFlags & Const.ACC_INTERFACE) != 0) { + accessFlags |= Const.ACC_ABSTRACT; } - if (((access_flags & Const.ACC_ABSTRACT) != 0) - && ((access_flags & Const.ACC_FINAL) != 0)) { - throw new ClassFormatException("Class " + file_name + " can't be both final and abstract"); + if (((accessFlags & Const.ACC_ABSTRACT) != 0) + && ((accessFlags & Const.ACC_FINAL) != 0)) { + throw new ClassFormatException("Class " + fileName + " can't be both final and abstract"); } - class_name_index = dataInputStream.readUnsignedShort(); - superclass_name_index = dataInputStream.readUnsignedShort(); + classNameIndex = dataInputStream.readUnsignedShort(); + superclassNameIndex = dataInputStream.readUnsignedShort(); } @@ -239,7 +239,7 @@ * @throws ClassFormatException */ private void readConstantPool() throws IOException, ClassFormatException { - constant_pool = new ConstantPool(dataInputStream); + constantPool = new ConstantPool(dataInputStream); } @@ -252,7 +252,7 @@ final int fields_count = dataInputStream.readUnsignedShort(); fields = new Field[fields_count]; for (int i = 0; i < fields_count; i++) { - fields[i] = new Field(dataInputStream, constant_pool); + fields[i] = new Field(dataInputStream, constantPool); } } @@ -266,7 +266,7 @@ */ private void readID() throws IOException, ClassFormatException { if (dataInputStream.readInt() != Const.JVM_CLASSFILE_MAGIC) { - throw new ClassFormatException(file_name + " is not a Java .class file"); + throw new ClassFormatException(fileName + " is not a Java .class file"); } } @@ -294,7 +294,7 @@ final int methods_count = dataInputStream.readUnsignedShort(); methods = new Method[methods_count]; for (int i = 0; i < methods_count; i++) { - methods[i] = new Method(dataInputStream, constant_pool); + methods[i] = new Method(dataInputStream, constantPool); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java index 81a54ae..c486f2b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java
@@ -46,10 +46,10 @@ */ public final class Code extends Attribute { - private int max_stack; // Maximum size of stack used by this method // TODO this could be made final (setter is not used) - private int max_locals; // Number of local variables // TODO this could be made final (setter is not used) + private int maxStack; // Maximum size of stack used by this method // TODO this could be made final (setter is not used) + private int maxLocals; // Number of local variables // TODO this could be made final (setter is not used) private byte[] code; // Actual byte code - private CodeException[] exception_table; // Table of handled exceptions + private CodeException[] exceptionTable; // Table of handled exceptions private Attribute[] attributes; // or LocalVariable @@ -81,9 +81,9 @@ * handler is active, i.e., a try { ... } catch() block. */ final int exception_table_length = file.readUnsignedShort(); - exception_table = new CodeException[exception_table_length]; + exceptionTable = new CodeException[exception_table_length]; for (int i = 0; i < exception_table_length; i++) { - exception_table[i] = new CodeException(file); + exceptionTable[i] = new CodeException(file); } /* Read all attributes, currently `LineNumberTable' and * `LocalVariableTable' @@ -104,20 +104,20 @@ /** * @param name_index Index pointing to the name <em>Code</em> * @param length Content length in bytes - * @param max_stack Maximum size of stack - * @param max_locals Number of local variables + * @param maxStack Maximum size of stack + * @param maxLocals Number of local variables * @param code Actual byte code - * @param exception_table Table of handled exceptions + * @param exceptionTable of handled exceptions * @param attributes Attributes of code: LineNumber or LocalVariable * @param constant_pool Array of constants */ - public Code(final int name_index, final int length, final int max_stack, final int max_locals, final byte[] code, - final CodeException[] exception_table, final Attribute[] attributes, final ConstantPool constant_pool) { + public Code(final int name_index, final int length, final int maxStack, final int maxLocals, final byte[] code, + final CodeException[] exceptionTable, final Attribute[] attributes, final ConstantPool constant_pool) { super(Const.ATTR_CODE, name_index, length, constant_pool); - this.max_stack = max_stack; - this.max_locals = max_locals; + this.maxStack = maxStack; + this.maxLocals = maxLocals; this.code = code != null ? code : new byte[0]; - this.exception_table = exception_table != null ? exception_table : new CodeException[0]; + this.exceptionTable = exceptionTable != null ? exceptionTable : new CodeException[0]; this.attributes = attributes != null ? attributes : new Attribute[0]; super.setLength(calculateLength()); // Adjust length } @@ -145,12 +145,12 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(max_stack); - file.writeShort(max_locals); + file.writeShort(maxStack); + file.writeShort(maxLocals); file.writeInt(code.length); file.write(code, 0, code.length); - file.writeShort(exception_table.length); - for (final CodeException exception : exception_table) { + file.writeShort(exceptionTable.length); + for (final CodeException exception : exceptionTable) { exception.dump(file); } file.writeShort(attributes.length); @@ -208,7 +208,7 @@ * @see CodeException */ public CodeException[] getExceptionTable() { - return exception_table; + return exceptionTable; } @@ -216,7 +216,7 @@ * @return Number of local variables. */ public int getMaxLocals() { - return max_locals; + return maxLocals; } @@ -224,7 +224,7 @@ * @return Maximum size of stack used by this method. */ public int getMaxStack() { - return max_stack; + return maxStack; } @@ -233,10 +233,10 @@ * and excluding all its attributes */ private int getInternalLength() { - return 2 /*max_stack*/+ 2 /*max_locals*/+ 4 /*code length*/ + return 2 /*maxStack*/+ 2 /*maxLocals*/+ 4 /*code length*/ + code.length /*byte-code*/ + 2 /*exception-table length*/ - + 8 * (exception_table == null ? 0 : exception_table.length) /* exception table */ + + 8 * (exceptionTable == null ? 0 : exceptionTable.length) /* exception table */ + 2 /* attributes count */; } @@ -275,27 +275,27 @@ /** - * @param exception_table exception table + * @param exceptionTable exception table */ - public void setExceptionTable( final CodeException[] exception_table ) { - this.exception_table = exception_table != null ? exception_table : new CodeException[0]; + public void setExceptionTable( final CodeException[] exceptionTable ) { + this.exceptionTable = exceptionTable != null ? exceptionTable : new CodeException[0]; super.setLength(calculateLength()); // Adjust length } /** - * @param max_locals maximum number of local variables + * @param maxLocals maximum number of local variables */ - public void setMaxLocals( final int max_locals ) { - this.max_locals = max_locals; + public void setMaxLocals( final int maxLocals ) { + this.maxLocals = maxLocals; } /** - * @param max_stack maximum stack size + * @param maxStack maximum stack size */ - public void setMaxStack( final int max_stack ) { - this.max_stack = max_stack; + public void setMaxStack( final int maxStack ) { + this.maxStack = maxStack; } @@ -304,18 +304,19 @@ */ public String toString( final boolean verbose ) { final StringBuilder buf = new StringBuilder(100); // CHECKSTYLE IGNORE MagicNumber - buf.append("Code(max_stack = ").append(max_stack).append(", max_locals = ").append( - max_locals).append(", code_length = ").append(code.length).append(")\n").append( + buf.append("Code(maxStack = ").append(maxStack).append(", maxLocals = ").append( + maxLocals).append(", code_length = ").append(code.length).append(")\n").append( Utility.codeToString(code, super.getConstantPool(), 0, -1, verbose)); - if (exception_table.length > 0) { + if (exceptionTable.length > 0) { buf.append("\nException handler(s) = \n").append("From\tTo\tHandler\tType\n"); - for (final CodeException exception : exception_table) { + for (final CodeException exception : exceptionTable) { buf.append(exception.toString(super.getConstantPool(), verbose)).append("\n"); } } if (attributes.length > 0) { buf.append("\nAttribute(s) = "); for (final Attribute attribute : attributes) { + buf.append("\n").append(attribute.getName()).append(":"); buf.append("\n").append(attribute); } } @@ -345,9 +346,9 @@ System.arraycopy(code, 0, c.code, 0, code.length); } c.setConstantPool(_constant_pool); - c.exception_table = new CodeException[exception_table.length]; - for (int i = 0; i < exception_table.length; i++) { - c.exception_table[i] = exception_table[i].copy(); + c.exceptionTable = new CodeException[exceptionTable.length]; + for (int i = 0; i < exceptionTable.length; i++) { + c.exceptionTable[i] = exceptionTable[i].copy(); } c.attributes = new Attribute[attributes.length]; for (int i = 0; i < attributes.length; i++) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java index 4512bd8..a1b8e46 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,16 +32,16 @@ * particular exception handler is active. * * @see Code - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public final class CodeException implements Cloneable, Node { - private int start_pc; // Range in the code the exception handler is - private int end_pc; // active. start_pc is inclusive, end_pc exclusive - private int handler_pc; /* Starting address of exception handler, i.e., + private int startPc; // Range in the code the exception handler is + private int endPc; // active. startPc is inclusive, endPc exclusive + private int handlerPc; /* Starting address of exception handler, i.e., * an offset from start of code. */ - private int catch_type; /* If this is zero the handler catches any + private int catchType; /* If this is zero the handler catches any * exception, otherwise it points to the * exception class which is to be caught. */ @@ -67,20 +67,20 @@ /** - * @param start_pc Range in the code the exception handler is active, - * start_pc is inclusive while - * @param end_pc is exclusive - * @param handler_pc Starting address of exception handler, i.e., + * @param startPc Range in the code the exception handler is active, + * startPc is inclusive while + * @param endPc is exclusive + * @param handlerPc Starting address of exception handler, i.e., * an offset from start of code. - * @param catch_type If zero the handler catches any + * @param catchType If zero the handler catches any * exception, otherwise it points to the exception class which is * to be caught. */ - public CodeException(final int start_pc, final int end_pc, final int handler_pc, final int catch_type) { - this.start_pc = start_pc; - this.end_pc = end_pc; - this.handler_pc = handler_pc; - this.catch_type = catch_type; + public CodeException(final int startPc, final int endPc, final int handlerPc, final int catchType) { + this.startPc = startPc; + this.endPc = endPc; + this.handlerPc = handlerPc; + this.catchType = catchType; } @@ -104,10 +104,10 @@ * @throws IOException */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(start_pc); - file.writeShort(end_pc); - file.writeShort(handler_pc); - file.writeShort(catch_type); + file.writeShort(startPc); + file.writeShort(endPc); + file.writeShort(handlerPc); + file.writeShort(catchType); } @@ -116,7 +116,7 @@ * the exception class which is to be caught. */ public int getCatchType() { - return catch_type; + return catchType; } @@ -124,7 +124,7 @@ * @return Exclusive end index of the region where the handler is active. */ public int getEndPC() { - return end_pc; + return endPc; } @@ -132,7 +132,7 @@ * @return Starting address of exception handler, relative to the code. */ public int getHandlerPC() { - return handler_pc; + return handlerPc; } @@ -140,39 +140,39 @@ * @return Inclusive start index of the region where the handler is active. */ public int getStartPC() { - return start_pc; + return startPc; } /** - * @param catch_type the type of exception that is caught + * @param catchType the type of exception that is caught */ - public void setCatchType( final int catch_type ) { - this.catch_type = catch_type; + public void setCatchType( final int catchType ) { + this.catchType = catchType; } /** - * @param end_pc end of handled block + * @param endPc end of handled block */ - public void setEndPC( final int end_pc ) { - this.end_pc = end_pc; + public void setEndPC( final int endPc ) { + this.endPc = endPc; } /** - * @param handler_pc where the actual code is + * @param handlerPc where the actual code is */ - public void setHandlerPC( final int handler_pc ) { // TODO unused - this.handler_pc = handler_pc; + public void setHandlerPC( final int handlerPc ) { // TODO unused + this.handlerPc = handlerPc; } /** - * @param start_pc start of handled block + * @param startPc start of handled block */ - public void setStartPC( final int start_pc ) { // TODO unused - this.start_pc = start_pc; + public void setStartPC( final int startPc ) { // TODO unused + this.startPc = startPc; } @@ -181,8 +181,8 @@ */ @Override public String toString() { - return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = " - + handler_pc + ", catch_type = " + catch_type + ")"; + return "CodeException(startPc = " + startPc + ", endPc = " + endPc + ", handlerPc = " + + handlerPc + ", catchType = " + catchType + ")"; } @@ -191,13 +191,13 @@ */ public String toString( final ConstantPool cp, final boolean verbose ) { String str; - if (catch_type == 0) { + if (catchType == 0) { str = "<Any exception>(0)"; } else { - str = Utility.compactClassName(cp.getConstantString(catch_type, Const.CONSTANT_Class), false) - + (verbose ? "(" + catch_type + ")" : ""); + str = Utility.compactClassName(cp.getConstantString(catchType, Const.CONSTANT_Class), false) + + (verbose ? "(" + catchType + ")" : ""); } - return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; + return startPc + "\t" + endPc + "\t" + handlerPc + "\t" + str; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java index fa431a6..56ffb23 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,7 +32,7 @@ * in the constant pool of a class file. The classes keep closely to * the JVM specification. * - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public abstract class Constant implements Cloneable, Node {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java index b33ce49..ed64179 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java
@@ -35,7 +35,7 @@ */ public final class ConstantClass extends Constant implements ConstantObject { - private int name_index; // Identical to ConstantString except for the name + private int nameIndex; // Identical to ConstantString except for the name /** @@ -58,12 +58,12 @@ /** - * @param name_index Name index in constant pool. Should refer to a + * @param nameIndex Name index in constant pool. Should refer to a * ConstantUtf8. */ - public ConstantClass(final int name_index) { + public ConstantClass(final int nameIndex) { super(Const.CONSTANT_Class); - this.name_index = name_index; + this.nameIndex = nameIndex; } @@ -89,7 +89,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { file.writeByte(super.getTag()); - file.writeShort(name_index); + file.writeShort(nameIndex); } @@ -97,15 +97,15 @@ * @return Name index in constant pool of class name. */ public int getNameIndex() { - return name_index; + return nameIndex; } /** - * @param name_index the name index in the constant pool of this Constant Class + * @param nameIndex the name index in the constant pool of this Constant Class */ - public void setNameIndex( final int name_index ) { - this.name_index = name_index; + public void setNameIndex( final int nameIndex ) { + this.nameIndex = nameIndex; } @@ -113,7 +113,7 @@ */ @Override public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(name_index, Const.CONSTANT_Utf8); + final Constant c = cp.getConstant(nameIndex, Const.CONSTANT_Utf8); return ((ConstantUtf8) c).getBytes(); } @@ -130,6 +130,6 @@ */ @Override public String toString() { - return super.toString() + "(name_index = " + name_index + ")"; + return super.toString() + "(nameIndex = " + nameIndex + ")"; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java index 76039c6..7191c7e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java
@@ -31,7 +31,7 @@ * and represents a reference to a invoke dynamic. * * @see Constant - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10"> * The CONSTANT_InvokeDynamic_info Structure in The Java Virtual Machine Specification</a> * @since 6.0 */
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java index 9e5ce84..d516f1a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java
@@ -36,8 +36,8 @@ */ public final class ConstantMethodHandle extends Constant { - private int reference_kind; - private int reference_index; + private int referenceKind; + private int referenceIndex; /** @@ -61,8 +61,8 @@ public ConstantMethodHandle(final int reference_kind, final int reference_index) { super(Const.CONSTANT_MethodHandle); - this.reference_kind = reference_kind; - this.reference_index = reference_index; + this.referenceKind = reference_kind; + this.referenceIndex = reference_index; } @@ -88,28 +88,28 @@ @Override public void dump( final DataOutputStream file ) throws IOException { file.writeByte(super.getTag()); - file.writeByte(reference_kind); - file.writeShort(reference_index); + file.writeByte(referenceKind); + file.writeShort(referenceIndex); } public int getReferenceKind() { - return reference_kind; + return referenceKind; } public void setReferenceKind(final int reference_kind) { - this.reference_kind = reference_kind; + this.referenceKind = reference_kind; } public int getReferenceIndex() { - return reference_index; + return referenceIndex; } public void setReferenceIndex(final int reference_index) { - this.reference_index = reference_index; + this.referenceIndex = reference_index; } @@ -118,7 +118,7 @@ */ @Override public String toString() { - return super.toString() + "(reference_kind = " + reference_kind + - ", reference_index = " + reference_index + ")"; + return super.toString() + "(referenceKind = " + referenceKind + + ", referenceIndex = " + referenceIndex + ")"; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java index d9ea592..08f894f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java
@@ -36,7 +36,7 @@ */ public final class ConstantMethodType extends Constant { - private int descriptor_index; + private int descriptorIndex; /** @@ -60,7 +60,7 @@ public ConstantMethodType(final int descriptor_index) { super(Const.CONSTANT_MethodType); - this.descriptor_index = descriptor_index; + this.descriptorIndex = descriptor_index; } @@ -86,17 +86,17 @@ @Override public void dump( final DataOutputStream file ) throws IOException { file.writeByte(super.getTag()); - file.writeShort(descriptor_index); + file.writeShort(descriptorIndex); } public int getDescriptorIndex() { - return descriptor_index; + return descriptorIndex; } public void setDescriptorIndex(final int descriptor_index) { - this.descriptor_index = descriptor_index; + this.descriptorIndex = descriptor_index; } @@ -105,6 +105,6 @@ */ @Override public String toString() { - return super.toString() + "(descriptor_index = " + descriptor_index + ")"; + return super.toString() + "(descriptorIndex = " + descriptorIndex + ")"; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java index aee6891..12c3706 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java
@@ -38,7 +38,7 @@ */ public final class ConstantModule extends Constant implements ConstantObject { - private int name_index; + private int nameIndex; /** @@ -61,12 +61,12 @@ /** - * @param name_index Name index in constant pool. Should refer to a + * @param nameIndex Name index in constant pool. Should refer to a * ConstantUtf8. */ - public ConstantModule(final int name_index) { + public ConstantModule(final int nameIndex) { super(Const.CONSTANT_Module); - this.name_index = name_index; + this.nameIndex = nameIndex; } @@ -92,7 +92,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { file.writeByte(super.getTag()); - file.writeShort(name_index); + file.writeShort(nameIndex); } @@ -100,15 +100,15 @@ * @return Name index in constant pool of module name. */ public int getNameIndex() { - return name_index; + return nameIndex; } /** - * @param name_index the name index in the constant pool of this Constant Module + * @param nameIndex the name index in the constant pool of this Constant Module */ - public void setNameIndex( final int name_index ) { - this.name_index = name_index; + public void setNameIndex( final int nameIndex ) { + this.nameIndex = nameIndex; } @@ -116,7 +116,7 @@ */ @Override public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(name_index, Const.CONSTANT_Utf8); + final Constant c = cp.getConstant(nameIndex, Const.CONSTANT_Utf8); return ((ConstantUtf8) c).getBytes(); } @@ -133,6 +133,6 @@ */ @Override public String toString() { - return super.toString() + "(name_index = " + name_index + ")"; + return super.toString() + "(nameIndex = " + nameIndex + ")"; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java index 2f0494a..f1ce119 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java
@@ -36,8 +36,8 @@ */ public final class ConstantNameAndType extends Constant { - private int name_index; // Name of field/method - private int signature_index; // and its signature. + private int nameIndex; // Name of field/method + private int signatureIndex; // and its signature. /** @@ -60,13 +60,13 @@ /** - * @param name_index Name of field/method - * @param signature_index and its signature + * @param nameIndex Name of field/method + * @param signatureIndex and its signature */ - public ConstantNameAndType(final int name_index, final int signature_index) { + public ConstantNameAndType(final int nameIndex, final int signatureIndex) { super(Const.CONSTANT_NameAndType); - this.name_index = name_index; - this.signature_index = signature_index; + this.nameIndex = nameIndex; + this.signatureIndex = signatureIndex; } @@ -92,8 +92,8 @@ @Override public void dump( final DataOutputStream file ) throws IOException { file.writeByte(super.getTag()); - file.writeShort(name_index); - file.writeShort(signature_index); + file.writeShort(nameIndex); + file.writeShort(signatureIndex); } @@ -101,7 +101,7 @@ * @return Name index in constant pool of field/method name. */ public int getNameIndex() { - return name_index; + return nameIndex; } @@ -116,7 +116,7 @@ * @return Index in constant pool of field/method signature. */ public int getSignatureIndex() { - return signature_index; + return signatureIndex; } @@ -128,18 +128,18 @@ /** - * @param name_index the name index of this constant + * @param nameIndex the name index of this constant */ - public void setNameIndex( final int name_index ) { - this.name_index = name_index; + public void setNameIndex( final int nameIndex ) { + this.nameIndex = nameIndex; } /** - * @param signature_index the signature index in the constant pool of this type + * @param signatureIndex the signature index in the constant pool of this type */ - public void setSignatureIndex( final int signature_index ) { - this.signature_index = signature_index; + public void setSignatureIndex( final int signatureIndex ) { + this.signatureIndex = signatureIndex; } @@ -148,7 +148,7 @@ */ @Override public String toString() { - return super.toString() + "(name_index = " + name_index + ", signature_index = " - + signature_index + ")"; + return super.toString() + "(nameIndex = " + nameIndex + ", signatureIndex = " + + signatureIndex + ")"; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java index d44d199..2770f95 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java
@@ -38,7 +38,7 @@ */ public final class ConstantPackage extends Constant implements ConstantObject { - private int name_index; + private int nameIndex; /** @@ -61,12 +61,12 @@ /** - * @param name_index Name index in constant pool. Should refer to a + * @param nameIndex Name index in constant pool. Should refer to a * ConstantUtf8. */ - public ConstantPackage(final int name_index) { + public ConstantPackage(final int nameIndex) { super(Const.CONSTANT_Package); - this.name_index = name_index; + this.nameIndex = nameIndex; } @@ -92,7 +92,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { file.writeByte(super.getTag()); - file.writeShort(name_index); + file.writeShort(nameIndex); } @@ -100,15 +100,15 @@ * @return Name index in constant pool of package name. */ public int getNameIndex() { - return name_index; + return nameIndex; } /** - * @param name_index the name index in the constant pool of this Constant Package + * @param nameIndex the name index in the constant pool of this Constant Package */ - public void setNameIndex( final int name_index ) { - this.name_index = name_index; + public void setNameIndex( final int nameIndex ) { + this.nameIndex = nameIndex; } @@ -116,7 +116,7 @@ */ @Override public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(name_index, Const.CONSTANT_Utf8); + final Constant c = cp.getConstant(nameIndex, Const.CONSTANT_Utf8); return ((ConstantUtf8) c).getBytes(); } @@ -133,6 +133,6 @@ */ @Override public String toString() { - return super.toString() + "(name_index = " + name_index + ")"; + return super.toString() + "(nameIndex = " + nameIndex + ")"; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java index d294fde..303b2b8 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java
@@ -40,13 +40,13 @@ */ public class ConstantPool implements Cloneable, Node { - private Constant[] constant_pool; + private Constant[] constantPool; /** - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public ConstantPool(final Constant[] constant_pool) { - this.constant_pool = constant_pool; + public ConstantPool(final Constant[] constantPool) { + this.constantPool = constantPool; } /** @@ -59,12 +59,12 @@ public ConstantPool(final DataInput input) throws IOException, ClassFormatException { byte tag; final int constant_pool_count = input.readUnsignedShort(); - constant_pool = new Constant[constant_pool_count]; - /* constant_pool[0] is unused by the compiler and may be used freely + constantPool = new Constant[constant_pool_count]; + /* constantPool[0] is unused by the compiler and may be used freely * by the implementation. */ for (int i = 1; i < constant_pool_count; i++) { - constant_pool[i] = Constant.readConstant(input); + constantPool[i] = Constant.readConstant(input); /* Quote from the JVM specification: * "All eight byte constants take up two spots in the constant pool. * If this is the n'th byte in the constant pool, then the next item @@ -72,7 +72,7 @@ * * Thus we have to increment the index counter. */ - tag = constant_pool[i].getTag(); + tag = constantPool[i].getTag(); if ((tag == Const.CONSTANT_Double) || (tag == Const.CONSTANT_Long)) { i++; } @@ -169,7 +169,7 @@ str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); break; default: // Never reached - throw new RuntimeException("Unknown constant type " + tag); + throw new IllegalArgumentException("Unknown constant type " + tag); } return str; } @@ -222,10 +222,10 @@ * @throws IOException */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(constant_pool.length); - for (int i = 1; i < constant_pool.length; i++) { - if (constant_pool[i] != null) { - constant_pool[i].dump(file); + file.writeShort(constantPool.length); + for (int i = 1; i < constantPool.length; i++) { + if (constantPool[i] != null) { + constantPool[i].dump(file); } } } @@ -238,11 +238,11 @@ * @see Constant */ public Constant getConstant( final int index ) { - if (index >= constant_pool.length || index < 0) { + if (index >= constantPool.length || index < 0) { throw new ClassFormatException("Invalid constant pool reference: " + index - + ". Constant pool size is: " + constant_pool.length); + + ". Constant pool size is: " + constantPool.length); } - return constant_pool[index]; + return constantPool[index]; } /** @@ -273,7 +273,7 @@ * @see Constant */ public Constant[] getConstantPool() { - return constant_pool; + return constantPool; } /** @@ -314,7 +314,7 @@ i = ((ConstantPackage) c).getNameIndex(); break; default: - throw new RuntimeException("getConstantString called with illegal tag " + tag); + throw new IllegalArgumentException("getConstantString called with illegal tag " + tag); } // Finally get the string from the constant pool c = getConstant(i, Const.CONSTANT_Utf8); @@ -326,7 +326,7 @@ * @return Length of constant pool. */ public int getLength() { - return constant_pool == null ? 0 : constant_pool.length; + return constantPool == null ? 0 : constantPool.length; } @@ -334,15 +334,15 @@ * @param constant Constant to set */ public void setConstant( final int index, final Constant constant ) { - constant_pool[index] = constant; + constantPool[index] = constant; } /** - * @param constant_pool + * @param constantPool */ - public void setConstantPool( final Constant[] constant_pool ) { - this.constant_pool = constant_pool; + public void setConstantPool( final Constant[] constantPool ) { + this.constantPool = constantPool; } @@ -352,8 +352,8 @@ @Override public String toString() { final StringBuilder buf = new StringBuilder(); - for (int i = 1; i < constant_pool.length; i++) { - buf.append(i).append(")").append(constant_pool[i]).append("\n"); + for (int i = 1; i < constantPool.length; i++) { + buf.append(i).append(")").append(constantPool[i]).append("\n"); } return buf.toString(); } @@ -366,10 +366,10 @@ ConstantPool c = null; try { c = (ConstantPool) clone(); - c.constant_pool = new Constant[constant_pool.length]; - for (int i = 1; i < constant_pool.length; i++) { - if (constant_pool[i] != null) { - c.constant_pool[i] = constant_pool[i].copy(); + c.constantPool = new Constant[constantPool.length]; + for (int i = 1; i < constantPool.length; i++) { + if (constantPool[i] != null) { + c.constantPool[i] = constantPool[i].copy(); } } } catch (final CloneNotSupportedException e) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java index e7ce0ea..cdc2c0c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java
@@ -35,7 +35,7 @@ */ public final class ConstantString extends Constant implements ConstantObject { - private int string_index; // Identical to ConstantClass except for this name + private int stringIndex; // Identical to ConstantClass except for this name /** @@ -58,11 +58,11 @@ /** - * @param string_index Index of Constant_Utf8 in constant pool + * @param stringIndex Index of Constant_Utf8 in constant pool */ - public ConstantString(final int string_index) { + public ConstantString(final int stringIndex) { super(Const.CONSTANT_String); - this.string_index = string_index; + this.stringIndex = stringIndex; } @@ -88,7 +88,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { file.writeByte(super.getTag()); - file.writeShort(string_index); + file.writeShort(stringIndex); } @@ -96,15 +96,15 @@ * @return Index in constant pool of the string (ConstantUtf8). */ public int getStringIndex() { - return string_index; + return stringIndex; } /** - * @param string_index the index into the constant of the string value + * @param stringIndex the index into the constant of the string value */ - public void setStringIndex( final int string_index ) { - this.string_index = string_index; + public void setStringIndex( final int stringIndex ) { + this.stringIndex = stringIndex; } @@ -113,7 +113,7 @@ */ @Override public String toString() { - return super.toString() + "(string_index = " + string_index + ")"; + return super.toString() + "(stringIndex = " + stringIndex + ")"; } @@ -121,7 +121,7 @@ */ @Override public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(string_index, Const.CONSTANT_Utf8); + final Constant c = cp.getConstant(stringIndex, Const.CONSTANT_Utf8); return ((ConstantUtf8) c).getBytes(); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java index 6be8e23..4b58ae8 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java
@@ -36,7 +36,7 @@ */ public final class ConstantValue extends Attribute { - private int constantvalue_index; + private int constantValueIndex; /** @@ -65,13 +65,13 @@ /** * @param name_index Name index in constant pool * @param length Content length in bytes - * @param constantvalue_index Index in constant pool + * @param constantValueIndex Index in constant pool * @param constant_pool Array of constants */ - public ConstantValue(final int name_index, final int length, final int constantvalue_index, + public ConstantValue(final int name_index, final int length, final int constantValueIndex, final ConstantPool constant_pool) { super(Const.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); - this.constantvalue_index = constantvalue_index; + this.constantValueIndex = constantValueIndex; } @@ -97,7 +97,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(constantvalue_index); + file.writeShort(constantValueIndex); } @@ -105,15 +105,15 @@ * @return Index in constant pool of constant value. */ public int getConstantValueIndex() { - return constantvalue_index; + return constantValueIndex; } /** - * @param constantvalue_index the index info the constant pool of this constant value + * @param constantValueIndex the index info the constant pool of this constant value */ - public void setConstantValueIndex( final int constantvalue_index ) { - this.constantvalue_index = constantvalue_index; + public void setConstantValueIndex( final int constantValueIndex ) { + this.constantValueIndex = constantValueIndex; } @@ -122,7 +122,7 @@ */ @Override public String toString() { - Constant c = super.getConstantPool().getConstant(constantvalue_index); + Constant c = super.getConstantPool().getConstant(constantValueIndex); String buf; int i; // Print constant to string depending on its type
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java index 738776d..d5967ff 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,7 +26,7 @@ /** * @since 6.0 - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public abstract class ElementValue { @@ -105,7 +105,7 @@ return new ArrayElementValue(ARRAY, evalues, cpool); default: - throw new RuntimeException("Unexpected element value kind in annotation: " + type); + throw new IllegalArgumentException("Unexpected element value kind in annotation: " + type); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java index 8aff839..ac8632e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java
@@ -41,7 +41,7 @@ { super(type, cpool); if (type != ENUM_CONSTANT) { - throw new RuntimeException( + throw new IllegalArgumentException( "Only element values of type enum can be built with this ctor - type specified: " + type); } this.typeIdx = typeIdx;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java index b851792..cddae11 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java
@@ -39,7 +39,7 @@ */ public final class ExceptionTable extends Attribute { - private int[] exception_index_table; // constant pool + private int[] exceptionIndexTable; // constant pool /** @@ -54,30 +54,30 @@ /** * @param name_index Index in constant pool * @param length Content length in bytes - * @param exception_index_table Table of indices in constant pool + * @param exceptionIndexTable Table of indices in constant pool * @param constant_pool Array of constants */ - public ExceptionTable(final int name_index, final int length, final int[] exception_index_table, + public ExceptionTable(final int name_index, final int length, final int[] exceptionIndexTable, final ConstantPool constant_pool) { super(Const.ATTR_EXCEPTIONS, name_index, length, constant_pool); - this.exception_index_table = exception_index_table != null ? exception_index_table : new int[0]; + this.exceptionIndexTable = exceptionIndexTable != null ? exceptionIndexTable : new int[0]; } /** * Construct object from input stream. - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants + * @param constantPool Array of constants * @throws IOException */ - ExceptionTable(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - this(name_index, length, (int[]) null, constant_pool); + ExceptionTable(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (int[]) null, constantPool); final int number_of_exceptions = input.readUnsignedShort(); - exception_index_table = new int[number_of_exceptions]; + exceptionIndexTable = new int[number_of_exceptions]; for (int i = 0; i < number_of_exceptions; i++) { - exception_index_table[i] = input.readUnsignedShort(); + exceptionIndexTable[i] = input.readUnsignedShort(); } } @@ -104,8 +104,8 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(exception_index_table.length); - for (final int index : exception_index_table) { + file.writeShort(exceptionIndexTable.length); + for (final int index : exceptionIndexTable) { file.writeShort(index); } } @@ -115,7 +115,7 @@ * @return Array of indices into constant pool of thrown exceptions. */ public int[] getExceptionIndexTable() { - return exception_index_table; + return exceptionIndexTable; } @@ -123,7 +123,7 @@ * @return Length of exception table. */ public int getNumberOfExceptions() { - return exception_index_table == null ? 0 : exception_index_table.length; + return exceptionIndexTable == null ? 0 : exceptionIndexTable.length; } @@ -131,9 +131,9 @@ * @return class names of thrown exceptions */ public String[] getExceptionNames() { - final String[] names = new String[exception_index_table.length]; - for (int i = 0; i < exception_index_table.length; i++) { - names[i] = super.getConstantPool().getConstantString(exception_index_table[i], + final String[] names = new String[exceptionIndexTable.length]; + for (int i = 0; i < exceptionIndexTable.length; i++) { + names[i] = super.getConstantPool().getConstantString(exceptionIndexTable[i], Const.CONSTANT_Class).replace('/', '.'); } return names; @@ -141,11 +141,11 @@ /** - * @param exception_index_table the list of exception indexes + * @param exceptionIndexTable the list of exception indexes * Also redefines number_of_exceptions according to table length. */ - public void setExceptionIndexTable( final int[] exception_index_table ) { - this.exception_index_table = exception_index_table != null ? exception_index_table : new int[0]; + public void setExceptionIndexTable( final int[] exceptionIndexTable ) { + this.exceptionIndexTable = exceptionIndexTable != null ? exceptionIndexTable : new int[0]; } @@ -157,10 +157,10 @@ final StringBuilder buf = new StringBuilder(); String str; buf.append("Exceptions: "); - for (int i = 0; i < exception_index_table.length; i++) { - str = super.getConstantPool().getConstantString(exception_index_table[i], Const.CONSTANT_Class); + for (int i = 0; i < exceptionIndexTable.length; i++) { + str = super.getConstantPool().getConstantString(exceptionIndexTable[i], Const.CONSTANT_Class); buf.append(Utility.compactClassName(str, false)); - if (i < exception_index_table.length - 1) { + if (i < exceptionIndexTable.length - 1) { buf.append(", "); } } @@ -174,10 +174,10 @@ @Override public Attribute copy( final ConstantPool _constant_pool ) { final ExceptionTable c = (ExceptionTable) clone(); - if (exception_index_table != null) { - c.exception_index_table = new int[exception_index_table.length]; - System.arraycopy(exception_index_table, 0, c.exception_index_table, 0, - exception_index_table.length); + if (exceptionIndexTable != null) { + c.exceptionIndexTable = new int[exceptionIndexTable.length]; + System.arraycopy(exceptionIndexTable, 0, c.exceptionIndexTable, 0, + exceptionIndexTable.length); } c.setConstantPool(_constant_pool); return c;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java index 6f2078d..e7fbbe0 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java
@@ -36,10 +36,10 @@ */ public final class InnerClass implements Cloneable, Node { - private int inner_class_index; - private int outer_class_index; - private int inner_name_index; - private int inner_access_flags; + private int innerClassIndex; + private int outerClassIndex; + private int innerNameIndex; + private int innerAccessFlags; /** @@ -63,17 +63,17 @@ /** - * @param inner_class_index Class index in constant pool of inner class - * @param outer_class_index Class index in constant pool of outer class - * @param inner_name_index Name index in constant pool of inner class - * @param inner_access_flags Access flags of inner class + * @param innerClassIndex Class index in constant pool of inner class + * @param outerClassIndex Class index in constant pool of outer class + * @param innerNameIndex Name index in constant pool of inner class + * @param innerAccessFlags Access flags of inner class */ - public InnerClass(final int inner_class_index, final int outer_class_index, final int inner_name_index, - final int inner_access_flags) { - this.inner_class_index = inner_class_index; - this.outer_class_index = outer_class_index; - this.inner_name_index = inner_name_index; - this.inner_access_flags = inner_access_flags; + public InnerClass(final int innerClassIndex, final int outerClassIndex, final int innerNameIndex, + final int innerAccessFlags) { + this.innerClassIndex = innerClassIndex; + this.outerClassIndex = outerClassIndex; + this.innerNameIndex = innerNameIndex; + this.innerAccessFlags = innerAccessFlags; } @@ -97,10 +97,10 @@ * @throws IOException */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(inner_class_index); - file.writeShort(outer_class_index); - file.writeShort(inner_name_index); - file.writeShort(inner_access_flags); + file.writeShort(innerClassIndex); + file.writeShort(outerClassIndex); + file.writeShort(innerNameIndex); + file.writeShort(innerAccessFlags); } @@ -108,7 +108,7 @@ * @return access flags of inner class. */ public int getInnerAccessFlags() { - return inner_access_flags; + return innerAccessFlags; } @@ -116,7 +116,7 @@ * @return class index of inner class. */ public int getInnerClassIndex() { - return inner_class_index; + return innerClassIndex; } @@ -124,7 +124,7 @@ * @return name index of inner class. */ public int getInnerNameIndex() { - return inner_name_index; + return innerNameIndex; } @@ -132,39 +132,39 @@ * @return class index of outer class. */ public int getOuterClassIndex() { - return outer_class_index; + return outerClassIndex; } /** - * @param inner_access_flags access flags for this inner class + * @param innerAccessFlags access flags for this inner class */ - public void setInnerAccessFlags( final int inner_access_flags ) { - this.inner_access_flags = inner_access_flags; + public void setInnerAccessFlags( final int innerAccessFlags ) { + this.innerAccessFlags = innerAccessFlags; } /** - * @param inner_class_index index into the constant pool for this class + * @param innerClassIndex index into the constant pool for this class */ - public void setInnerClassIndex( final int inner_class_index ) { - this.inner_class_index = inner_class_index; + public void setInnerClassIndex( final int innerClassIndex ) { + this.innerClassIndex = innerClassIndex; } /** - * @param inner_name_index index into the constant pool for this class's name + * @param innerNameIndex index into the constant pool for this class's name */ - public void setInnerNameIndex( final int inner_name_index ) { // TODO unused - this.inner_name_index = inner_name_index; + public void setInnerNameIndex( final int innerNameIndex ) { // TODO unused + this.innerNameIndex = innerNameIndex; } /** - * @param outer_class_index index into the constant pool for the owning class + * @param outerClassIndex index into the constant pool for the owning class */ - public void setOuterClassIndex( final int outer_class_index ) { // TODO unused - this.outer_class_index = outer_class_index; + public void setOuterClassIndex( final int outerClassIndex ) { // TODO unused + this.outerClassIndex = outerClassIndex; } @@ -173,34 +173,34 @@ */ @Override public String toString() { - return "InnerClass(" + inner_class_index + ", " + outer_class_index + ", " - + inner_name_index + ", " + inner_access_flags + ")"; + return "InnerClass(" + innerClassIndex + ", " + outerClassIndex + ", " + + innerNameIndex + ", " + innerAccessFlags + ")"; } /** * @return Resolved string representation */ - public String toString( final ConstantPool constant_pool ) { + public String toString( final ConstantPool constantPool ) { String outer_class_name; String inner_name; - String inner_class_name = constant_pool.getConstantString(inner_class_index, + String inner_class_name = constantPool.getConstantString(innerClassIndex, Const.CONSTANT_Class); inner_class_name = Utility.compactClassName(inner_class_name, false); - if (outer_class_index != 0) { - outer_class_name = constant_pool.getConstantString(outer_class_index, + if (outerClassIndex != 0) { + outer_class_name = constantPool.getConstantString(outerClassIndex, Const.CONSTANT_Class); outer_class_name = " of class " + Utility.compactClassName(outer_class_name, false); } else { outer_class_name = ""; } - if (inner_name_index != 0) { - inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index, + if (innerNameIndex != 0) { + inner_name = ((ConstantUtf8) constantPool.getConstant(innerNameIndex, Const.CONSTANT_Utf8)).getBytes(); } else { inner_name = "(anonymous)"; } - String access = Utility.accessToString(inner_access_flags, true); + String access = Utility.accessToString(innerAccessFlags, true); access = access.isEmpty() ? "" : (access + " "); return " " + access + inner_name + "=class " + inner_class_name + outer_class_name; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java index 24cbb3f..567972f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java
@@ -37,7 +37,7 @@ */ public final class InnerClasses extends Attribute { - private InnerClass[] inner_classes; + private InnerClass[] innerClasses; /** @@ -52,13 +52,13 @@ /** * @param name_index Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes - * @param inner_classes array of inner classes attributes + * @param innerClasses array of inner classes attributes * @param constant_pool Array of constants */ - public InnerClasses(final int name_index, final int length, final InnerClass[] inner_classes, + public InnerClasses(final int name_index, final int length, final InnerClass[] innerClasses, final ConstantPool constant_pool) { super(Const.ATTR_INNER_CLASSES, name_index, length, constant_pool); - this.inner_classes = inner_classes != null ? inner_classes : new InnerClass[0]; + this.innerClasses = innerClasses != null ? innerClasses : new InnerClass[0]; } @@ -75,9 +75,9 @@ throws IOException { this(name_index, length, (InnerClass[]) null, constant_pool); final int number_of_classes = input.readUnsignedShort(); - inner_classes = new InnerClass[number_of_classes]; + innerClasses = new InnerClass[number_of_classes]; for (int i = 0; i < number_of_classes; i++) { - inner_classes[i] = new InnerClass(input); + innerClasses[i] = new InnerClass(input); } } @@ -104,8 +104,8 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(inner_classes.length); - for (final InnerClass inner_class : inner_classes) { + file.writeShort(innerClasses.length); + for (final InnerClass inner_class : innerClasses) { inner_class.dump(file); } } @@ -115,15 +115,15 @@ * @return array of inner class "records" */ public InnerClass[] getInnerClasses() { - return inner_classes; + return innerClasses; } /** - * @param inner_classes the array of inner classes + * @param innerClasses the array of inner classes */ - public void setInnerClasses( final InnerClass[] inner_classes ) { - this.inner_classes = inner_classes != null ? inner_classes : new InnerClass[0]; + public void setInnerClasses( final InnerClass[] innerClasses ) { + this.innerClasses = innerClasses != null ? innerClasses : new InnerClass[0]; } @@ -134,9 +134,9 @@ public String toString() { final StringBuilder buf = new StringBuilder(); buf.append("InnerClasses("); - buf.append(inner_classes.length); + buf.append(innerClasses.length); buf.append("):\n"); - for (final InnerClass inner_class : inner_classes) { + for (final InnerClass inner_class : innerClasses) { buf.append(inner_class.toString(super.getConstantPool())).append("\n"); } return buf.substring(0, buf.length()-1); // remove the last newline @@ -150,9 +150,9 @@ public Attribute copy( final ConstantPool _constant_pool ) { // TODO this could be recoded to use a lower level constructor after creating a copy of the inner classes final InnerClasses c = (InnerClasses) clone(); - c.inner_classes = new InnerClass[inner_classes.length]; - for (int i = 0; i < inner_classes.length; i++) { - c.inner_classes[i] = inner_classes[i].copy(); + c.innerClasses = new InnerClass[innerClasses.length]; + for (int i = 0; i < innerClasses.length; i++) { + c.innerClasses[i] = innerClasses[i].copy(); } c.setConstantPool(_constant_pool); return c;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java index f74aa6e..052059f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -41,28 +41,28 @@ /** * Represents a Java class, i.e., the data structures, constant pool, * fields, methods and commands contained in a Java .class file. - * See <a href="http://docs.oracle.com/javase/specs/">JVM specification</a> for details. + * See <a href="https://docs.oracle.com/javase/specs/">JVM specification</a> for details. * The intent of this class is to represent a parsed or otherwise existing * class file. Those interested in programatically generating classes * should see the <a href="../generic/ClassGen.html">ClassGen</a> class. * @see com.sun.org.apache.bcel.internal.generic.ClassGen - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable<JavaClass> { - private String file_name; - private String package_name; - private String source_file_name = "<Unknown>"; - private int class_name_index; - private int superclass_name_index; - private String class_name; - private String superclass_name; + private String fileName; + private String packageName; + private String sourceFileName = "<Unknown>"; + private int classNameIndex; + private int superclassNameIndex; + private String className; + private String superclassName; private int major; private int minor; // Compiler version - private ConstantPool constant_pool; // Constant pool + private ConstantPool constantPool; // Constant pool private int[] interfaces; // implemented interfaces - private String[] interface_names; + private String[] interfaceNames; private Field[] fields; // Fields, i.e., variables of class private Method[] methods; // methods defined in the class private Attribute[] attributes; // attributes defined in the class @@ -104,24 +104,24 @@ /** * Constructor gets all contents as arguments. * - * @param class_name_index Index into constant pool referencing a + * @param classNameIndex Index into constant pool referencing a * ConstantClass that represents this class. - * @param superclass_name_index Index into constant pool referencing a + * @param superclassNameIndex Index into constant pool referencing a * ConstantClass that represents this class's superclass. - * @param file_name File name + * @param fileName File name * @param major Major compiler version * @param minor Minor compiler version * @param access_flags Access rights defined by bit flags - * @param constant_pool Array of constants + * @param constantPool Array of constants * @param interfaces Implemented interfaces * @param fields Class fields * @param methods Class methods * @param attributes Class attributes * @param source Read from file or generated in memory? */ - public JavaClass(final int class_name_index, final int superclass_name_index, - final String file_name, final int major, final int minor, final int access_flags, - final ConstantPool constant_pool, int[] interfaces, Field[] fields, + public JavaClass(final int classNameIndex, final int superclassNameIndex, + final String fileName, final int major, final int minor, final int access_flags, + final ConstantPool constantPool, int[] interfaces, Field[] fields, Method[] methods, Attribute[] attributes, final byte source) { super(access_flags); if (interfaces == null) { @@ -136,12 +136,12 @@ if (methods == null) { methods = new Method[0]; } - this.class_name_index = class_name_index; - this.superclass_name_index = superclass_name_index; - this.file_name = file_name; + this.classNameIndex = classNameIndex; + this.superclassNameIndex = superclassNameIndex; + this.fileName = fileName; this.major = major; this.minor = minor; - this.constant_pool = constant_pool; + this.constantPool = constantPool; this.interfaces = interfaces; this.fields = fields; this.methods = methods; @@ -150,7 +150,7 @@ // Get source file name if available for (final Attribute attribute : attributes) { if (attribute instanceof SourceFile) { - source_file_name = ((SourceFile) attribute).getSourceFileName(); + sourceFileName = ((SourceFile) attribute).getSourceFileName(); break; } } @@ -158,26 +158,26 @@ * `ConstantClass' but we check that anyway via the * `ConstPool.getConstant' method. */ - class_name = constant_pool.getConstantString(class_name_index, Const.CONSTANT_Class); - class_name = Utility.compactClassName(class_name, false); - final int index = class_name.lastIndexOf('.'); + className = constantPool.getConstantString(classNameIndex, Const.CONSTANT_Class); + className = Utility.compactClassName(className, false); + final int index = className.lastIndexOf('.'); if (index < 0) { - package_name = ""; + packageName = ""; } else { - package_name = class_name.substring(0, index); + packageName = className.substring(0, index); } - if (superclass_name_index > 0) { + if (superclassNameIndex > 0) { // May be zero -> class is java.lang.Object - superclass_name = constant_pool.getConstantString(superclass_name_index, + superclassName = constantPool.getConstantString(superclassNameIndex, Const.CONSTANT_Class); - superclass_name = Utility.compactClassName(superclass_name, false); + superclassName = Utility.compactClassName(superclassName, false); } else { - superclass_name = "java.lang.Object"; + superclassName = "java.lang.Object"; } - interface_names = new String[interfaces.length]; + interfaceNames = new String[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { - final String str = constant_pool.getConstantString(interfaces[i], Const.CONSTANT_Class); - interface_names[i] = Utility.compactClassName(str, false); + final String str = constantPool.getConstantString(interfaces[i], Const.CONSTANT_Class); + interfaceNames[i] = Utility.compactClassName(str, false); } } @@ -185,24 +185,24 @@ /** * Constructor gets all contents as arguments. * - * @param class_name_index Class name - * @param superclass_name_index Superclass name - * @param file_name File name + * @param classNameIndex Class name + * @param superclassNameIndex Superclass name + * @param fileName File name * @param major Major compiler version * @param minor Minor compiler version * @param access_flags Access rights defined by bit flags - * @param constant_pool Array of constants + * @param constantPool Array of constants * @param interfaces Implemented interfaces * @param fields Class fields * @param methods Class methods * @param attributes Class attributes */ - public JavaClass(final int class_name_index, final int superclass_name_index, - final String file_name, final int major, final int minor, final int access_flags, - final ConstantPool constant_pool, final int[] interfaces, final Field[] fields, + public JavaClass(final int classNameIndex, final int superclassNameIndex, + final String fileName, final int major, final int minor, final int access_flags, + final ConstantPool constantPool, final int[] interfaces, final Field[] fields, final Method[] methods, final Attribute[] attributes) { - this(class_name_index, superclass_name_index, file_name, major, minor, access_flags, - constant_pool, interfaces, fields, methods, attributes, HEAP); + this(classNameIndex, superclassNameIndex, fileName, major, minor, access_flags, + constantPool, interfaces, fields, methods, attributes, HEAP); } @@ -251,7 +251,7 @@ /** - * Dump class to a file named file_name. + * Dump class to a file named fileName. * * @param _file_name Output file name * @throws IOException @@ -303,10 +303,10 @@ file.writeInt(Const.JVM_CLASSFILE_MAGIC); file.writeShort(minor); file.writeShort(major); - constant_pool.dump(file); + constantPool.dump(file); file.writeShort(super.getAccessFlags()); - file.writeShort(class_name_index); - file.writeShort(superclass_name_index); + file.writeShort(classNameIndex); + file.writeShort(superclassNameIndex); file.writeShort(interfaces.length); for (final int interface1 : interfaces) { file.writeShort(interface1); @@ -354,7 +354,7 @@ * @return Class name. */ public String getClassName() { - return class_name; + return className; } @@ -362,7 +362,7 @@ * @return Package name. */ public String getPackageName() { - return package_name; + return packageName; } @@ -370,7 +370,7 @@ * @return Class name index. */ public int getClassNameIndex() { - return class_name_index; + return classNameIndex; } @@ -378,7 +378,7 @@ * @return Constant pool. */ public ConstantPool getConstantPool() { - return constant_pool; + return constantPool; } @@ -396,7 +396,7 @@ * @return File name of class, aka SourceFile attribute value */ public String getFileName() { - return file_name; + return fileName; } @@ -404,7 +404,7 @@ * @return Names of implemented interfaces. */ public String[] getInterfaceNames() { - return interface_names; + return interfaceNames; } @@ -459,7 +459,7 @@ * @return sbsolute path to file where this class was read from */ public String getSourceFileName() { - return source_file_name; + return sourceFileName; } @@ -471,7 +471,7 @@ * @return Superclass name. */ public String getSuperclassName() { - return superclass_name; + return superclassName; } @@ -479,7 +479,7 @@ * @return Class name index. */ public int getSuperclassNameIndex() { - return superclass_name_index; + return superclassNameIndex; } /** @@ -491,26 +491,26 @@ /** - * @param class_name . + * @param className . */ - public void setClassName( final String class_name ) { - this.class_name = class_name; + public void setClassName( final String className ) { + this.className = className; } /** - * @param class_name_index . + * @param classNameIndex . */ - public void setClassNameIndex( final int class_name_index ) { - this.class_name_index = class_name_index; + public void setClassNameIndex( final int classNameIndex ) { + this.classNameIndex = classNameIndex; } /** - * @param constant_pool . + * @param constantPool . */ - public void setConstantPool( final ConstantPool constant_pool ) { - this.constant_pool = constant_pool; + public void setConstantPool( final ConstantPool constantPool ) { + this.constantPool = constantPool; } @@ -525,16 +525,16 @@ /** * Set File name of class, aka SourceFile attribute value */ - public void setFileName( final String file_name ) { - this.file_name = file_name; + public void setFileName( final String fileName ) { + this.fileName = fileName; } /** - * @param interface_names . + * @param interfaceNames . */ - public void setInterfaceNames( final String[] interface_names ) { - this.interface_names = interface_names; + public void setInterfaceNames( final String[] interfaceNames ) { + this.interfaceNames = interfaceNames; } @@ -573,24 +573,24 @@ /** * Set absolute path to file this class was read from. */ - public void setSourceFileName( final String source_file_name ) { - this.source_file_name = source_file_name; + public void setSourceFileName( final String sourceFileName ) { + this.sourceFileName = sourceFileName; } /** - * @param superclass_name . + * @param superclassName . */ - public void setSuperclassName( final String superclass_name ) { - this.superclass_name = superclass_name; + public void setSuperclassName( final String superclassName ) { + this.superclassName = superclassName; } /** - * @param superclass_name_index . + * @param superclassNameIndex . */ - public void setSuperclassNameIndex( final int superclass_name_index ) { - this.superclass_name_index = superclass_name_index; + public void setSuperclassNameIndex( final int superclassNameIndex ) { + this.superclassNameIndex = superclassNameIndex; } @@ -603,24 +603,24 @@ access = access.isEmpty() ? "" : (access + " "); final StringBuilder buf = new StringBuilder(128); buf.append(access).append(Utility.classOrInterface(super.getAccessFlags())).append(" ").append( - class_name).append(" extends ").append( - Utility.compactClassName(superclass_name, false)).append('\n'); + className).append(" extends ").append( + Utility.compactClassName(superclassName, false)).append('\n'); final int size = interfaces.length; if (size > 0) { buf.append("implements\t\t"); for (int i = 0; i < size; i++) { - buf.append(interface_names[i]); + buf.append(interfaceNames[i]); if (i < size - 1) { buf.append(", "); } } buf.append('\n'); } - buf.append("file name\t\t").append(file_name).append('\n'); - buf.append("compiled from\t\t").append(source_file_name).append('\n'); + buf.append("file name\t\t").append(fileName).append('\n'); + buf.append("compiled from\t\t").append(sourceFileName).append('\n'); buf.append("compiler version\t").append(major).append(".").append(minor).append('\n'); buf.append("access flags\t\t").append(super.getAccessFlags()).append('\n'); - buf.append("constant pool\t\t").append(constant_pool.getLength()).append(" entries\n"); + buf.append("constant pool\t\t").append(constantPool.getLength()).append(" entries\n"); buf.append("ACC_SUPER flag\t\t").append(isSuper()).append("\n"); if (attributes.length > 0) { buf.append("\nAttribute(s):\n"); @@ -668,20 +668,20 @@ JavaClass c = null; try { c = (JavaClass) clone(); - c.constant_pool = constant_pool.copy(); + c.constantPool = constantPool.copy(); c.interfaces = interfaces.clone(); - c.interface_names = interface_names.clone(); + c.interfaceNames = interfaceNames.clone(); c.fields = new Field[fields.length]; for (int i = 0; i < fields.length; i++) { - c.fields[i] = fields[i].copy(c.constant_pool); + c.fields[i] = fields[i].copy(c.constantPool); } c.methods = new Method[methods.length]; for (int i = 0; i < methods.length; i++) { - c.methods[i] = methods[i].copy(c.constant_pool); + c.methods[i] = methods[i].copy(c.constantPool); } c.attributes = new Attribute[attributes.length]; for (int i = 0; i < attributes.length; i++) { - c.attributes[i] = attributes[i].copy(c.constant_pool); + c.attributes[i] = attributes[i].copy(c.constantPool); } } catch (final CloneNotSupportedException e) { // TODO should this throw? @@ -724,7 +724,7 @@ final InnerClass[] innerClasses = ((InnerClasses) attribute).getInnerClasses(); for (final InnerClass innerClasse : innerClasses) { boolean innerClassAttributeRefersToMe = false; - String inner_class_name = constant_pool.getConstantString(innerClasse.getInnerClassIndex(), + String inner_class_name = constantPool.getConstantString(innerClasse.getInnerClassIndex(), Const.CONSTANT_Class); inner_class_name = Utility.compactClassName(inner_class_name, false); if (inner_class_name.equals(getClassName())) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java index 266e04b..f90b88f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java
@@ -35,10 +35,10 @@ public final class LineNumber implements Cloneable, Node { /** Program Counter (PC) corresponds to line */ - private short start_pc; + private short startPc; /** number in source file */ - private short line_number; + private short lineNumber; /** * Initialize from another object. @@ -62,12 +62,12 @@ /** - * @param start_pc Program Counter (PC) corresponds to - * @param line_number line number in source file + * @param startPc Program Counter (PC) corresponds to + * @param lineNumber line number in source file */ - public LineNumber(final int start_pc, final int line_number) { - this.start_pc = (short) start_pc; - this.line_number = (short)line_number; + public LineNumber(final int startPc, final int lineNumber) { + this.startPc = (short) startPc; + this.lineNumber = (short)lineNumber; } @@ -91,8 +91,8 @@ * @throws IOException if an I/O Exception occurs in writeShort */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(start_pc); - file.writeShort(line_number); + file.writeShort(startPc); + file.writeShort(lineNumber); } @@ -100,7 +100,7 @@ * @return Corresponding source line */ public int getLineNumber() { - return 0xffff & line_number; + return 0xffff & lineNumber; } @@ -108,23 +108,23 @@ * @return PC in code */ public int getStartPC() { - return 0xffff & start_pc; + return 0xffff & startPc; } /** - * @param line_number the source line number + * @param lineNumber the source line number */ - public void setLineNumber( final int line_number ) { - this.line_number = (short) line_number; + public void setLineNumber( final int lineNumber ) { + this.lineNumber = (short) lineNumber; } /** - * @param start_pc the pc for this line number + * @param startPc the pc for this line number */ - public void setStartPC( final int start_pc ) { - this.start_pc = (short) start_pc; + public void setStartPC( final int startPc ) { + this.startPc = (short) startPc; } @@ -133,7 +133,7 @@ */ @Override public String toString() { - return "LineNumber(" + start_pc + ", " + line_number + ")"; + return "LineNumber(" + startPc + ", " + lineNumber + ")"; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java index 78a4fd9..7bad272 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,12 +32,12 @@ * * @see Code * @see LineNumber - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public final class LineNumberTable extends Attribute { private static final int MAX_LINE_LENGTH = 72; - private LineNumber[] line_number_table; // Table of line/numbers pairs + private LineNumber[] lineNumberTable; // Table of line/numbers pairs /* @@ -52,13 +52,13 @@ /* * @param name_index Index of name * @param length Content length in bytes - * @param line_number_table Table of line/numbers pairs + * @param lineNumberTable Table of line/numbers pairs * @param constant_pool Array of constants */ public LineNumberTable(final int name_index, final int length, final LineNumber[] line_number_table, final ConstantPool constant_pool) { super(Const.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); - this.line_number_table = line_number_table; + this.lineNumberTable = line_number_table; } /** @@ -73,9 +73,9 @@ throws IOException { this(name_index, length, (LineNumber[]) null, constant_pool); final int line_number_table_length = input.readUnsignedShort(); - line_number_table = new LineNumber[line_number_table_length]; + lineNumberTable = new LineNumber[line_number_table_length]; for (int i = 0; i < line_number_table_length; i++) { - line_number_table[i] = new LineNumber(input); + lineNumberTable[i] = new LineNumber(input); } } @@ -100,8 +100,8 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(line_number_table.length); - for (final LineNumber lineNumber : line_number_table) { + file.writeShort(lineNumberTable.length); + for (final LineNumber lineNumber : lineNumberTable) { lineNumber.dump(file); } } @@ -110,14 +110,14 @@ * @return Array of (pc offset, line number) pairs. */ public LineNumber[] getLineNumberTable() { - return line_number_table; + return lineNumberTable; } /** - * @param line_number_table the line number entries for this table + * @param lineNumberTable the line number entries for this table */ - public void setLineNumberTable( final LineNumber[] line_number_table ) { - this.line_number_table = line_number_table; + public void setLineNumberTable( final LineNumber[] lineNumberTable ) { + this.lineNumberTable = lineNumberTable; } /** @@ -128,12 +128,12 @@ final StringBuilder buf = new StringBuilder(); final StringBuilder line = new StringBuilder(); - for (int i = 0; i < line_number_table.length; i++) { - line.append(line_number_table[i].toString()); - if (i < line_number_table.length - 1) { + for (int i = 0; i < lineNumberTable.length; i++) { + line.append(lineNumberTable[i].toString()); + if (i < lineNumberTable.length - 1) { line.append(", "); } - if ((line.length() > MAX_LINE_LENGTH) && (i < line_number_table.length - 1)) { + if ((line.length() > MAX_LINE_LENGTH) && (i < lineNumberTable.length - 1)) { line.append(SecuritySupport.NEWLINE); buf.append(line); line.setLength(0); @@ -151,7 +151,7 @@ */ public int getSourceLine( final int pos ) { int l = 0; - int r = line_number_table.length - 1; + int r = lineNumberTable.length - 1; if (r < 0) { return -1; } @@ -161,9 +161,9 @@ */ do { final int i = (l + r) >>> 1; - final int j = line_number_table[i].getStartPC(); + final int j = lineNumberTable[i].getStartPC(); if (j == pos) { - return line_number_table[i].getLineNumber(); + return lineNumberTable[i].getLineNumber(); } else if (pos < j) { r = i - 1; } else { @@ -184,7 +184,7 @@ if (min_index < 0) { return -1; } - return line_number_table[min_index].getLineNumber(); + return lineNumberTable[min_index].getLineNumber(); } /** @@ -193,17 +193,18 @@ @Override public Attribute copy( final ConstantPool _constant_pool ) { // TODO could use the lower level constructor and thereby allow - // line_number_table to be made final + // lineNumberTable to be made final final LineNumberTable c = (LineNumberTable) clone(); - c.line_number_table = new LineNumber[line_number_table.length]; - for (int i = 0; i < line_number_table.length; i++) { - c.line_number_table[i] = line_number_table[i].copy(); + c.lineNumberTable = new LineNumber[lineNumberTable.length]; + for (int i = 0; i < lineNumberTable.length; i++) { + c.lineNumberTable[i] = lineNumberTable[i].copy(); } c.setConstantPool(_constant_pool); return c; } + public int getTableLength() { - return line_number_table == null ? 0 : line_number_table.length; + return lineNumberTable == null ? 0 : lineNumberTable.length; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java index 7f1c4b5..f0605cf 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,27 +32,27 @@ * to represent an element of the LocalVariableTable as well as an element * of the LocalVariableTypeTable. The nomenclature used here may be a bit confusing; * while the two items have the same layout in a class file, a LocalVariableTable - * attribute contains a descriptor_index, not a signature_index. The - * LocalVariableTypeTable attribute does have a signature_index. + * attribute contains a descriptor_index, not a signatureIndex. The + * LocalVariableTypeTable attribute does have a signatureIndex. * @see com.sun.org.apache.bcel.internal.classfile.Utility for more details on the difference. * * @see LocalVariableTable * @see LocalVariableTypeTable - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public final class LocalVariable implements Cloneable, Node { - private int start_pc; // Range in which the variable is valid + private int startPc; // Range in which the variable is valid private int length; - private int name_index; // Index in constant pool of variable name + private int nameIndex; // Index in constant pool of variable name // Technically, a decscriptor_index for a local variable table entry - // and a signature_index for a local variable type table entry. - private int signature_index; // Index of variable signature + // and a signatureIndex for a local variable type table entry. + private int signatureIndex; // Index of variable signature private int index; /* Variable is index'th local variable on * this method's frame. */ - private ConstantPool constant_pool; - private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries + private ConstantPool constantPool; + private int origIndex; // never changes; used to match up with LocalVariableTypeTable entries /** @@ -64,7 +64,7 @@ public LocalVariable(final LocalVariable localVariable) { this(localVariable.getStartPC(), localVariable.getLength(), localVariable.getNameIndex(), localVariable.getSignatureIndex(), localVariable.getIndex(), localVariable.getConstantPool()); - this.orig_index = localVariable.getOrigIndex(); + this.origIndex = localVariable.getOrigIndex(); } /** @@ -79,43 +79,43 @@ /** - * @param start_pc Range in which the variable + * @param startPc Range in which the variable * @param length ... is valid - * @param name_index Index in constant pool of variable name - * @param signature_index Index of variable's signature + * @param nameIndex Index in constant pool of variable name + * @param signatureIndex Index of variable's signature * @param index Variable is `index'th local variable on the method's frame - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index, - final ConstantPool constant_pool) { - this.start_pc = start_pc; + public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index, + final ConstantPool constantPool) { + this.startPc = startPc; this.length = length; - this.name_index = name_index; - this.signature_index = signature_index; + this.nameIndex = nameIndex; + this.signatureIndex = signatureIndex; this.index = index; - this.constant_pool = constant_pool; - this.orig_index = index; + this.constantPool = constantPool; + this.origIndex = index; } /** - * @param start_pc Range in which the variable + * @param startPc Range in which the variable * @param length ... is valid - * @param name_index Index in constant pool of variable name - * @param signature_index Index of variable's signature + * @param nameIndex Index in constant pool of variable name + * @param signatureIndex Index of variable's signature * @param index Variable is `index'th local variable on the method's frame - * @param constant_pool Array of constants - * @param orig_index Variable is `index'th local variable on the method's frame prior to any changes + * @param constantPool Array of constants + * @param origIndex Variable is `index'th local variable on the method's frame prior to any changes */ - public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index, - final ConstantPool constant_pool, final int orig_index) { - this.start_pc = start_pc; + public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index, + final ConstantPool constantPool, final int origIndex) { + this.startPc = startPc; this.length = length; - this.name_index = name_index; - this.signature_index = signature_index; + this.nameIndex = nameIndex; + this.signatureIndex = signatureIndex; this.index = index; - this.constant_pool = constant_pool; - this.orig_index = orig_index; + this.constantPool = constantPool; + this.origIndex = origIndex; } @@ -140,10 +140,10 @@ * @see java.io.FilterOutputStream#out */ public void dump(final DataOutputStream dataOutputStream) throws IOException { - dataOutputStream.writeShort(start_pc); + dataOutputStream.writeShort(startPc); dataOutputStream.writeShort(length); - dataOutputStream.writeShort(name_index); - dataOutputStream.writeShort(signature_index); + dataOutputStream.writeShort(nameIndex); + dataOutputStream.writeShort(signatureIndex); dataOutputStream.writeShort(index); } @@ -151,7 +151,7 @@ * @return Constant pool used by this object. */ public ConstantPool getConstantPool() { - return constant_pool; + return constantPool; } @@ -168,7 +168,7 @@ */ public String getName() { ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); + c = (ConstantUtf8) constantPool.getConstant(nameIndex, Const.CONSTANT_Utf8); return c.getBytes(); } @@ -177,7 +177,7 @@ * @return Index in constant pool of variable name. */ public int getNameIndex() { - return name_index; + return nameIndex; } @@ -186,7 +186,7 @@ */ public String getSignature() { ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8); + c = (ConstantUtf8) constantPool.getConstant(signatureIndex, Const.CONSTANT_Utf8); return c.getBytes(); } @@ -195,7 +195,7 @@ * @return Index in constant pool of variable signature. */ public int getSignatureIndex() { - return signature_index; + return signatureIndex; } @@ -211,7 +211,7 @@ * @return index of register where variable was originally stored */ public int getOrigIndex() { - return orig_index; + return origIndex; } @@ -219,7 +219,7 @@ * @return Start of range where the variable is valid */ public int getStartPC() { - return start_pc; + return startPc; } @@ -230,16 +230,16 @@ final String name = getName(); final String signature = Utility.signatureToString(getSignature(), false); final String label = "LocalVariable" + (typeTable ? "Types" : "" ); - return label + "(start_pc = " + start_pc + ", length = " + length + ", index = " + return label + "(startPc = " + startPc + ", length = " + length + ", index = " + index + ":" + signature + " " + name + ")"; } /** - * @param constant_pool Constant pool to be used for this object. + * @param constantPool Constant pool to be used for this object. */ - public void setConstantPool( final ConstantPool constant_pool ) { - this.constant_pool = constant_pool; + public void setConstantPool( final ConstantPool constantPool ) { + this.constantPool = constantPool; } @@ -252,18 +252,18 @@ /** - * @param name_index the index into the constant pool for the name of this variable + * @param nameIndex the index into the constant pool for the name of this variable */ - public void setNameIndex( final int name_index ) { // TODO unused - this.name_index = name_index; + public void setNameIndex( final int nameIndex ) { // TODO unused + this.nameIndex = nameIndex; } /** - * @param signature_index the index into the constant pool for the signature of this variable + * @param signatureIndex the index into the constant pool for the signature of this variable */ - public void setSignatureIndex( final int signature_index ) { // TODO unused - this.signature_index = signature_index; + public void setSignatureIndex( final int signatureIndex ) { // TODO unused + this.signatureIndex = signatureIndex; } @@ -276,10 +276,10 @@ /** - * @param start_pc Specify range where the local variable is valid. + * @param startPc Specify range where the local variable is valid. */ - public void setStartPC( final int start_pc ) { // TODO unused - this.start_pc = start_pc; + public void setStartPC( final int startPc ) { // TODO unused + this.startPc = startPc; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java index 2735478..12bf71d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java
@@ -36,7 +36,7 @@ */ public class LocalVariableTable extends Attribute { - private LocalVariable[] local_variable_table; // variables + private LocalVariable[] localVariableTable; // variables /** @@ -49,15 +49,15 @@ /** - * @param name_index Index in constant pool to `LocalVariableTable' + * @param nameIndex Index in constant pool to `LocalVariableTable' * @param length Content length in bytes - * @param local_variable_table Table of local variables - * @param constant_pool Array of constants + * @param localVariableTable Table of local variables + * @param constantPool Array of constants */ - public LocalVariableTable(final int name_index, final int length, final LocalVariable[] local_variable_table, - final ConstantPool constant_pool) { - super(Const.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); - this.local_variable_table = local_variable_table; + public LocalVariableTable(final int nameIndex, final int length, final LocalVariable[] localVariableTable, + final ConstantPool constantPool) { + super(Const.ATTR_LOCAL_VARIABLE_TABLE, nameIndex, length, constantPool); + this.localVariableTable = localVariableTable; } @@ -73,9 +73,9 @@ throws IOException { this(name_index, length, (LocalVariable[]) null, constant_pool); final int local_variable_table_length = input.readUnsignedShort(); - local_variable_table = new LocalVariable[local_variable_table_length]; + localVariableTable = new LocalVariable[local_variable_table_length]; for (int i = 0; i < local_variable_table_length; i++) { - local_variable_table[i] = new LocalVariable(input, constant_pool); + localVariableTable[i] = new LocalVariable(input, constant_pool); } } @@ -102,8 +102,8 @@ @Override public final void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(local_variable_table.length); - for (final LocalVariable variable : local_variable_table) { + file.writeShort(localVariableTable.length); + for (final LocalVariable variable : localVariableTable) { variable.dump(file); } } @@ -113,7 +113,7 @@ * @return Array of local variables of method. */ public final LocalVariable[] getLocalVariableTable() { - return local_variable_table; + return localVariableTable; } @@ -128,7 +128,7 @@ */ @java.lang.Deprecated public final LocalVariable getLocalVariable( final int index ) { - for (final LocalVariable variable : local_variable_table) { + for (final LocalVariable variable : localVariableTable) { if (variable.getIndex() == index) { return variable; } @@ -145,7 +145,7 @@ * @return the LocalVariable that matches or null if not found */ public final LocalVariable getLocalVariable( final int index, final int pc ) { - for (final LocalVariable variable : local_variable_table) { + for (final LocalVariable variable : localVariableTable) { if (variable.getIndex() == index) { final int start_pc = variable.getStartPC(); final int end_pc = start_pc + variable.getLength(); @@ -159,7 +159,7 @@ public final void setLocalVariableTable( final LocalVariable[] local_variable_table ) { - this.local_variable_table = local_variable_table; + this.localVariableTable = local_variable_table; } @@ -169,9 +169,9 @@ @Override public final String toString() { final StringBuilder buf = new StringBuilder(); - for (int i = 0; i < local_variable_table.length; i++) { - buf.append(local_variable_table[i]); - if (i < local_variable_table.length - 1) { + for (int i = 0; i < localVariableTable.length; i++) { + buf.append(localVariableTable[i]); + if (i < localVariableTable.length - 1) { buf.append('\n'); } } @@ -185,9 +185,9 @@ @Override public Attribute copy( final ConstantPool _constant_pool ) { final LocalVariableTable c = (LocalVariableTable) clone(); - c.local_variable_table = new LocalVariable[local_variable_table.length]; - for (int i = 0; i < local_variable_table.length; i++) { - c.local_variable_table[i] = local_variable_table[i].copy(); + c.localVariableTable = new LocalVariable[localVariableTable.length]; + for (int i = 0; i < localVariableTable.length; i++) { + c.localVariableTable[i] = localVariableTable[i].copy(); } c.setConstantPool(_constant_pool); return c; @@ -195,6 +195,6 @@ public final int getTableLength() { - return local_variable_table == null ? 0 : local_variable_table.length; + return localVariableTable == null ? 0 : localVariableTable.length; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java index b0c781e..bdd5d7a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java
@@ -50,7 +50,7 @@ // u2 name_index; // u2 signature_index; // u2 index; -// } local_variable_type_table[local_variable_type_table_length]; +// } localVariableTypeTable[local_variable_type_table_length]; // } // J5TODO: Needs some testing ! @@ -59,7 +59,7 @@ */ public class LocalVariableTypeTable extends Attribute { - private LocalVariable[] local_variable_type_table; // variables + private LocalVariable[] localVariableTypeTable; // variables public LocalVariableTypeTable(final LocalVariableTypeTable c) { this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool()); @@ -67,17 +67,17 @@ public LocalVariableTypeTable(final int name_index, final int length, final LocalVariable[] local_variable_table, final ConstantPool constant_pool) { super(Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool); - this.local_variable_type_table = local_variable_table; + this.localVariableTypeTable = local_variable_table; } LocalVariableTypeTable(final int nameIdx, final int len, final DataInput input, final ConstantPool cpool) throws IOException { this(nameIdx, len, (LocalVariable[]) null, cpool); final int local_variable_type_table_length = input.readUnsignedShort(); - local_variable_type_table = new LocalVariable[local_variable_type_table_length]; + localVariableTypeTable = new LocalVariable[local_variable_type_table_length]; for (int i = 0; i < local_variable_type_table_length; i++) { - local_variable_type_table[i] = new LocalVariable(input, cpool); + localVariableTypeTable[i] = new LocalVariable(input, cpool); } } @@ -89,18 +89,18 @@ @Override public final void dump(final DataOutputStream file) throws IOException { super.dump(file); - file.writeShort(local_variable_type_table.length); - for (final LocalVariable variable : local_variable_type_table) { + file.writeShort(localVariableTypeTable.length); + for (final LocalVariable variable : localVariableTypeTable) { variable.dump(file); } } public final LocalVariable[] getLocalVariableTypeTable() { - return local_variable_type_table; + return localVariableTypeTable; } public final LocalVariable getLocalVariable(final int index) { - for (final LocalVariable variable : local_variable_type_table) { + for (final LocalVariable variable : localVariableTypeTable) { if (variable.getIndex() == index) { return variable; } @@ -110,7 +110,7 @@ } public final void setLocalVariableTable(final LocalVariable[] local_variable_table) { - this.local_variable_type_table = local_variable_table; + this.localVariableTypeTable = local_variable_table; } /** @@ -120,10 +120,10 @@ public final String toString() { final StringBuilder buf = new StringBuilder(); - for (int i = 0; i < local_variable_type_table.length; i++) { - buf.append(local_variable_type_table[i].toStringShared(true)); + for (int i = 0; i < localVariableTypeTable.length; i++) { + buf.append(localVariableTypeTable[i].toStringShared(true)); - if (i < local_variable_type_table.length - 1) { + if (i < localVariableTypeTable.length - 1) { buf.append('\n'); } } @@ -138,9 +138,9 @@ public Attribute copy(final ConstantPool constant_pool) { final LocalVariableTypeTable c = (LocalVariableTypeTable) clone(); - c.local_variable_type_table = new LocalVariable[local_variable_type_table.length]; - for (int i = 0; i < local_variable_type_table.length; i++) { - c.local_variable_type_table[i] = local_variable_type_table[i].copy(); + c.localVariableTypeTable = new LocalVariable[localVariableTypeTable.length]; + for (int i = 0; i < localVariableTypeTable.length; i++) { + c.localVariableTypeTable[i] = localVariableTypeTable[i].copy(); } c.setConstantPool(constant_pool); @@ -148,6 +148,6 @@ } public final int getTableLength() { - return local_variable_type_table == null ? 0 : local_variable_type_table.length; + return localVariableTypeTable == null ? 0 : localVariableTypeTable.length; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java index 1d0bc16..8615533 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java
@@ -30,17 +30,17 @@ /** * Entry of the parameters table. * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24"> * The class File Format : The MethodParameters Attribute</a> * @since 6.0 */ public class MethodParameter implements Cloneable { /** Index of the CONSTANT_Utf8_info structure in the constant_pool table representing the name of the parameter */ - private int name_index; + private int nameIndex; /** The access flags */ - private int access_flags; + private int accessFlags; public MethodParameter() { } @@ -53,46 +53,46 @@ * @throws ClassFormatException */ MethodParameter(final DataInput input) throws IOException { - name_index = input.readUnsignedShort(); - access_flags = input.readUnsignedShort(); + nameIndex = input.readUnsignedShort(); + accessFlags = input.readUnsignedShort(); } public int getNameIndex() { - return name_index; + return nameIndex; } public void setNameIndex(final int name_index) { - this.name_index = name_index; + this.nameIndex = name_index; } /** * Returns the name of the parameter. */ public String getParameterName(final ConstantPool constant_pool) { - if (name_index == 0) { + if (nameIndex == 0) { return null; } - return ((ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8)).getBytes(); + return ((ConstantUtf8) constant_pool.getConstant(nameIndex, Const.CONSTANT_Utf8)).getBytes(); } public int getAccessFlags() { - return access_flags; + return accessFlags; } public void setAccessFlags(final int access_flags) { - this.access_flags = access_flags; + this.accessFlags = access_flags; } public boolean isFinal() { - return (access_flags & Const.ACC_FINAL) != 0; + return (accessFlags & Const.ACC_FINAL) != 0; } public boolean isSynthetic() { - return (access_flags & Const.ACC_SYNTHETIC) != 0; + return (accessFlags & Const.ACC_SYNTHETIC) != 0; } public boolean isMandated() { - return (access_flags & Const.ACC_MANDATED) != 0; + return (accessFlags & Const.ACC_MANDATED) != 0; } public void accept(final Visitor v) { @@ -106,8 +106,8 @@ * @throws IOException */ public final void dump(final DataOutputStream file) throws IOException { - file.writeShort(name_index); - file.writeShort(access_flags); + file.writeShort(nameIndex); + file.writeShort(accessFlags); } /**
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java index 0bab2b0..0ee75fb 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java
@@ -30,7 +30,7 @@ /** * This class represents a MethodParameters attribute. * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24"> * The class File Format : The MethodParameters Attribute</a> * @since 6.0 */
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java index ff4dfe3..ffb87b1 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java
@@ -28,7 +28,8 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from <em>Attribute</em> and represents the list of modules required, exported, opened or provided by a module. + * This class is derived from <em>Attribute</em> and represents the list of + * modules required, exported, opened or provided by a module. * There may be at most one Module attribute in a ClassFile structure. * * @see Attribute @@ -36,16 +37,16 @@ */ public final class Module extends Attribute { - private final int module_name_index; - private final int module_flags; - private final int module_version_index; + private final int moduleNameIndex; + private final int moduleFlags; + private final int moduleVersionIndex; - private ModuleRequires[] requires_table; - private ModuleExports[] exports_table; - private ModuleOpens[] opens_table; - private final int uses_count; - private final int[] uses_index; - private ModuleProvides[] provides_table; + private ModuleRequires[] requiresTable; + private ModuleExports[] exportsTable; + private ModuleOpens[] opensTable; + private final int usesCount; + private final int[] usesIndex; + private ModuleProvides[] providesTable; /** * Construct object from input stream. @@ -58,38 +59,38 @@ Module(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { super(Const.ATTR_MODULE, name_index, length, constant_pool); - module_name_index = input.readUnsignedShort(); - module_flags = input.readUnsignedShort(); - module_version_index = input.readUnsignedShort(); + moduleNameIndex = input.readUnsignedShort(); + moduleFlags = input.readUnsignedShort(); + moduleVersionIndex = input.readUnsignedShort(); final int requires_count = input.readUnsignedShort(); - requires_table = new ModuleRequires[requires_count]; + requiresTable = new ModuleRequires[requires_count]; for (int i = 0; i < requires_count; i++) { - requires_table[i] = new ModuleRequires(input); + requiresTable[i] = new ModuleRequires(input); } final int exports_count = input.readUnsignedShort(); - exports_table = new ModuleExports[exports_count]; + exportsTable = new ModuleExports[exports_count]; for (int i = 0; i < exports_count; i++) { - exports_table[i] = new ModuleExports(input); + exportsTable[i] = new ModuleExports(input); } final int opens_count = input.readUnsignedShort(); - opens_table = new ModuleOpens[opens_count]; + opensTable = new ModuleOpens[opens_count]; for (int i = 0; i < opens_count; i++) { - opens_table[i] = new ModuleOpens(input); + opensTable[i] = new ModuleOpens(input); } - uses_count = input.readUnsignedShort(); - uses_index = new int[uses_count]; - for (int i = 0; i < uses_count; i++) { - uses_index[i] = input.readUnsignedShort(); + usesCount = input.readUnsignedShort(); + usesIndex = new int[usesCount]; + for (int i = 0; i < usesCount; i++) { + usesIndex[i] = input.readUnsignedShort(); } final int provides_count = input.readUnsignedShort(); - provides_table = new ModuleProvides[provides_count]; + providesTable = new ModuleProvides[provides_count]; for (int i = 0; i < provides_count; i++) { - provides_table[i] = new ModuleProvides(input); + providesTable[i] = new ModuleProvides(input); } } @@ -113,7 +114,7 @@ * @see ModuleRequires */ public ModuleRequires[] getRequiresTable() { - return requires_table; + return requiresTable; } @@ -122,7 +123,7 @@ * @see ModuleExports */ public ModuleExports[] getExportsTable() { - return exports_table; + return exportsTable; } @@ -131,7 +132,7 @@ * @see ModuleOpens */ public ModuleOpens[] getOpensTable() { - return opens_table; + return opensTable; } @@ -140,7 +141,7 @@ * @see ModuleProvides */ public ModuleProvides[] getProvidesTable() { - return provides_table; + return providesTable; } @@ -154,32 +155,32 @@ public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(module_name_index); - file.writeShort(module_flags); - file.writeShort(module_version_index); + file.writeShort(moduleNameIndex); + file.writeShort(moduleFlags); + file.writeShort(moduleVersionIndex); - file.writeShort(requires_table.length); - for (final ModuleRequires entry : requires_table) { + file.writeShort(requiresTable.length); + for (final ModuleRequires entry : requiresTable) { entry.dump(file); } - file.writeShort(exports_table.length); - for (final ModuleExports entry : exports_table) { + file.writeShort(exportsTable.length); + for (final ModuleExports entry : exportsTable) { entry.dump(file); } - file.writeShort(opens_table.length); - for (final ModuleOpens entry : opens_table) { + file.writeShort(opensTable.length); + for (final ModuleOpens entry : opensTable) { entry.dump(file); } - file.writeShort(uses_index.length); - for (final int entry : uses_index) { + file.writeShort(usesIndex.length); + for (final int entry : usesIndex) { file.writeShort(entry); } - file.writeShort(provides_table.length); - for (final ModuleProvides entry : provides_table) { + file.writeShort(providesTable.length); + for (final ModuleProvides entry : providesTable) { entry.dump(file); } } @@ -193,34 +194,34 @@ final ConstantPool cp = super.getConstantPool(); final StringBuilder buf = new StringBuilder(); buf.append("Module:\n"); - buf.append(" name: ") .append(cp.getConstantString(module_name_index, Const.CONSTANT_Module).replace('/', '.')).append("\n"); - buf.append(" flags: ") .append(String.format("%04x", module_flags)).append("\n"); - final String version = module_version_index == 0 ? "0" : cp.getConstantString(module_version_index, Const.CONSTANT_Utf8); + buf.append(" name: ") .append(cp.getConstantString(moduleNameIndex, Const.CONSTANT_Module).replace('/', '.')).append("\n"); + buf.append(" flags: ") .append(String.format("%04x", moduleFlags)).append("\n"); + final String version = moduleVersionIndex == 0 ? "0" : cp.getConstantString(moduleVersionIndex, Const.CONSTANT_Utf8); buf.append(" version: ") .append(version).append("\n"); - buf.append(" requires(").append(requires_table.length).append("):\n"); - for (final ModuleRequires module : requires_table) { + buf.append(" requires(").append(requiresTable.length).append("):\n"); + for (final ModuleRequires module : requiresTable) { buf.append(" ").append(module.toString(cp)).append("\n"); } - buf.append(" exports(").append(exports_table.length).append("):\n"); - for (final ModuleExports module : exports_table) { + buf.append(" exports(").append(exportsTable.length).append("):\n"); + for (final ModuleExports module : exportsTable) { buf.append(" ").append(module.toString(cp)).append("\n"); } - buf.append(" opens(").append(opens_table.length).append("):\n"); - for (final ModuleOpens module : opens_table) { + buf.append(" opens(").append(opensTable.length).append("):\n"); + for (final ModuleOpens module : opensTable) { buf.append(" ").append(module.toString(cp)).append("\n"); } - buf.append(" uses(").append(uses_index.length).append("):\n"); - for (final int index : uses_index) { + buf.append(" uses(").append(usesIndex.length).append("):\n"); + for (final int index : usesIndex) { final String class_name = cp.getConstantString(index, Const.CONSTANT_Class); buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n"); } - buf.append(" provides(").append(provides_table.length).append("):\n"); - for (final ModuleProvides module : provides_table) { + buf.append(" provides(").append(providesTable.length).append("):\n"); + for (final ModuleProvides module : providesTable) { buf.append(" ").append(module.toString(cp)).append("\n"); } @@ -235,24 +236,24 @@ public Attribute copy( final ConstantPool _constant_pool ) { final Module c = (Module) clone(); - c.requires_table = new ModuleRequires[requires_table.length]; - for (int i = 0; i < requires_table.length; i++) { - c.requires_table[i] = requires_table[i].copy(); + c.requiresTable = new ModuleRequires[requiresTable.length]; + for (int i = 0; i < requiresTable.length; i++) { + c.requiresTable[i] = requiresTable[i].copy(); } - c.exports_table = new ModuleExports[exports_table.length]; - for (int i = 0; i < exports_table.length; i++) { - c.exports_table[i] = exports_table[i].copy(); + c.exportsTable = new ModuleExports[exportsTable.length]; + for (int i = 0; i < exportsTable.length; i++) { + c.exportsTable[i] = exportsTable[i].copy(); } - c.opens_table = new ModuleOpens[opens_table.length]; - for (int i = 0; i < opens_table.length; i++) { - c.opens_table[i] = opens_table[i].copy(); + c.opensTable = new ModuleOpens[opensTable.length]; + for (int i = 0; i < opensTable.length; i++) { + c.opensTable[i] = opensTable[i].copy(); } - c.provides_table = new ModuleProvides[provides_table.length]; - for (int i = 0; i < provides_table.length; i++) { - c.provides_table[i] = provides_table[i].copy(); + c.providesTable = new ModuleProvides[providesTable.length]; + for (int i = 0; i < providesTable.length; i++) { + c.providesTable[i] = providesTable[i].copy(); } c.setConstantPool(_constant_pool);
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java index 441c08b..ec581c8 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java
@@ -36,10 +36,10 @@ */ public final class ModuleExports implements Cloneable, Node { - private final int exports_index; // points to CONSTANT_Package_info - private final int exports_flags; - private final int exports_to_count; - private final int[] exports_to_index; // points to CONSTANT_Module_info + private final int exportsIndex; // points to CONSTANT_Package_info + private final int exportsFlags; + private final int exportsToCount; + private final int[] exportsToIndex; // points to CONSTANT_Module_info /** @@ -49,12 +49,12 @@ * @throws IOException if an I/O Exception occurs in readUnsignedShort */ ModuleExports(final DataInput file) throws IOException { - exports_index = file.readUnsignedShort(); - exports_flags = file.readUnsignedShort(); - exports_to_count = file.readUnsignedShort(); - exports_to_index = new int[exports_to_count]; - for (int i = 0; i < exports_to_count; i++) { - exports_to_index[i] = file.readUnsignedShort(); + exportsIndex = file.readUnsignedShort(); + exportsFlags = file.readUnsignedShort(); + exportsToCount = file.readUnsignedShort(); + exportsToIndex = new int[exportsToCount]; + for (int i = 0; i < exportsToCount; i++) { + exportsToIndex[i] = file.readUnsignedShort(); } } @@ -80,10 +80,10 @@ * @throws IOException if an I/O Exception occurs in writeShort */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(exports_index); - file.writeShort(exports_flags); - file.writeShort(exports_to_count); - for (final int entry : exports_to_index) { + file.writeShort(exportsIndex); + file.writeShort(exportsFlags); + file.writeShort(exportsToCount); + for (final int entry : exportsToIndex) { file.writeShort(entry); } } @@ -94,7 +94,7 @@ */ @Override public String toString() { - return "exports(" + exports_index + ", " + exports_flags + ", " + exports_to_count + ", ...)"; + return "exports(" + exportsIndex + ", " + exportsFlags + ", " + exportsToCount + ", ...)"; } @@ -103,11 +103,11 @@ */ public String toString( final ConstantPool constant_pool ) { final StringBuilder buf = new StringBuilder(); - final String package_name = constant_pool.constantToString(exports_index, Const.CONSTANT_Package); + final String package_name = constant_pool.constantToString(exportsIndex, Const.CONSTANT_Package); buf.append(Utility.compactClassName(package_name, false)); - buf.append(", ").append(String.format("%04x", exports_flags)); - buf.append(", to(").append(exports_to_count).append("):\n"); - for (final int index : exports_to_index) { + buf.append(", ").append(String.format("%04x", exportsFlags)); + buf.append(", to(").append(exportsToCount).append("):\n"); + for (final int index : exportsToIndex) { final String module_name = constant_pool.getConstantString(index, Const.CONSTANT_Module); buf.append(" ").append(Utility.compactClassName(module_name, false)).append("\n"); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java index 2924df1..7b6d89e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java
@@ -35,7 +35,7 @@ */ public final class ModuleMainClass extends Attribute { - private int main_class_index; + private int mainClassIndex; /** @@ -50,27 +50,27 @@ /** * @param name_index Index in constant pool * @param length Content length in bytes - * @param main_class_index Host class index - * @param constant_pool Array of constants + * @param mainClassIndex Host class index + * @param constantPool Array of constants */ - public ModuleMainClass(final int name_index, final int length, final int main_class_index, - final ConstantPool constant_pool) { - super(Const.ATTR_NEST_MEMBERS, name_index, length, constant_pool); - this.main_class_index = main_class_index; + public ModuleMainClass(final int name_index, final int length, final int mainClassIndex, + final ConstantPool constantPool) { + super(Const.ATTR_NEST_MEMBERS, name_index, length, constantPool); + this.mainClassIndex = mainClassIndex; } /** * Construct object from input stream. - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants + * @param constantPool Array of constants * @throws IOException */ - ModuleMainClass(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - this(name_index, length, 0, constant_pool); - main_class_index = input.readUnsignedShort(); + ModuleMainClass(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, 0, constantPool); + mainClassIndex = input.readUnsignedShort(); } @@ -96,7 +96,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(main_class_index); + file.writeShort(mainClassIndex); } @@ -104,15 +104,15 @@ * @return index into constant pool of host class name. */ public int getHostClassIndex() { - return main_class_index; + return mainClassIndex; } /** - * @param main_class_index the host class index + * @param mainClassIndex the host class index */ - public void setHostClassIndex( final int main_class_index ) { - this.main_class_index = main_class_index; + public void setHostClassIndex( final int mainClassIndex ) { + this.mainClassIndex = mainClassIndex; } @@ -123,7 +123,7 @@ public String toString() { final StringBuilder buf = new StringBuilder(); buf.append("ModuleMainClass: "); - final String class_name = super.getConstantPool().getConstantString(main_class_index, Const.CONSTANT_Class); + final String class_name = super.getConstantPool().getConstantString(mainClassIndex, Const.CONSTANT_Class); buf.append(Utility.compactClassName(class_name, false)); return buf.toString(); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java index 81d4eb2..341228e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java
@@ -36,10 +36,10 @@ */ public final class ModuleOpens implements Cloneable, Node { - private final int opens_index; // points to CONSTANT_Package_info - private final int opens_flags; - private final int opens_to_count; - private final int[] opens_to_index; // points to CONSTANT_Module_info + private final int opensIndex; // points to CONSTANT_Package_info + private final int opensFlags; + private final int opensToCount; + private final int[] opensToIndex; // points to CONSTANT_Module_info /** @@ -49,12 +49,12 @@ * @throws IOException if an I/O Exception occurs in readUnsignedShort */ ModuleOpens(final DataInput file) throws IOException { - opens_index = file.readUnsignedShort(); - opens_flags = file.readUnsignedShort(); - opens_to_count = file.readUnsignedShort(); - opens_to_index = new int[opens_to_count]; - for (int i = 0; i < opens_to_count; i++) { - opens_to_index[i] = file.readUnsignedShort(); + opensIndex = file.readUnsignedShort(); + opensFlags = file.readUnsignedShort(); + opensToCount = file.readUnsignedShort(); + opensToIndex = new int[opensToCount]; + for (int i = 0; i < opensToCount; i++) { + opensToIndex[i] = file.readUnsignedShort(); } } @@ -80,10 +80,10 @@ * @throws IOException if an I/O Exception occurs in writeShort */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(opens_index); - file.writeShort(opens_flags); - file.writeShort(opens_to_count); - for (final int entry : opens_to_index) { + file.writeShort(opensIndex); + file.writeShort(opensFlags); + file.writeShort(opensToCount); + for (final int entry : opensToIndex) { file.writeShort(entry); } } @@ -94,7 +94,7 @@ */ @Override public String toString() { - return "opens(" + opens_index + ", " + opens_flags + ", " + opens_to_count + ", ...)"; + return "opens(" + opensIndex + ", " + opensFlags + ", " + opensToCount + ", ...)"; } @@ -103,11 +103,11 @@ */ public String toString( final ConstantPool constant_pool ) { final StringBuilder buf = new StringBuilder(); - final String package_name = constant_pool.constantToString(opens_index, Const.CONSTANT_Package); + final String package_name = constant_pool.constantToString(opensIndex, Const.CONSTANT_Package); buf.append(Utility.compactClassName(package_name, false)); - buf.append(", ").append(String.format("%04x", opens_flags)); - buf.append(", to(").append(opens_to_count).append("):\n"); - for (final int index : opens_to_index) { + buf.append(", ").append(String.format("%04x", opensFlags)); + buf.append(", to(").append(opensToCount).append("):\n"); + for (final int index : opensToIndex) { final String module_name = constant_pool.getConstantString(index, Const.CONSTANT_Module); buf.append(" ").append(Utility.compactClassName(module_name, false)).append("\n"); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java index f946bd0..1e1cb98 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java
@@ -35,7 +35,7 @@ */ public final class ModulePackages extends Attribute { - private int[] package_index_table; + private int[] packageIndexTable; /** @@ -48,15 +48,15 @@ /** - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes - * @param package_index_table Table of indices in constant pool - * @param constant_pool Array of constants + * @param packageIndexTable Table of indices in constant pool + * @param constantPool Array of constants */ - public ModulePackages(final int name_index, final int length, final int[] package_index_table, - final ConstantPool constant_pool) { - super(Const.ATTR_MODULE_PACKAGES, name_index, length, constant_pool); - this.package_index_table = package_index_table != null ? package_index_table : new int[0]; + public ModulePackages(final int nameIndex, final int length, final int[] packageIndexTable, + final ConstantPool constantPool) { + super(Const.ATTR_MODULE_PACKAGES, nameIndex, length, constantPool); + this.packageIndexTable = packageIndexTable != null ? packageIndexTable : new int[0]; } @@ -71,9 +71,9 @@ ModulePackages(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { this(name_index, length, (int[]) null, constant_pool); final int number_of_packages = input.readUnsignedShort(); - package_index_table = new int[number_of_packages]; + packageIndexTable = new int[number_of_packages]; for (int i = 0; i < number_of_packages; i++) { - package_index_table[i] = input.readUnsignedShort(); + packageIndexTable[i] = input.readUnsignedShort(); } } @@ -100,8 +100,8 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(package_index_table.length); - for (final int index : package_index_table) { + file.writeShort(packageIndexTable.length); + for (final int index : packageIndexTable) { file.writeShort(index); } } @@ -111,7 +111,7 @@ * @return array of indices into constant pool of package names. */ public int[] getPackageIndexTable() { - return package_index_table; + return packageIndexTable; } @@ -119,7 +119,7 @@ * @return Length of package table. */ public int getNumberOfPackages() { - return package_index_table == null ? 0 : package_index_table.length; + return packageIndexTable == null ? 0 : packageIndexTable.length; } @@ -127,9 +127,9 @@ * @return string array of package names */ public String[] getPackageNames() { - final String[] names = new String[package_index_table.length]; - for (int i = 0; i < package_index_table.length; i++) { - names[i] = super.getConstantPool().getConstantString(package_index_table[i], + final String[] names = new String[packageIndexTable.length]; + for (int i = 0; i < packageIndexTable.length; i++) { + names[i] = super.getConstantPool().getConstantString(packageIndexTable[i], Const.CONSTANT_Package).replace('/', '.'); } return names; @@ -137,11 +137,11 @@ /** - * @param package_index_table the list of package indexes + * @param packageIndexTable the list of package indexes * Also redefines number_of_packages according to table length. */ - public void setPackageIndexTable( final int[] package_index_table ) { - this.package_index_table = package_index_table != null ? package_index_table : new int[0]; + public void setPackageIndexTable( final int[] packageIndexTable ) { + this.packageIndexTable = packageIndexTable != null ? packageIndexTable : new int[0]; } @@ -152,9 +152,9 @@ public String toString() { final StringBuilder buf = new StringBuilder(); buf.append("ModulePackages("); - buf.append(package_index_table.length); + buf.append(packageIndexTable.length); buf.append("):\n"); - for (final int index : package_index_table) { + for (final int index : packageIndexTable) { final String package_name = super.getConstantPool().getConstantString(index, Const.CONSTANT_Package); buf.append(" ").append(Utility.compactClassName(package_name, false)).append("\n"); } @@ -168,10 +168,10 @@ @Override public Attribute copy( final ConstantPool _constant_pool ) { final ModulePackages c = (ModulePackages) clone(); - if (package_index_table != null) { - c.package_index_table = new int[package_index_table.length]; - System.arraycopy(package_index_table, 0, c.package_index_table, 0, - package_index_table.length); + if (packageIndexTable != null) { + c.packageIndexTable = new int[packageIndexTable.length]; + System.arraycopy(packageIndexTable, 0, c.packageIndexTable, 0, + packageIndexTable.length); } c.setConstantPool(_constant_pool); return c;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java index 90c1059..8cbeecc 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java
@@ -36,9 +36,9 @@ */ public final class ModuleProvides implements Cloneable, Node { - private final int provides_index; // points to CONSTANT_Class_info - private final int provides_with_count; - private final int[] provides_with_index; // points to CONSTANT_Class_info + private final int providesIndex; // points to CONSTANT_Class_info + private final int providesWithCount; + private final int[] providesWithIndex; // points to CONSTANT_Class_info /** @@ -48,11 +48,11 @@ * @throws IOException if an I/O Exception occurs in readUnsignedShort */ ModuleProvides(final DataInput file) throws IOException { - provides_index = file.readUnsignedShort(); - provides_with_count = file.readUnsignedShort(); - provides_with_index = new int[provides_with_count]; - for (int i = 0; i < provides_with_count; i++) { - provides_with_index[i] = file.readUnsignedShort(); + providesIndex = file.readUnsignedShort(); + providesWithCount = file.readUnsignedShort(); + providesWithIndex = new int[providesWithCount]; + for (int i = 0; i < providesWithCount; i++) { + providesWithIndex[i] = file.readUnsignedShort(); } } @@ -78,9 +78,9 @@ * @throws IOException if an I/O Exception occurs in writeShort */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(provides_index); - file.writeShort(provides_with_count); - for (final int entry : provides_with_index) { + file.writeShort(providesIndex); + file.writeShort(providesWithCount); + for (final int entry : providesWithIndex) { file.writeShort(entry); } } @@ -91,7 +91,7 @@ */ @Override public String toString() { - return "provides(" + provides_index + ", " + provides_with_count + ", ...)"; + return "provides(" + providesIndex + ", " + providesWithCount + ", ...)"; } @@ -100,10 +100,10 @@ */ public String toString( final ConstantPool constant_pool ) { final StringBuilder buf = new StringBuilder(); - final String interface_name = constant_pool.constantToString(provides_index, Const.CONSTANT_Class); + final String interface_name = constant_pool.constantToString(providesIndex, Const.CONSTANT_Class); buf.append(Utility.compactClassName(interface_name, false)); - buf.append(", with(").append(provides_with_count).append("):\n"); - for (final int index : provides_with_index) { + buf.append(", with(").append(providesWithCount).append("):\n"); + for (final int index : providesWithIndex) { final String class_name = constant_pool.getConstantString(index, Const.CONSTANT_Class); buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n"); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java index d860a86..a368197 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java
@@ -36,9 +36,9 @@ */ public final class ModuleRequires implements Cloneable, Node { - private final int requires_index; // points to CONSTANT_Module_info - private final int requires_flags; - private final int requires_version_index; // either 0 or points to CONSTANT_Utf8_info + private final int requiresIndex; // points to CONSTANT_Module_info + private final int requiresFlags; + private final int requiresVersionIndex; // either 0 or points to CONSTANT_Utf8_info /** @@ -48,9 +48,9 @@ * @throws IOException if an I/O Exception occurs in readUnsignedShort */ ModuleRequires(final DataInput file) throws IOException { - requires_index = file.readUnsignedShort(); - requires_flags = file.readUnsignedShort(); - requires_version_index = file.readUnsignedShort(); + requiresIndex = file.readUnsignedShort(); + requiresFlags = file.readUnsignedShort(); + requiresVersionIndex = file.readUnsignedShort(); } @@ -75,9 +75,9 @@ * @throws IOException if an I/O Exception occurs in writeShort */ public void dump( final DataOutputStream file ) throws IOException { - file.writeShort(requires_index); - file.writeShort(requires_flags); - file.writeShort(requires_version_index); + file.writeShort(requiresIndex); + file.writeShort(requiresFlags); + file.writeShort(requiresVersionIndex); } @@ -86,7 +86,7 @@ */ @Override public String toString() { - return "requires(" + requires_index + ", " + String.format("%04x", requires_flags) + ", " + requires_version_index + ")"; + return "requires(" + requiresIndex + ", " + String.format("%04x", requiresFlags) + ", " + requiresVersionIndex + ")"; } @@ -95,10 +95,10 @@ */ public String toString( final ConstantPool constant_pool ) { final StringBuilder buf = new StringBuilder(); - final String module_name = constant_pool.constantToString(requires_index, Const.CONSTANT_Module); + final String module_name = constant_pool.constantToString(requiresIndex, Const.CONSTANT_Module); buf.append(Utility.compactClassName(module_name, false)); - buf.append(", ").append(String.format("%04x", requires_flags)); - final String version = requires_version_index == 0 ? "0" : constant_pool.getConstantString(requires_version_index, Const.CONSTANT_Utf8); + buf.append(", ").append(String.format("%04x", requiresFlags)); + final String version = requiresVersionIndex == 0 ? "0" : constant_pool.getConstantString(requiresVersionIndex, Const.CONSTANT_Utf8); buf.append(", ").append(version); return buf.toString(); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java index c71b28e..b9a0a1d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java
@@ -36,7 +36,7 @@ */ public final class NestHost extends Attribute { - private int host_class_index; + private int hostClassIndex; /** @@ -49,15 +49,15 @@ /** - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes - * @param host_class_index Host class index - * @param constant_pool Array of constants + * @param hostClassIndex Host class index + * @param constantPool Array of constants */ - public NestHost(final int name_index, final int length, final int host_class_index, - final ConstantPool constant_pool) { - super(Const.ATTR_NEST_MEMBERS, name_index, length, constant_pool); - this.host_class_index = host_class_index; + public NestHost(final int nameIndex, final int length, final int hostClassIndex, + final ConstantPool constantPool) { + super(Const.ATTR_NEST_MEMBERS, nameIndex, length, constantPool); + this.hostClassIndex = hostClassIndex; } @@ -71,7 +71,7 @@ */ NestHost(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { this(name_index, length, 0, constant_pool); - host_class_index = input.readUnsignedShort(); + hostClassIndex = input.readUnsignedShort(); } @@ -97,7 +97,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(host_class_index); + file.writeShort(hostClassIndex); } @@ -105,15 +105,15 @@ * @return index into constant pool of host class name. */ public int getHostClassIndex() { - return host_class_index; + return hostClassIndex; } /** - * @param host_class_index the host class index + * @param hostClassIndex the host class index */ - public void setHostClassIndex( final int host_class_index ) { - this.host_class_index = host_class_index; + public void setHostClassIndex( final int hostClassIndex ) { + this.hostClassIndex = hostClassIndex; } @@ -124,7 +124,7 @@ public String toString() { final StringBuilder buf = new StringBuilder(); buf.append("NestHost: "); - final String class_name = super.getConstantPool().getConstantString(host_class_index, Const.CONSTANT_Class); + final String class_name = super.getConstantPool().getConstantString(hostClassIndex, Const.CONSTANT_Class); buf.append(Utility.compactClassName(class_name, false)); return buf.toString(); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java index 4d87c18..fed7464 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java
@@ -35,17 +35,17 @@ */ public final class PMGClass extends Attribute { - private int pmg_class_index; - private int pmg_index; + private int pmgClassIndex; + private int pmgIndex; /** * Initialize from another object. Note that both objects use the same * references (shallow copy). Use copy() for a physical copy. */ - public PMGClass(final PMGClass c) { - this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(), c - .getConstantPool()); + public PMGClass(final PMGClass pgmClass) { + this(pgmClass.getNameIndex(), pgmClass.getLength(), pgmClass.getPMGIndex(), pgmClass.getPMGClassIndex(), + pgmClass.getConstantPool()); } @@ -66,15 +66,15 @@ /** * @param name_index Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes - * @param pmg_index index in constant pool for source file name - * @param pmg_class_index Index in constant pool to CONSTANT_Utf8 - * @param constant_pool Array of constants + * @param pmgIndex index in constant pool for source file name + * @param pmgClassIndex Index in constant pool to CONSTANT_Utf8 + * @param constantPool Array of constants */ - public PMGClass(final int name_index, final int length, final int pmg_index, final int pmg_class_index, - final ConstantPool constant_pool) { - super(Const.ATTR_PMG, name_index, length, constant_pool); - this.pmg_index = pmg_index; - this.pmg_class_index = pmg_class_index; + public PMGClass(final int name_index, final int length, final int pmgIndex, final int pmgClassIndex, + final ConstantPool constantPool) { + super(Const.ATTR_PMG, name_index, length, constantPool); + this.pmgIndex = pmgIndex; + this.pmgClassIndex = pmgClassIndex; } @@ -100,8 +100,8 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(pmg_index); - file.writeShort(pmg_class_index); + file.writeShort(pmgIndex); + file.writeShort(pmgClassIndex); } @@ -109,15 +109,15 @@ * @return Index in constant pool of source file name. */ public int getPMGClassIndex() { - return pmg_class_index; + return pmgClassIndex; } /** - * @param pmg_class_index + * @param pmgClassIndex */ - public void setPMGClassIndex( final int pmg_class_index ) { - this.pmg_class_index = pmg_class_index; + public void setPMGClassIndex( final int pmgClassIndex ) { + this.pmgClassIndex = pmgClassIndex; } @@ -125,15 +125,15 @@ * @return Index in constant pool of source file name. */ public int getPMGIndex() { - return pmg_index; + return pmgIndex; } /** - * @param pmg_index + * @param pmgIndex */ - public void setPMGIndex( final int pmg_index ) { - this.pmg_index = pmg_index; + public void setPMGIndex( final int pmgIndex ) { + this.pmgIndex = pmgIndex; } @@ -141,7 +141,7 @@ * @return PMG name. */ public String getPMGName() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmg_index, + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmgIndex, Const.CONSTANT_Utf8); return c.getBytes(); } @@ -151,7 +151,7 @@ * @return PMG class name. */ public String getPMGClassName() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmg_class_index, + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmgClassIndex, Const.CONSTANT_Utf8); return c.getBytes(); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java index cf676e5..f652ad7 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java
@@ -35,7 +35,7 @@ */ public class ParameterAnnotationEntry implements Node { - private final AnnotationEntry[] annotation_table; + private final AnnotationEntry[] annotationTable; /** @@ -46,10 +46,10 @@ */ ParameterAnnotationEntry(final DataInput input, final ConstantPool constant_pool) throws IOException { final int annotation_table_length = input.readUnsignedShort(); - annotation_table = new AnnotationEntry[annotation_table_length]; + annotationTable = new AnnotationEntry[annotation_table_length]; for (int i = 0; i < annotation_table_length; i++) { // TODO isRuntimeVisible - annotation_table[i] = AnnotationEntry.read(input, constant_pool, false); + annotationTable[i] = AnnotationEntry.read(input, constant_pool, false); } } @@ -70,12 +70,12 @@ * returns the array of annotation entries in this annotation */ public AnnotationEntry[] getAnnotationEntries() { - return annotation_table; + return annotationTable; } public void dump(final DataOutputStream dos) throws IOException { - dos.writeShort(annotation_table.length); - for (final AnnotationEntry entry : annotation_table) { + dos.writeShort(annotationTable.length); + for (final AnnotationEntry entry : annotationTable) { entry.dump(dos); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java index 9ad197a..2370ed7 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java
@@ -33,7 +33,7 @@ public abstract class ParameterAnnotations extends Attribute { /** Table of parameter annotations */ - private ParameterAnnotationEntry[] parameter_annotation_table; + private ParameterAnnotationEntry[] parameterAnnotationTable; /** * @param parameter_annotation_type the subclass type of the parameter annotation @@ -47,24 +47,24 @@ this(parameter_annotation_type, name_index, length, (ParameterAnnotationEntry[]) null, constant_pool); final int num_parameters = input.readUnsignedByte(); - parameter_annotation_table = new ParameterAnnotationEntry[num_parameters]; + parameterAnnotationTable = new ParameterAnnotationEntry[num_parameters]; for (int i = 0; i < num_parameters; i++) { - parameter_annotation_table[i] = new ParameterAnnotationEntry(input, constant_pool); + parameterAnnotationTable[i] = new ParameterAnnotationEntry(input, constant_pool); } } /** - * @param parameter_annotation_type the subclass type of the parameter annotation - * @param name_index Index pointing to the name <em>Code</em> + * @param parameterAnnotationType the subclass type of the parameter annotation + * @param nameIndex Index pointing to the name <em>Code</em> * @param length Content length in bytes - * @param parameter_annotation_table the actual parameter annotations - * @param constant_pool Array of constants + * @param parameterAnnotationTable the actual parameter annotations + * @param constantPool Array of constants */ - public ParameterAnnotations(final byte parameter_annotation_type, final int name_index, final int length, - final ParameterAnnotationEntry[] parameter_annotation_table, final ConstantPool constant_pool) { - super(parameter_annotation_type, name_index, length, constant_pool); - this.parameter_annotation_table = parameter_annotation_table; + public ParameterAnnotations(final byte parameterAnnotationType, final int nameIndex, final int length, + final ParameterAnnotationEntry[] parameterAnnotationTable, final ConstantPool constantPool) { + super(parameterAnnotationType, nameIndex, length, constantPool); + this.parameterAnnotationTable = parameterAnnotationTable; } @@ -82,10 +82,10 @@ /** - * @param parameter_annotation_table the entries to set in this parameter annotation + * @param parameterAnnotationTable the entries to set in this parameter annotation */ - public final void setParameterAnnotationTable(final ParameterAnnotationEntry[] parameter_annotation_table ) { - this.parameter_annotation_table = parameter_annotation_table; + public final void setParameterAnnotationTable(final ParameterAnnotationEntry[] parameterAnnotationTable ) { + this.parameterAnnotationTable = parameterAnnotationTable; } @@ -93,7 +93,7 @@ * @return the parameter annotation entry table */ public final ParameterAnnotationEntry[] getParameterAnnotationTable() { - return parameter_annotation_table; + return parameterAnnotationTable; } @@ -101,16 +101,16 @@ * returns the array of parameter annotation entries in this parameter annotation */ public ParameterAnnotationEntry[] getParameterAnnotationEntries() { - return parameter_annotation_table; + return parameterAnnotationTable; } @Override public void dump(final DataOutputStream dos) throws IOException { super.dump(dos); - dos.writeByte(parameter_annotation_table.length); + dos.writeByte(parameterAnnotationTable.length); - for (final ParameterAnnotationEntry element : parameter_annotation_table) { + for (final ParameterAnnotationEntry element : parameterAnnotationTable) { element.dump(dos); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java index a647602..45c138c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java
@@ -36,7 +36,7 @@ */ public final class Signature extends Attribute { - private int signature_index; + private int signatureIndex; /** @@ -65,12 +65,12 @@ /** * @param name_index Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes - * @param signature_index Index in constant pool to CONSTANT_Utf8 + * @param signatureIndex Index in constant pool to CONSTANT_Utf8 * @param constant_pool Array of constants */ - public Signature(final int name_index, final int length, final int signature_index, final ConstantPool constant_pool) { + public Signature(final int name_index, final int length, final int signatureIndex, final ConstantPool constant_pool) { super(Const.ATTR_SIGNATURE, name_index, length, constant_pool); - this.signature_index = signature_index; + this.signatureIndex = signatureIndex; } @@ -97,7 +97,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(signature_index); + file.writeShort(signatureIndex); } @@ -105,15 +105,15 @@ * @return Index in constant pool of source file name. */ public int getSignatureIndex() { - return signature_index; + return signatureIndex; } /** - * @param signature_index the index info the constant pool of this signature + * @param signatureIndex the index info the constant pool of this signature */ - public void setSignatureIndex( final int signature_index ) { - this.signature_index = signature_index; + public void setSignatureIndex( final int signatureIndex ) { + this.signatureIndex = signatureIndex; } @@ -121,7 +121,7 @@ * @return GJ signature. */ public String getSignature() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(signature_index, + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(signatureIndex, Const.CONSTANT_Utf8); return c.getBytes(); } @@ -157,7 +157,7 @@ private static void matchIdent( final MyByteArrayInputStream in, final StringBuilder buf ) { int ch; if ((ch = in.read()) == -1) { - throw new RuntimeException("Illegal signature: " + in.getData() + throw new IllegalArgumentException("Illegal signature: " + in.getData() + " no ident, reaching EOF"); } //System.out.println("return from ident:" + (char)ch); @@ -207,7 +207,7 @@ matchGJIdent(in, buf); while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters if (ch == -1) { - throw new RuntimeException("Illegal signature: " + in.getData() + throw new IllegalArgumentException("Illegal signature: " + in.getData() + " reaching EOF"); } //System.out.println("Still no >"); @@ -228,7 +228,7 @@ in.unread(); return; } else if (ch != ';') { - throw new RuntimeException("Illegal signature: " + in.getData() + " read " + (char) ch); + throw new IllegalArgumentException("Illegal signature: " + in.getData() + " read " + (char) ch); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java index 24efbc3..7b3050e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java
@@ -55,7 +55,7 @@ public String getValueString() { if (super.getType() != STRING) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueString() on a non STRING ElementValue"); } final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(getIndex(), @@ -66,7 +66,7 @@ public int getValueInt() { if (super.getType() != PRIMITIVE_INT) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueString() on a non STRING ElementValue"); } final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), @@ -77,7 +77,7 @@ public byte getValueByte() { if (super.getType() != PRIMITIVE_BYTE) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueByte() on a non BYTE ElementValue"); } final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), @@ -88,7 +88,7 @@ public char getValueChar() { if (super.getType() != PRIMITIVE_CHAR) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueChar() on a non CHAR ElementValue"); } final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), @@ -99,7 +99,7 @@ public long getValueLong() { if (super.getType() != PRIMITIVE_LONG) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueLong() on a non LONG ElementValue"); } final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex()); @@ -109,7 +109,7 @@ public float getValueFloat() { if (super.getType() != PRIMITIVE_FLOAT) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueFloat() on a non FLOAT ElementValue"); } final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex()); @@ -119,7 +119,7 @@ public double getValueDouble() { if (super.getType() != PRIMITIVE_DOUBLE) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueDouble() on a non DOUBLE ElementValue"); } final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex()); @@ -129,7 +129,7 @@ public boolean getValueBoolean() { if (super.getType() != PRIMITIVE_BOOLEAN) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueBoolean() on a non BOOLEAN ElementValue"); } final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); @@ -139,7 +139,7 @@ public short getValueShort() { if (super.getType() != PRIMITIVE_SHORT) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueShort() on a non SHORT ElementValue"); } final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); @@ -200,7 +200,7 @@ Const.CONSTANT_Utf8); return cu8.getBytes(); default: - throw new RuntimeException("SimpleElementValue class does not know how to stringify type " + _type); + throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + _type); } } @@ -223,7 +223,7 @@ dos.writeShort(getIndex()); break; default: - throw new RuntimeException("SimpleElementValue doesnt know how to write out type " + _type); + throw new IllegalStateException("SimpleElementValue doesnt know how to write out type " + _type); } } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java index 2ed8ddf..dc030f5 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java
@@ -37,7 +37,7 @@ */ public final class SourceFile extends Attribute { - private int sourcefile_index; + private int sourceFileIndex; /** @@ -67,18 +67,18 @@ * @param name_index Index in constant pool to CONSTANT_Utf8, which * should represent the string "SourceFile". * @param length Content length in bytes, the value should be 2. - * @param constant_pool The constant pool that this attribute is + * @param constantPool The constant pool that this attribute is * associated with. - * @param sourcefile_index Index in constant pool to CONSTANT_Utf8. This + * @param sourceFileIndex Index in constant pool to CONSTANT_Utf8. This * string will be interpreted as the name of the file from which this * class was compiled. It will not be interpreted as indicating the name * of the directory contqining the file or an absolute path; this * information has to be supplied the consumer of this attribute - in * many cases, the JVM. */ - public SourceFile(final int name_index, final int length, final int sourcefile_index, final ConstantPool constant_pool) { - super(Const.ATTR_SOURCE_FILE, name_index, length, constant_pool); - this.sourcefile_index = sourcefile_index; + public SourceFile(final int name_index, final int length, final int sourceFileIndex, final ConstantPool constantPool) { + super(Const.ATTR_SOURCE_FILE, name_index, length, constantPool); + this.sourceFileIndex = sourceFileIndex; } @@ -104,7 +104,7 @@ @Override public void dump( final DataOutputStream file ) throws IOException { super.dump(file); - file.writeShort(sourcefile_index); + file.writeShort(sourceFileIndex); } @@ -112,15 +112,15 @@ * @return Index in constant pool of source file name. */ public int getSourceFileIndex() { - return sourcefile_index; + return sourceFileIndex; } /** - * @param sourcefile_index + * @param sourceFileIndex */ - public void setSourceFileIndex( final int sourcefile_index ) { - this.sourcefile_index = sourcefile_index; + public void setSourceFileIndex( final int sourceFileIndex ) { + this.sourceFileIndex = sourceFileIndex; } @@ -128,7 +128,7 @@ * @return Source file name. */ public String getSourceFileName() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(sourcefile_index, + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(sourceFileIndex, Const.CONSTANT_Utf8); return c.getBytes(); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java index 987fcfe..e5f4b8c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java
@@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -39,6 +38,7 @@ * @see Code * @see StackMapEntry * @see StackMapType + * @LastModified: Oct 2020 */ public final class StackMap extends Attribute {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java index e9abad0..eaf233a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java
@@ -37,11 +37,11 @@ public final class StackMapEntry implements Node, Cloneable { - private int frame_type; - private int byte_code_offset; - private StackMapType[] types_of_locals; - private StackMapType[] types_of_stack_items; - private ConstantPool constant_pool; + private int frameType; + private int byteCodeOffset; + private StackMapType[] typesOfLocals; + private StackMapType[] typesOfStackItems; + private ConstantPool constantPool; /** @@ -53,43 +53,43 @@ StackMapEntry(final DataInput input, final ConstantPool constantPool) throws IOException { this(input.readByte() & 0xFF, -1, null, null, constantPool); - if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { - byte_code_offset = frame_type - Const.SAME_FRAME; - } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { - byte_code_offset = frame_type - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; - types_of_stack_items = new StackMapType[1]; - types_of_stack_items[0] = new StackMapType(input, constantPool); - } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - byte_code_offset = input.readShort(); - types_of_stack_items = new StackMapType[1]; - types_of_stack_items[0] = new StackMapType(input, constantPool); - } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { - byte_code_offset = input.readShort(); - } else if (frame_type == Const.SAME_FRAME_EXTENDED) { - byte_code_offset = input.readShort(); - } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { - byte_code_offset = input.readShort(); - final int number_of_locals = frame_type - 251; - types_of_locals = new StackMapType[number_of_locals]; + if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { + byteCodeOffset = frameType - Const.SAME_FRAME; + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + byteCodeOffset = frameType - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; + typesOfStackItems = new StackMapType[1]; + typesOfStackItems[0] = new StackMapType(input, constantPool); + } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + byteCodeOffset = input.readShort(); + typesOfStackItems = new StackMapType[1]; + typesOfStackItems[0] = new StackMapType(input, constantPool); + } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { + byteCodeOffset = input.readShort(); + } else if (frameType == Const.SAME_FRAME_EXTENDED) { + byteCodeOffset = input.readShort(); + } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { + byteCodeOffset = input.readShort(); + final int number_of_locals = frameType - 251; + typesOfLocals = new StackMapType[number_of_locals]; for (int i = 0; i < number_of_locals; i++) { - types_of_locals[i] = new StackMapType(input, constantPool); + typesOfLocals[i] = new StackMapType(input, constantPool); } - } else if (frame_type == Const.FULL_FRAME) { - byte_code_offset = input.readShort(); + } else if (frameType == Const.FULL_FRAME) { + byteCodeOffset = input.readShort(); final int number_of_locals = input.readShort(); - types_of_locals = new StackMapType[number_of_locals]; + typesOfLocals = new StackMapType[number_of_locals]; for (int i = 0; i < number_of_locals; i++) { - types_of_locals[i] = new StackMapType(input, constantPool); + typesOfLocals[i] = new StackMapType(input, constantPool); } final int number_of_stack_items = input.readShort(); - types_of_stack_items = new StackMapType[number_of_stack_items]; + typesOfStackItems = new StackMapType[number_of_stack_items]; for (int i = 0; i < number_of_stack_items; i++) { - types_of_stack_items[i] = new StackMapType(input, constantPool); + typesOfStackItems[i] = new StackMapType(input, constantPool); } } else { /* Can't happen */ - throw new ClassFormatException ("Invalid frame type found while parsing stack map table: " + frame_type); + throw new ClassFormatException ("Invalid frame type found while parsing stack map table: " + frameType); } } @@ -109,16 +109,16 @@ public StackMapEntry(final int byteCodeOffset, final int numberOfLocals, final StackMapType[] typesOfLocals, final int numberOfStackItems, final StackMapType[] typesOfStackItems, final ConstantPool constantPool) { - this.byte_code_offset = byteCodeOffset; - this.types_of_locals = typesOfLocals != null ? typesOfLocals : new StackMapType[0]; - this.types_of_stack_items = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0]; - this.constant_pool = constantPool; + this.byteCodeOffset = byteCodeOffset; + this.typesOfLocals = typesOfLocals != null ? typesOfLocals : new StackMapType[0]; + this.typesOfStackItems = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0]; + this.constantPool = constantPool; } /** * Create an instance * - * @param tag the frame_type to use + * @param tag the frameType to use * @param byteCodeOffset * @param typesOfLocals array of {@link StackMapType}s of locals * @param typesOfStackItems array ot {@link StackMapType}s of stack items @@ -127,11 +127,11 @@ public StackMapEntry(final int tag, final int byteCodeOffset, final StackMapType[] typesOfLocals, final StackMapType[] typesOfStackItems, final ConstantPool constantPool) { - this.frame_type = tag; - this.byte_code_offset = byteCodeOffset; - this.types_of_locals = typesOfLocals != null ? typesOfLocals : new StackMapType[0]; - this.types_of_stack_items = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0]; - this.constant_pool = constantPool; + this.frameType = tag; + this.byteCodeOffset = byteCodeOffset; + this.typesOfLocals = typesOfLocals != null ? typesOfLocals : new StackMapType[0]; + this.typesOfStackItems = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0]; + this.constantPool = constantPool; } @@ -142,37 +142,37 @@ * @throws IOException */ public void dump( final DataOutputStream file ) throws IOException { - file.write(frame_type); - if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + file.write(frameType); + if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { // nothing to be done - } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { - types_of_stack_items[0].dump(file); - } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - file.writeShort(byte_code_offset); - types_of_stack_items[0].dump(file); - } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { - file.writeShort(byte_code_offset); - } else if (frame_type == Const.SAME_FRAME_EXTENDED) { - file.writeShort(byte_code_offset); - } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { - file.writeShort(byte_code_offset); - for (final StackMapType type : types_of_locals) { + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + typesOfStackItems[0].dump(file); + } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + file.writeShort(byteCodeOffset); + typesOfStackItems[0].dump(file); + } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { + file.writeShort(byteCodeOffset); + } else if (frameType == Const.SAME_FRAME_EXTENDED) { + file.writeShort(byteCodeOffset); + } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { + file.writeShort(byteCodeOffset); + for (final StackMapType type : typesOfLocals) { type.dump(file); } - } else if (frame_type == Const.FULL_FRAME) { - file.writeShort(byte_code_offset); - file.writeShort(types_of_locals.length); - for (final StackMapType type : types_of_locals) { + } else if (frameType == Const.FULL_FRAME) { + file.writeShort(byteCodeOffset); + file.writeShort(typesOfLocals.length); + for (final StackMapType type : typesOfLocals) { type.dump(file); } - file.writeShort(types_of_stack_items.length); - for (final StackMapType type : types_of_stack_items) { + file.writeShort(typesOfStackItems.length); + for (final StackMapType type : typesOfStackItems) { type.dump(file); } } else { /* Can't happen */ - throw new ClassFormatException ("Invalid Stack map table tag: " + frame_type); + throw new ClassFormatException ("Invalid Stack map table tag: " + frameType); } } @@ -184,40 +184,40 @@ public String toString() { final StringBuilder buf = new StringBuilder(64); buf.append("("); - if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { buf.append("SAME"); - } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { buf.append("SAME_LOCALS_1_STACK"); - } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { buf.append("SAME_LOCALS_1_STACK_EXTENDED"); - } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { - buf.append("CHOP ").append(String.valueOf(251-frame_type)); - } else if (frame_type == Const.SAME_FRAME_EXTENDED) { + } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { + buf.append("CHOP ").append(String.valueOf(251-frameType)); + } else if (frameType == Const.SAME_FRAME_EXTENDED) { buf.append("SAME_EXTENDED"); - } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { - buf.append("APPEND ").append(String.valueOf(frame_type-251)); - } else if (frame_type == Const.FULL_FRAME) { + } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { + buf.append("APPEND ").append(String.valueOf(frameType-251)); + } else if (frameType == Const.FULL_FRAME) { buf.append("FULL"); } else { - buf.append("UNKNOWN (").append(frame_type).append(")"); + buf.append("UNKNOWN (").append(frameType).append(")"); } - buf.append(", offset delta=").append(byte_code_offset); - if (types_of_locals.length > 0) { + buf.append(", offset delta=").append(byteCodeOffset); + if (typesOfLocals.length > 0) { buf.append(", locals={"); - for (int i = 0; i < types_of_locals.length; i++) { - buf.append(types_of_locals[i]); - if (i < types_of_locals.length - 1) { + for (int i = 0; i < typesOfLocals.length; i++) { + buf.append(typesOfLocals[i]); + if (i < typesOfLocals.length - 1) { buf.append(", "); } } buf.append("}"); } - if (types_of_stack_items.length > 0) { + if (typesOfStackItems.length > 0) { buf.append(", stack items={"); - for (int i = 0; i < types_of_stack_items.length; i++) { - buf.append(types_of_stack_items[i]); - if (i < types_of_stack_items.length - 1) { + for (int i = 0; i < typesOfStackItems.length; i++) { + buf.append(typesOfStackItems[i]); + if (i < typesOfStackItems.length - 1) { buf.append(", "); } } @@ -233,91 +233,91 @@ * */ int getMapEntrySize() { - if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { return 1; - } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { - return 1 + (types_of_stack_items[0].hasIndex() ? 3 : 1); - } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - return 3 + (types_of_stack_items[0].hasIndex() ? 3 : 1); - } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + return 1 + (typesOfStackItems[0].hasIndex() ? 3 : 1); + } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + return 3 + (typesOfStackItems[0].hasIndex() ? 3 : 1); + } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { return 3; - } else if (frame_type == Const.SAME_FRAME_EXTENDED) { + } else if (frameType == Const.SAME_FRAME_EXTENDED) { return 3; - } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { + } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { int len = 3; - for (final StackMapType types_of_local : types_of_locals) { + for (final StackMapType types_of_local : typesOfLocals) { len += types_of_local.hasIndex() ? 3 : 1; } return len; - } else if (frame_type == Const.FULL_FRAME) { + } else if (frameType == Const.FULL_FRAME) { int len = 7; - for (final StackMapType types_of_local : types_of_locals) { + for (final StackMapType types_of_local : typesOfLocals) { len += types_of_local.hasIndex() ? 3 : 1; } - for (final StackMapType types_of_stack_item : types_of_stack_items) { + for (final StackMapType types_of_stack_item : typesOfStackItems) { len += types_of_stack_item.hasIndex() ? 3 : 1; } return len; } else { - throw new RuntimeException("Invalid StackMap frame_type: " + frame_type); + throw new IllegalStateException("Invalid StackMap frameType: " + frameType); } } public void setFrameType( final int f ) { if (f >= Const.SAME_FRAME && f <= Const.SAME_FRAME_MAX) { - byte_code_offset = f - Const.SAME_FRAME; + byteCodeOffset = f - Const.SAME_FRAME; } else if (f >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && f <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { - byte_code_offset = f - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; + byteCodeOffset = f - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; } else if (f == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock } else if (f >= Const.CHOP_FRAME && f <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock } else if (f == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock } else if (f >= Const.APPEND_FRAME && f <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock } else if (f == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock } else { - throw new RuntimeException("Invalid StackMap frame_type"); + throw new IllegalArgumentException("Invalid StackMap frameType"); } - frame_type = f; + frameType = f; } public int getFrameType() { - return frame_type; + return frameType; } public void setByteCodeOffset( final int new_offset ) { if (new_offset < 0 || new_offset > 32767) { - throw new RuntimeException("Invalid StackMap offset: " + new_offset); + throw new IllegalArgumentException("Invalid StackMap offset: " + new_offset); } - if (frame_type >= Const.SAME_FRAME && - frame_type <= Const.SAME_FRAME_MAX) { + if (frameType >= Const.SAME_FRAME && + frameType <= Const.SAME_FRAME_MAX) { if (new_offset > Const.SAME_FRAME_MAX) { - frame_type = Const.SAME_FRAME_EXTENDED; + frameType = Const.SAME_FRAME_EXTENDED; } else { - frame_type = new_offset; + frameType = new_offset; } - } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { if (new_offset > Const.SAME_FRAME_MAX) { - frame_type = Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED; + frameType = Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED; } else { - frame_type = Const.SAME_LOCALS_1_STACK_ITEM_FRAME + new_offset; + frameType = Const.SAME_LOCALS_1_STACK_ITEM_FRAME + new_offset; } - } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frame_type >= Const.CHOP_FRAME && - frame_type <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frame_type == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frame_type >= Const.APPEND_FRAME && - frame_type <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frame_type == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frameType >= Const.CHOP_FRAME && + frameType <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frameType == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frameType >= Const.APPEND_FRAME && + frameType <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frameType == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock } else { - throw new RuntimeException("Invalid StackMap frame_type: " + frame_type); + throw new IllegalStateException("Invalid StackMap frameType: " + frameType); } - byte_code_offset = new_offset; + byteCodeOffset = new_offset; } @@ -329,12 +329,12 @@ * @param delta offset delta */ public void updateByteCodeOffset(final int delta) { - setByteCodeOffset(byte_code_offset + delta); + setByteCodeOffset(byteCodeOffset + delta); } public int getByteCodeOffset() { - return byte_code_offset; + return byteCodeOffset; } @@ -348,17 +348,17 @@ public int getNumberOfLocals() { - return types_of_locals.length; + return typesOfLocals.length; } public void setTypesOfLocals( final StackMapType[] types ) { - types_of_locals = types != null ? types : new StackMapType[0]; + typesOfLocals = types != null ? types : new StackMapType[0]; } public StackMapType[] getTypesOfLocals() { - return types_of_locals; + return typesOfLocals; } @@ -372,17 +372,17 @@ public int getNumberOfStackItems() { - return types_of_stack_items.length; + return typesOfStackItems.length; } public void setTypesOfStackItems( final StackMapType[] types ) { - types_of_stack_items = types != null ? types : new StackMapType[0]; + typesOfStackItems = types != null ? types : new StackMapType[0]; } public StackMapType[] getTypesOfStackItems() { - return types_of_stack_items; + return typesOfStackItems; } @@ -397,13 +397,13 @@ throw new Error("Clone Not Supported"); } - e.types_of_locals = new StackMapType[types_of_locals.length]; - for (int i = 0; i < types_of_locals.length; i++) { - e.types_of_locals[i] = types_of_locals[i].copy(); + e.typesOfLocals = new StackMapType[typesOfLocals.length]; + for (int i = 0; i < typesOfLocals.length; i++) { + e.typesOfLocals[i] = typesOfLocals[i].copy(); } - e.types_of_stack_items = new StackMapType[types_of_stack_items.length]; - for (int i = 0; i < types_of_stack_items.length; i++) { - e.types_of_stack_items[i] = types_of_stack_items[i].copy(); + e.typesOfStackItems = new StackMapType[typesOfStackItems.length]; + for (int i = 0; i < typesOfStackItems.length; i++) { + e.typesOfStackItems[i] = typesOfStackItems[i].copy(); } return e; } @@ -426,14 +426,14 @@ * @return Constant pool used by this object. */ public ConstantPool getConstantPool() { - return constant_pool; + return constantPool; } /** - * @param constant_pool Constant pool to be used for this object. + * @param constantPool Constant pool to be used for this object. */ - public void setConstantPool( final ConstantPool constant_pool ) { - this.constant_pool = constant_pool; + public void setConstantPool( final ConstantPool constantPool ) { + this.constantPool = constantPool; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java index bf0f749..8d7c387 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java
@@ -39,7 +39,7 @@ private byte type; private int index = -1; // Index to CONSTANT_Class or offset - private ConstantPool constant_pool; + private ConstantPool constantPool; /** @@ -52,7 +52,7 @@ if (hasIndex()) { this.index = file.readShort(); } - this.constant_pool = constant_pool; + this.constantPool = constant_pool; } @@ -62,17 +62,17 @@ */ public StackMapType(final byte type, final int index, final ConstantPool constant_pool) { if ((type < Const.ITEM_Bogus) || (type > Const.ITEM_NewObject)) { - throw new RuntimeException("Illegal type for StackMapType: " + type); + throw new IllegalArgumentException("Illegal type for StackMapType: " + type); } this.type = type; this.index = index; - this.constant_pool = constant_pool; + this.constantPool = constant_pool; } public void setType( final byte t ) { if ((t < Const.ITEM_Bogus) || (t > Const.ITEM_NewObject)) { - throw new RuntimeException("Illegal type for StackMapType: " + t); + throw new IllegalArgumentException("Illegal type for StackMapType: " + t); } type = t; } @@ -122,7 +122,7 @@ if (index < 0) { return ", class=<unknown>"; } - return ", class=" + constant_pool.constantToString(index, Const.CONSTANT_Class); + return ", class=" + constantPool.constantToString(index, Const.CONSTANT_Class); } else if (type == Const.ITEM_NewObject) { return ", offset=" + index; } else { @@ -157,14 +157,14 @@ * @return Constant pool used by this object. */ public ConstantPool getConstantPool() { - return constant_pool; + return constantPool; } /** - * @param constant_pool Constant pool to be used for this object. + * @param constantPool Constant pool to be used for this object. */ - public void setConstantPool( final ConstantPool constant_pool ) { - this.constant_pool = constant_pool; + public void setConstantPool( final ConstantPool constantPool ) { + this.constantPool = constantPool; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java index b12cb28..9b93a91 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java
@@ -45,15 +45,15 @@ private byte[] bytes; private final String name; - private static final Map<String, Unknown> unknown_attributes = new HashMap<>(); + private static final Map<String, Unknown> unknownAttributes = new HashMap<>(); /** @return array of unknown attributes, but just one for each kind. */ static Unknown[] getUnknownAttributes() { - final Unknown[] unknowns = new Unknown[unknown_attributes.size()]; - unknown_attributes.values().toArray(unknowns); - unknown_attributes.clear(); + final Unknown[] unknowns = new Unknown[unknownAttributes.size()]; + unknownAttributes.values().toArray(unknowns); + unknownAttributes.clear(); return unknowns; } @@ -80,7 +80,7 @@ this.bytes = bytes; name = ((ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8)) .getBytes(); - unknown_attributes.put(name, this); + unknownAttributes.put(name, this); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java index a1f23d4..8577bdf 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,7 +42,7 @@ /** * Utility functions that do not really belong to any class in particular. * - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ // @since 6.0 methods are no longer final public abstract class Utility { @@ -772,10 +772,10 @@ * There is some nomenclature confusion through much of the BCEL code base with * respect to the terms Descriptor and Signature. For the offical definitions see: * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3"> * Descriptors in The Java Virtual Machine Specification</a> * - * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.9.1"> + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.9.1"> * Signatures in The Java Virtual Machine Specification</a> * * In brief, a descriptor is a string representing the type of a field or method. @@ -835,30 +835,29 @@ index += unwrap(consumed_chars); // update position // ignore any throws information in the signature return type; - } else { - // Could be Class or Type... - type = typeSignatureToString(signature.substring(index), chopit); - index += unwrap(consumed_chars); // update position - if ((typeParams.length() == 0) && (index == signature.length())) { - // We have a Type signature. - return type; - } - // We have a Class signature. - final StringBuilder typeClass = new StringBuilder(typeParams); - typeClass.append(" extends "); - typeClass.append(type); - if (index < signature.length()) { - typeClass.append(" implements "); - typeClass.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position - } - while (index < signature.length()) { - typeClass.append(", "); - typeClass.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position - } - return typeClass.toString(); } + // Could be Class or Type... + type = typeSignatureToString(signature.substring(index), chopit); + index += unwrap(consumed_chars); // update position + if ((typeParams.length() == 0) && (index == signature.length())) { + // We have a Type signature. + return type; + } + // We have a Class signature. + final StringBuilder typeClass = new StringBuilder(typeParams); + typeClass.append(" extends "); + typeClass.append(type); + if (index < signature.length()) { + typeClass.append(" implements "); + typeClass.append(typeSignatureToString(signature.substring(index), chopit)); + index += unwrap(consumed_chars); // update position + } + while (index < signature.length()) { + typeClass.append(", "); + typeClass.append(typeSignatureToString(signature.substring(index), chopit)); + index += unwrap(consumed_chars); // update position + } + return typeClass.toString(); } @@ -1149,7 +1148,7 @@ break; case '[': if (!char_found) { - throw new RuntimeException("Illegal type: " + type); + throw new IllegalArgumentException("Illegal type: " + type); } index = i; break loop; @@ -1191,13 +1190,13 @@ switch (c) { case '[': if (open) { - throw new RuntimeException("Illegally nested brackets:" + brackets); + throw new IllegalArgumentException("Illegally nested brackets:" + brackets); } open = true; break; case ']': if (!open) { - throw new RuntimeException("Illegally nested brackets:" + brackets); + throw new IllegalArgumentException("Illegally nested brackets:" + brackets); } open = false; count++; @@ -1208,7 +1207,7 @@ } } if (open) { - throw new RuntimeException("Illegally nested brackets:" + brackets); + throw new IllegalArgumentException("Illegally nested brackets:" + brackets); } return count; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java index 61c08bb..e58f600 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java
@@ -46,7 +46,7 @@ { super(type, cpool); if (type != ANNOTATION) { - throw new RuntimeException( + throw new IllegalArgumentException( "Only element values of type annotation can be built with this ctor - type specified: " + type); } this.a = annotation; @@ -69,7 +69,7 @@ @Override public String stringifyValue() { - throw new RuntimeException("Not implemented yet"); + throw new UnsupportedOperationException("Not implemented yet"); } /**
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java index 699b656..b20f6ba 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java
@@ -49,7 +49,7 @@ { super(type, cpool); if (type != ARRAY) { - throw new RuntimeException( + throw new IllegalArgumentException( "Only element values of type array can be built with this ctor - type specified: " + type); } this.evalues = new ArrayList<>();
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java index f38e6bb..50b0dbf 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java
@@ -83,7 +83,7 @@ case com.sun.org.apache.bcel.internal.Const.AASTORE: return Type.OBJECT; default: - throw new ClassGenException("Oops: unknown case in switch" + _opcode); + throw new ClassGenException("Unknown case in switch" + _opcode); } } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java index 68de2f3..3b20c73 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java
@@ -29,7 +29,7 @@ public final class ArrayType extends ReferenceType { private int dimensions; - private Type basic_type; + private Type basicType; /** @@ -66,20 +66,20 @@ case Const.T_ARRAY: final ArrayType array = (ArrayType) type; this.dimensions = dimensions + array.dimensions; - basic_type = array.basic_type; + basicType = array.basicType; break; case Const.T_VOID: throw new ClassGenException("Invalid type: void[]"); default: // Basic type or reference this.dimensions = dimensions; - basic_type = type; + basicType = type; break; } final StringBuilder buf = new StringBuilder(); for (int i = 0; i < this.dimensions; i++) { buf.append('['); } - buf.append(basic_type.getSignature()); + buf.append(basicType.getSignature()); super.setSignature(buf.toString()); } @@ -88,7 +88,7 @@ * @return basic type of array, i.e., for int[][][] the basic type is int */ public Type getBasicType() { - return basic_type; + return basicType; } @@ -97,9 +97,9 @@ */ public Type getElementType() { if (dimensions == 1) { - return basic_type; + return basicType; } - return new ArrayType(basic_type, dimensions - 1); + return new ArrayType(basicType, dimensions - 1); } @@ -114,7 +114,7 @@ */ @Override public int hashCode() { - return basic_type.hashCode() ^ dimensions; + return basicType.hashCode() ^ dimensions; } @@ -124,7 +124,7 @@ public boolean equals( final Object _type ) { if (_type instanceof ArrayType) { final ArrayType array = (ArrayType) _type; - return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); + return (array.dimensions == dimensions) && array.basicType.equals(basicType); } return false; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java index cd3de5a..04be4be 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,28 +42,28 @@ * existing java class (file). * * @see JavaClass - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class ClassGen extends AccessFlags implements Cloneable { /* Corresponds to the fields found in a JavaClass object. */ - private String class_name; - private String super_class_name; - private final String file_name; - private int class_name_index = -1; + private String className; + private String superClassName; + private final String fileName; + private int classNameIndex = -1; private int superclass_name_index = -1; - private int major = Const.MAJOR; - private int minor = Const.MINOR; + private int major = Const.MAJOR_1_1; + private int minor = Const.MINOR_1_1; private ConstantPoolGen cp; // Template for building up constant pool // ArrayLists instead of arrays to gather fields, methods, etc. - private final List<Field> field_vec = new ArrayList<>(); - private final List<Method> method_vec = new ArrayList<>(); - private final List<Attribute> attribute_vec = new ArrayList<>(); - private final List<String> interface_vec = new ArrayList<>(); - private final List<AnnotationEntryGen> annotation_vec = new ArrayList<>(); + private final List<Field> fieldList = new ArrayList<>(); + private final List<Method> methodList = new ArrayList<>(); + private final List<Attribute> attributeList = new ArrayList<>(); + private final List<String> interfaceList = new ArrayList<>(); + private final List<AnnotationEntryGen> annotationList = new ArrayList<>(); - private static BCELComparator _cmp = new BCELComparator() { + private static BCELComparator bcelComparator = new BCELComparator() { @Override public boolean equals( final Object o1, final Object o2 ) { @@ -83,27 +83,27 @@ /** Convenience constructor to set up some important values initially. * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers + * @param className fully qualified class name + * @param superClassName fully qualified superclass name + * @param fileName source file name + * @param accessFlags access qualifiers * @param interfaces implemented interfaces * @param cp constant pool to use */ - public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags, + public ClassGen(final String className, final String superClassName, final String fileName, final int accessFlags, final String[] interfaces, final ConstantPoolGen cp) { - super(access_flags); - this.class_name = class_name; - this.super_class_name = super_class_name; - this.file_name = file_name; + super(accessFlags); + this.className = className; + this.superClassName = superClassName; + this.fileName = fileName; this.cp = cp; // Put everything needed by default into the constant pool and the vectors - if (file_name != null) { - addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp + if (fileName != null) { + addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(fileName), cp .getConstantPool())); } - class_name_index = cp.addClass(class_name); - superclass_name_index = cp.addClass(super_class_name); + classNameIndex = cp.addClass(className); + superclass_name_index = cp.addClass(superClassName); if (interfaces != null) { for (final String interface1 : interfaces) { addInterface(interface1); @@ -114,15 +114,15 @@ /** Convenience constructor to set up some important values initially. * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers + * @param className fully qualified class name + * @param superClassName fully qualified superclass name + * @param fileName source file name + * @param accessFlags access qualifiers * @param interfaces implemented interfaces */ - public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags, + public ClassGen(final String className, final String superClassName, final String fileName, final int accessFlags, final String[] interfaces) { - this(class_name, super_class_name, file_name, access_flags, interfaces, + this(className, superClassName, fileName, accessFlags, interfaces, new ConstantPoolGen()); } @@ -133,11 +133,11 @@ */ public ClassGen(final JavaClass clazz) { super(clazz.getAccessFlags()); - class_name_index = clazz.getClassNameIndex(); + classNameIndex = clazz.getClassNameIndex(); superclass_name_index = clazz.getSuperclassNameIndex(); - class_name = clazz.getClassName(); - super_class_name = clazz.getSuperclassName(); - file_name = clazz.getSourceFileName(); + className = clazz.getClassName(); + superClassName = clazz.getSuperclassName(); + fileName = clazz.getSourceFileName(); cp = new ConstantPoolGen(clazz.getConstantPool()); major = clazz.getMajor(); minor = clazz.getMinor(); @@ -205,18 +205,18 @@ final Field[] fields = getFields(); final Method[] methods = getMethods(); Attribute[] attributes = null; - if (annotation_vec.isEmpty()) { + if (annotationList.isEmpty()) { attributes = getAttributes(); } else { // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations' final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries()); - attributes = new Attribute[attribute_vec.size()+annAttributes.length]; - attribute_vec.toArray(attributes); - System.arraycopy(annAttributes,0,attributes,attribute_vec.size(),annAttributes.length); + attributes = new Attribute[attributeList.size()+annAttributes.length]; + attributeList.toArray(attributes); + System.arraycopy(annAttributes,0,attributes,attributeList.size(),annAttributes.length); } // Must be last since the above calls may still add something to it final ConstantPool _cp = this.cp.getFinalConstantPool(); - return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, + return new JavaClass(classNameIndex, superclass_name_index, fileName, major, minor, super.getAccessFlags(), _cp, interfaces, fields, methods, attributes); } @@ -226,7 +226,7 @@ * @param name interface to implement (fully qualified class name) */ public void addInterface( final String name ) { - interface_vec.add(name); + interfaceList.add(name); } @@ -235,7 +235,7 @@ * @param name interface to remove (fully qualified name) */ public void removeInterface( final String name ) { - interface_vec.remove(name); + interfaceList.remove(name); } @@ -275,11 +275,11 @@ * @param a attribute to add */ public void addAttribute( final Attribute a ) { - attribute_vec.add(a); + attributeList.add(a); } public void addAnnotationEntry(final AnnotationEntryGen a) { - annotation_vec.add(a); + annotationList.add(a); } @@ -288,7 +288,7 @@ * @param m method to add */ public void addMethod( final Method m ) { - method_vec.add(m); + methodList.add(m); } @@ -301,10 +301,10 @@ public void addEmptyConstructor( final int access_flags ) { final InstructionList il = new InstructionList(); il.append(InstructionConst.THIS); // Push `this' - il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V"))); + il.append(new INVOKESPECIAL(cp.addMethodref(superClassName, "<init>", "()V"))); il.append(InstructionConst.RETURN); final MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>", - class_name, il, cp); + className, il, cp); mg.setMaxStack(1); addMethod(mg.getMethod()); } @@ -315,19 +315,19 @@ * @param f field to add */ public void addField( final Field f ) { - field_vec.add(f); + fieldList.add(f); } public boolean containsField( final Field f ) { - return field_vec.contains(f); + return fieldList.contains(f); } /** @return field object with given name, or null */ public Field containsField( final String name ) { - for (final Field f : field_vec) { + for (final Field f : fieldList) { if (f.getName().equals(name)) { return f; } @@ -339,7 +339,7 @@ /** @return method object with given name and signature, or null */ public Method containsMethod( final String name, final String signature ) { - for (final Method m : method_vec) { + for (final Method m : methodList) { if (m.getName().equals(name) && m.getSignature().equals(signature)) { return m; } @@ -353,7 +353,7 @@ * @param a attribute to remove */ public void removeAttribute( final Attribute a ) { - attribute_vec.remove(a); + attributeList.remove(a); } @@ -362,7 +362,7 @@ * @param m method to remove */ public void removeMethod( final Method m ) { - method_vec.remove(m); + methodList.remove(m); } @@ -373,11 +373,11 @@ if (new_ == null) { throw new ClassGenException("Replacement method must not be null"); } - final int i = method_vec.indexOf(old); + final int i = methodList.indexOf(old); if (i < 0) { - method_vec.add(new_); + methodList.add(new_); } else { - method_vec.set(i, new_); + methodList.set(i, new_); } } @@ -389,11 +389,11 @@ if (new_ == null) { throw new ClassGenException("Replacement method must not be null"); } - final int i = field_vec.indexOf(old); + final int i = fieldList.indexOf(old); if (i < 0) { - field_vec.add(new_); + fieldList.add(new_); } else { - field_vec.set(i, new_); + fieldList.set(i, new_); } } @@ -403,44 +403,44 @@ * @param f field to remove */ public void removeField( final Field f ) { - field_vec.remove(f); + fieldList.remove(f); } public String getClassName() { - return class_name; + return className; } public String getSuperclassName() { - return super_class_name; + return superClassName; } public String getFileName() { - return file_name; + return fileName; } public void setClassName( final String name ) { - class_name = name.replace('/', '.'); - class_name_index = cp.addClass(name); + className = name.replace('/', '.'); + classNameIndex = cp.addClass(name); } public void setSuperclassName( final String name ) { - super_class_name = name.replace('/', '.'); + superClassName = name.replace('/', '.'); superclass_name_index = cp.addClass(name); } public Method[] getMethods() { - return method_vec.toArray(new Method[method_vec.size()]); + return methodList.toArray(new Method[methodList.size()]); } public void setMethods( final Method[] methods ) { - method_vec.clear(); + methodList.clear(); for (final Method method : methods) { addMethod(method); } @@ -448,45 +448,45 @@ public void setMethodAt( final Method method, final int pos ) { - method_vec.set(pos, method); + methodList.set(pos, method); } public Method getMethodAt( final int pos ) { - return method_vec.get(pos); + return methodList.get(pos); } public String[] getInterfaceNames() { - final int size = interface_vec.size(); + final int size = interfaceList.size(); final String[] interfaces = new String[size]; - interface_vec.toArray(interfaces); + interfaceList.toArray(interfaces); return interfaces; } public int[] getInterfaces() { - final int size = interface_vec.size(); + final int size = interfaceList.size(); final int[] interfaces = new int[size]; for (int i = 0; i < size; i++) { - interfaces[i] = cp.addClass(interface_vec.get(i)); + interfaces[i] = cp.addClass(interfaceList.get(i)); } return interfaces; } public Field[] getFields() { - return field_vec.toArray(new Field[field_vec.size()]); + return fieldList.toArray(new Field[fieldList.size()]); } public Attribute[] getAttributes() { - return attribute_vec.toArray(new Attribute[attribute_vec.size()]); + return attributeList.toArray(new Attribute[attributeList.size()]); } // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here? public AnnotationEntryGen[] getAnnotationEntries() { - return annotation_vec.toArray(new AnnotationEntryGen[annotation_vec.size()]); + return annotationList.toArray(new AnnotationEntryGen[annotationList.size()]); } @@ -501,15 +501,15 @@ public void setClassNameIndex( final int class_name_index ) { - this.class_name_index = class_name_index; - class_name = cp.getConstantPool().getConstantString(class_name_index, + this.classNameIndex = class_name_index; + className = cp.getConstantPool().getConstantString(class_name_index, Const.CONSTANT_Class).replace('/', '.'); } public void setSuperclassNameIndex( final int superclass_name_index ) { this.superclass_name_index = superclass_name_index; - super_class_name = cp.getConstantPool().getConstantString(superclass_name_index, + superClassName = cp.getConstantPool().getConstantString(superclass_name_index, Const.CONSTANT_Class).replace('/', '.'); } @@ -520,7 +520,7 @@ public int getClassNameIndex() { - return class_name_index; + return classNameIndex; } private List<ClassObserver> observers; @@ -572,7 +572,7 @@ * @return Comparison strategy object */ public static BCELComparator getComparator() { - return _cmp; + return bcelComparator; } @@ -580,7 +580,7 @@ * @param comparator Comparison strategy object */ public static void setComparator( final BCELComparator comparator ) { - _cmp = comparator; + bcelComparator = comparator; } @@ -593,7 +593,7 @@ */ @Override public boolean equals( final Object obj ) { - return _cmp.equals(this, obj); + return bcelComparator.equals(this, obj); } @@ -605,6 +605,6 @@ */ @Override public int hashCode() { - return _cmp.hashCode(this); + return bcelComparator.hashCode(this); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java index 1915d927..de1a31d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java
@@ -37,27 +37,27 @@ */ public final class CodeExceptionGen implements InstructionTargeter, Cloneable { - private InstructionHandle start_pc; - private InstructionHandle end_pc; - private InstructionHandle handler_pc; - private ObjectType catch_type; + private InstructionHandle startPc; + private InstructionHandle endPc; + private InstructionHandle handlerPc; + private ObjectType catchType; /** * Add an exception handler, i.e., specify region where a handler is active and an * instruction where the actual handling is done. * - * @param start_pc Start of handled region (inclusive) - * @param end_pc End of handled region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type which exception is handled, null for ANY + * @param startPc Start of handled region (inclusive) + * @param endPc End of handled region (inclusive) + * @param handlerPc Where handling is done + * @param catchType which exception is handled, null for ANY */ - public CodeExceptionGen(final InstructionHandle start_pc, final InstructionHandle end_pc, - final InstructionHandle handler_pc, final ObjectType catch_type) { - setStartPC(start_pc); - setEndPC(end_pc); - setHandlerPC(handler_pc); - this.catch_type = catch_type; + public CodeExceptionGen(final InstructionHandle startPc, final InstructionHandle endPc, + final InstructionHandle handlerPc, final ObjectType catchType) { + setStartPC(startPc); + setEndPC(endPc); + setHandlerPC(handlerPc); + this.catchType = catchType; } @@ -71,36 +71,36 @@ * @param cp constant pool */ public CodeException getCodeException( final ConstantPoolGen cp ) { - return new CodeException(start_pc.getPosition(), end_pc.getPosition() - + end_pc.getInstruction().getLength(), handler_pc.getPosition(), - (catch_type == null) ? 0 : cp.addClass(catch_type)); + return new CodeException(startPc.getPosition(), endPc.getPosition() + + endPc.getInstruction().getLength(), handlerPc.getPosition(), + (catchType == null) ? 0 : cp.addClass(catchType)); } /* Set start of handler - * @param start_pc Start of handled region (inclusive) + * @param startPc Start of handled region (inclusive) */ public void setStartPC( final InstructionHandle start_pc ) { // TODO could be package-protected? - BranchInstruction.notifyTarget(this.start_pc, start_pc, this); - this.start_pc = start_pc; + BranchInstruction.notifyTarget(this.startPc, start_pc, this); + this.startPc = start_pc; } /* Set end of handler - * @param end_pc End of handled region (inclusive) + * @param endPc End of handled region (inclusive) */ public void setEndPC( final InstructionHandle end_pc ) { // TODO could be package-protected? - BranchInstruction.notifyTarget(this.end_pc, end_pc, this); - this.end_pc = end_pc; + BranchInstruction.notifyTarget(this.endPc, end_pc, this); + this.endPc = end_pc; } /* Set handler code - * @param handler_pc Start of handler + * @param handlerPc Start of handler */ public void setHandlerPC( final InstructionHandle handler_pc ) { // TODO could be package-protected? - BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this); - this.handler_pc = handler_pc; + BranchInstruction.notifyTarget(this.handlerPc, handler_pc, this); + this.handlerPc = handler_pc; } @@ -111,21 +111,21 @@ @Override public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { boolean targeted = false; - if (start_pc == old_ih) { + if (startPc == old_ih) { targeted = true; setStartPC(new_ih); } - if (end_pc == old_ih) { + if (endPc == old_ih) { targeted = true; setEndPC(new_ih); } - if (handler_pc == old_ih) { + if (handlerPc == old_ih) { targeted = true; setHandlerPC(new_ih); } if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " - + end_pc + ", " + handler_pc + "}"); + throw new ClassGenException("Not targeting " + old_ih + ", but {" + startPc + ", " + + endPc + ", " + handlerPc + "}"); } } @@ -135,46 +135,46 @@ */ @Override public boolean containsTarget( final InstructionHandle ih ) { - return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); + return (startPc == ih) || (endPc == ih) || (handlerPc == ih); } /** Sets the type of the Exception to catch. Set 'null' for ANY. */ - public void setCatchType( final ObjectType catch_type ) { - this.catch_type = catch_type; + public void setCatchType( final ObjectType catchType ) { + this.catchType = catchType; } /** Gets the type of the Exception to catch, 'null' for ANY. */ public ObjectType getCatchType() { - return catch_type; + return catchType; } /** @return start of handled region (inclusive) */ public InstructionHandle getStartPC() { - return start_pc; + return startPc; } /** @return end of handled region (inclusive) */ public InstructionHandle getEndPC() { - return end_pc; + return endPc; } /** @return start of handler */ public InstructionHandle getHandlerPC() { - return handler_pc; + return handlerPc; } @Override public String toString() { - return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; + return "CodeExceptionGen(" + startPc + ", " + endPc + ", " + handlerPc + ")"; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java index b430b6e..a1dadbf 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -50,7 +50,7 @@ * JVM and that Double and Long constants need two slots. * * @see Constant - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class ConstantPoolGen { @@ -98,15 +98,15 @@ final ConstantString s = (ConstantString) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; final String key = u8.getBytes(); - if (!string_table.containsKey(key)) { - string_table.put(key, new Index(i)); + if (!stringTable.containsKey(key)) { + stringTable.put(key, new Index(i)); } } else if (c instanceof ConstantClass) { final ConstantClass s = (ConstantClass) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; final String key = u8.getBytes(); - if (!class_table.containsKey(key)) { - class_table.put(key, new Index(i)); + if (!classTable.containsKey(key)) { + classTable.put(key, new Index(i)); } } else if (c instanceof ConstantNameAndType) { final ConstantNameAndType n = (ConstantNameAndType) c; @@ -119,14 +119,14 @@ final String key = sb.toString(); sb.delete(0, sb.length()); - if (!n_a_t_table.containsKey(key)) { - n_a_t_table.put(key, new Index(i)); + if (!natTable.containsKey(key)) { + natTable.put(key, new Index(i)); } } else if (c instanceof ConstantUtf8) { final ConstantUtf8 u = (ConstantUtf8) c; final String key = u.getBytes(); - if (!utf8_table.containsKey(key)) { - utf8_table.put(key, new Index(i)); + if (!utf8Table.containsKey(key)) { + utf8Table.put(key, new Index(i)); } } else if (c instanceof ConstantCP) { final ConstantCP m = (ConstantCP) c; @@ -164,8 +164,8 @@ final String key = sb.toString(); sb.delete(0, sb.length()); - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(i)); + if (!cpTable.containsKey(key)) { + cpTable.put(key, new Index(i)); } } else if (c == null) { // entries may be null // nothing to do @@ -220,7 +220,7 @@ } } - private final Map<String, Index> string_table = new HashMap<>(); + private final Map<String, Index> stringTable = new HashMap<>(); /** @@ -230,7 +230,7 @@ * @return index on success, -1 otherwise */ public int lookupString( final String str ) { - final Index index = string_table.get(str); + final Index index = stringTable.get(str); return (index != null) ? index.index : -1; } @@ -251,13 +251,13 @@ final ConstantString s = new ConstantString(utf8); ret = index; constants[index++] = s; - if (!string_table.containsKey(str)) { - string_table.put(str, new Index(ret)); + if (!stringTable.containsKey(str)) { + stringTable.put(str, new Index(ret)); } return ret; } - private final Map<String, Index> class_table = new HashMap<>(); + private final Map<String, Index> classTable = new HashMap<>(); /** @@ -267,7 +267,7 @@ * @return index on success, -1 otherwise */ public int lookupClass( final String str ) { - final Index index = class_table.get(str.replace('.', '/')); + final Index index = classTable.get(str.replace('.', '/')); return (index != null) ? index.index : -1; } @@ -281,8 +281,8 @@ final ConstantClass c = new ConstantClass(addUtf8(clazz)); ret = index; constants[index++] = c; - if (!class_table.containsKey(clazz)) { - class_table.put(clazz, new Index(ret)); + if (!classTable.containsKey(clazz)) { + classTable.put(clazz, new Index(ret)); } return ret; } @@ -396,7 +396,7 @@ return ret; } - private final Map<String, Index> utf8_table = new HashMap<>(); + private final Map<String, Index> utf8Table = new HashMap<>(); /** @@ -406,7 +406,7 @@ * @return index on success, -1 otherwise */ public int lookupUtf8( final String n ) { - final Index index = utf8_table.get(n); + final Index index = utf8Table.get(n); return (index != null) ? index.index : -1; } @@ -425,8 +425,8 @@ adjustSize(); ret = index; constants[index++] = new ConstantUtf8(n); - if (!utf8_table.containsKey(n)) { - utf8_table.put(n, new Index(ret)); + if (!utf8Table.containsKey(n)) { + utf8Table.put(n, new Index(ret)); } return ret; } @@ -508,7 +508,7 @@ return ret; } - private final Map<String, Index> n_a_t_table = new HashMap<>(); + private final Map<String, Index> natTable = new HashMap<>(); /** @@ -519,7 +519,7 @@ * @return index on success, -1 otherwise */ public int lookupNameAndType( final String name, final String signature ) { - final Index _index = n_a_t_table.get(name + NAT_DELIM + signature); + final Index _index = natTable.get(name + NAT_DELIM + signature); return (_index != null) ? _index.index : -1; } @@ -545,13 +545,13 @@ ret = index; constants[index++] = new ConstantNameAndType(name_index, signature_index); final String key = name + NAT_DELIM + signature; - if (!n_a_t_table.containsKey(key)) { - n_a_t_table.put(key, new Index(ret)); + if (!natTable.containsKey(key)) { + natTable.put(key, new Index(ret)); } return ret; } - private final Map<String, Index> cp_table = new HashMap<>(); + private final Map<String, Index> cpTable = new HashMap<>(); /** @@ -563,7 +563,7 @@ * @return index on success, -1 otherwise */ public int lookupMethodref( final String class_name, final String method_name, final String signature ) { - final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name + final Index index = cpTable.get(class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature); return (index != null) ? index.index : -1; } @@ -596,8 +596,8 @@ ret = index; constants[index++] = new ConstantMethodref(class_index, name_and_type_index); final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(ret)); + if (!cpTable.containsKey(key)) { + cpTable.put(key, new Index(ret)); } return ret; } @@ -617,7 +617,7 @@ * @return index on success, -1 otherwise */ public int lookupInterfaceMethodref( final String class_name, final String method_name, final String signature ) { - final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name + final Index index = cpTable.get(class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature); return (index != null) ? index.index : -1; } @@ -651,8 +651,8 @@ ret = index; constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(ret)); + if (!cpTable.containsKey(key)) { + cpTable.put(key, new Index(ret)); } return ret; } @@ -672,7 +672,7 @@ * @return index on success, -1 otherwise */ public int lookupFieldref( final String class_name, final String field_name, final String signature ) { - final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name + final Index index = cpTable.get(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature); return (index != null) ? index.index : -1; } @@ -700,8 +700,8 @@ ret = index; constants[index++] = new ConstantFieldref(class_index, name_and_type_index); final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(ret)); + if (!cpTable.containsKey(key)) { + cpTable.put(key, new Index(ret)); } return ret; } @@ -817,11 +817,11 @@ case Const.CONSTANT_Fieldref: return addFieldref(class_name, name, signature); default: // Never reached - throw new RuntimeException("Unknown constant type " + c); + throw new IllegalArgumentException("Unknown constant type " + c); } } default: // Never reached - throw new RuntimeException("Unknown constant type " + c); + throw new IllegalArgumentException("Unknown constant type " + c); } } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java index 0e730e6..cebc7c4 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -34,7 +34,7 @@ /** * @since 6.0 - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public abstract class ElementValueGen { @@ -141,7 +141,7 @@ } return new ArrayElementValueGen(ARRAY, evalues, cpGen); default: - throw new RuntimeException("Unexpected element value kind in annotation: " + type); + throw new IllegalArgumentException("Unexpected element value kind in annotation: " + type); } } @@ -183,7 +183,7 @@ return new ClassElementValueGen((ClassElementValue) value, cpool, copyPoolEntries); default: - throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); + throw new UnsupportedOperationException("Not implemented yet! (" + value.getElementValueType() + ")"); } } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java index 5a92837..218ea89 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java
@@ -37,19 +37,19 @@ private final ElementValueGen value; - private final ConstantPoolGen cpool; + private final ConstantPoolGen constantPoolGen; public ElementValuePairGen(final ElementValuePair nvp, final ConstantPoolGen cpool, final boolean copyPoolEntries) { - this.cpool = cpool; + this.constantPoolGen = cpool; // J5ASSERT: // Could assert nvp.getNameString() points to the same thing as - // cpool.getConstant(nvp.getNameIndex()) + // constantPoolGen.getConstant(nvp.getNameIndex()) // if - // (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) + // (!nvp.getNameString().equals(((ConstantUtf8)constantPoolGen.getConstant(nvp.getNameIndex())).getBytes())) // { - // throw new RuntimeException("envp buggered"); + // throw new IllegalArgumentException("envp buggered"); // } if (copyPoolEntries) { @@ -68,7 +68,7 @@ public ElementValuePair getElementNameValuePair() { final ElementValue immutableValue = value.getElementValue(); - return new ElementValuePair(nameIdx, immutableValue, cpool + return new ElementValuePair(nameIdx, immutableValue, constantPoolGen .getConstantPool()); } @@ -77,7 +77,7 @@ { this.nameIdx = idx; this.value = value; - this.cpool = cpool; + this.constantPoolGen = cpool; } public ElementValuePairGen(final String name, final ElementValueGen value, @@ -85,7 +85,7 @@ { this.nameIdx = cpool.addUtf8(name); this.value = value; - this.cpool = cpool; + this.constantPoolGen = cpool; } protected void dump(final DataOutputStream dos) throws IOException @@ -101,8 +101,8 @@ public final String getNameString() { - // ConstantString cu8 = (ConstantString)cpool.getConstant(nameIdx); - return ((ConstantUtf8) cpool.getConstant(nameIdx)).getBytes(); + // ConstantString cu8 = (ConstantString)constantPoolGen.getConstant(nameIdx); + return ((ConstantUtf8) constantPoolGen.getConstant(nameIdx)).getBytes(); } public final ElementValueGen getValue()
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java index ae2746e..1395852 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java
@@ -48,7 +48,7 @@ { super(ElementValueGen.ENUM_CONSTANT, cpool); if (super.getElementValueType() != ENUM_CONSTANT) { - throw new RuntimeException( + throw new IllegalArgumentException( "Only element values of type enum can be built with this ctor - type specified: " + super.getElementValueType()); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java index 1e5e861..78af8b6 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -41,7 +41,7 @@ * course be compatible with to the declared type). * * @see Field - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class FieldGen extends FieldGenOrMethodGen { @@ -255,7 +255,7 @@ case Const.T_REFERENCE: return super.getConstantPool().addString((String) value); default: - throw new RuntimeException("Oops: Unhandled : " + super.getType().getType()); // sic + throw new IllegalStateException("Unhandled : " + super.getType().getType()); // sic } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java index e0e07ee..1c2e37f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -30,7 +30,7 @@ * Super class for FieldGen and MethodGen objects, since they have * some methods in common! * - * @LastModified: Jun 2020 + * @LastModified: May 2021 */ public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable { @@ -38,10 +38,10 @@ private Type type; private ConstantPoolGen cp; - private final List<Attribute> attribute_vec = new ArrayList<>(); + private final List<Attribute> attributeList = new ArrayList<>(); // @since 6.0 - private final List<AnnotationEntryGen> annotation_vec= new ArrayList<>(); + private final List<AnnotationEntryGen> annotationList = new ArrayList<>(); protected FieldGenOrMethodGen() { @@ -103,15 +103,15 @@ * @param a attribute to be added */ public void addAttribute( final Attribute a ) { - attribute_vec.add(a); + attributeList.add(a); } /** * @since 6.0 */ - protected void addAnnotationEntry(final AnnotationEntryGen ag) // TODO could this be package protected? + public void addAnnotationEntry(final AnnotationEntryGen ag) { - annotation_vec.add(ag); + annotationList.add(ag); } @@ -119,15 +119,15 @@ * Remove an attribute. */ public void removeAttribute( final Attribute a ) { - attribute_vec.remove(a); + attributeList.remove(a); } /** * @since 6.0 */ - protected void removeAnnotationEntry(final AnnotationEntryGen ag) // TODO could this be package protected? + public void removeAnnotationEntry(final AnnotationEntryGen ag) { - annotation_vec.remove(ag); + annotationList.remove(ag); } @@ -135,15 +135,15 @@ * Remove all attributes. */ public void removeAttributes() { - attribute_vec.clear(); + attributeList.clear(); } /** * @since 6.0 */ - protected void removeAnnotationEntries() // TODO could this be package protected? + public void removeAnnotationEntries() { - annotation_vec.clear(); + annotationList.clear(); } @@ -151,15 +151,11 @@ * @return all attributes of this method. */ public Attribute[] getAttributes() { - final Attribute[] attributes = new Attribute[attribute_vec.size()]; - attribute_vec.toArray(attributes); - return attributes; + return attributeList.toArray(new Attribute[0]); } public AnnotationEntryGen[] getAnnotationEntries() { - final AnnotationEntryGen[] annotations = new AnnotationEntryGen[annotation_vec.size()]; - annotation_vec.toArray(annotations); - return annotations; + return annotationList.toArray(new AnnotationEntryGen[0]); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java index 46f026c..d6bac98 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -36,10 +36,10 @@ * mechanism entirely. * * @see - * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic"> + * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic"> * The invokedynamic instruction in The Java Virtual Machine Specification</a> * @since 6.0 - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class INVOKEDYNAMIC extends InvokeInstruction {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java index 6f1736c..4953abd 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java
@@ -34,7 +34,7 @@ * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -> ...</PRE> * * @see - * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface"> + * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface"> * The invokeinterface instruction in The Java Virtual Machine Specification</a> */ public final class INVOKEINTERFACE extends InvokeInstruction {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java index d3eed22..ce27d07 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java
@@ -34,7 +34,7 @@ * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -> ...</PRE> * * @see - * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial"> + * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial"> * The invokespecial instruction in The Java Virtual Machine Specification</a> */ public class INVOKESPECIAL extends InvokeInstruction {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java index 356e131..a897025 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java
@@ -33,7 +33,7 @@ * <PRE>Stack: ..., [arg1, [arg2 ...]] -> ...</PRE> * * @see - * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic"> + * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic"> * The invokestatic instruction in The Java Virtual Machine Specification</a> */ public class INVOKESTATIC extends InvokeInstruction {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java index a9652fd..bd5a2b5 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java
@@ -33,7 +33,7 @@ * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -> ...</PRE> * * @see - * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual"> + * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual"> * The invokevirtual instruction in The Java Virtual Machine Specification</a> */ public class INVOKEVIRTUAL extends InvokeInstruction {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java index bb78cb9..d2ec08e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,7 +32,7 @@ * * @see Const * @see InstructionConst - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class InstructionFactory { @@ -76,30 +76,52 @@ */ public InvokeInstruction createInvoke( final String class_name, final String name, final Type ret_type, final Type[] arg_types, final short kind ) { + return createInvoke(class_name, name, ret_type, arg_types, kind, kind == Const.INVOKEINTERFACE); + } + + /** + * Creates an invoke instruction. (Except for invokedynamic.) + * + * @param class_name name of the called class + * @param name name of the called method + * @param ret_type return type of method + * @param arg_types argument types of method + * @param kind how to invoke: INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL + * @param use_interface force use of InterfaceMethodref + * @return A new InvokeInstruction. + * @since 6.5.0 + */ + public InvokeInstruction createInvoke( final String class_name, final String name, final Type ret_type, + final Type[] arg_types, final short kind, final boolean use_interface) { + if (kind != Const.INVOKESPECIAL && kind != Const.INVOKEVIRTUAL && kind != Const.INVOKESTATIC + && kind != Const.INVOKEINTERFACE && kind != Const.INVOKEDYNAMIC) { + throw new IllegalArgumentException("Unknown invoke kind: " + kind); + } int index; int nargs = 0; final String signature = Type.getMethodSignature(ret_type, arg_types); for (final Type arg_type : arg_types) { nargs += arg_type.getSize(); } - if (kind == Const.INVOKEINTERFACE) { + if (use_interface) { index = cp.addInterfaceMethodref(class_name, name, signature); } else { index = cp.addMethodref(class_name, name, signature); } switch (kind) { - case Const.INVOKESPECIAL: - return new INVOKESPECIAL(index); - case Const.INVOKEVIRTUAL: - return new INVOKEVIRTUAL(index); - case Const.INVOKESTATIC: - return new INVOKESTATIC(index); - case Const.INVOKEINTERFACE: - return new INVOKEINTERFACE(index, nargs + 1); - case Const.INVOKEDYNAMIC: - return new INVOKEDYNAMIC(index); - default: - throw new RuntimeException("Oops: Unknown invoke kind: " + kind); + case Const.INVOKESPECIAL: + return new INVOKESPECIAL(index); + case Const.INVOKEVIRTUAL: + return new INVOKEVIRTUAL(index); + case Const.INVOKESTATIC: + return new INVOKESTATIC(index); + case Const.INVOKEINTERFACE: + return new INVOKEINTERFACE(index, nargs + 1); + case Const.INVOKEDYNAMIC: + return new INVOKEDYNAMIC(index); + default: + // Can't happen + throw new IllegalStateException("Unknown invoke kind: " + kind); } } @@ -248,7 +270,7 @@ case Const.T_OBJECT: return createInvoke(append_mos[1], Const.INVOKEVIRTUAL); default: - throw new RuntimeException("Oops: No append for this type? " + type); + throw new IllegalArgumentException("No append for this type? " + type); } } @@ -276,7 +298,7 @@ case Const.PUTSTATIC: return new PUTSTATIC(index); default: - throw new RuntimeException("Oops: Unknown getfield kind:" + kind); + throw new IllegalArgumentException("Unknown getfield kind:" + kind); } } @@ -310,7 +332,7 @@ case Const.T_VOID: return InstructionConst.RETURN; default: - throw new RuntimeException("Invalid type: " + type); + throw new IllegalArgumentException("Invalid type: " + type); } } @@ -338,7 +360,7 @@ case '>': return op.equals(">>>") ? InstructionConst.IUSHR : InstructionConst.ISHR; default: - throw new RuntimeException("Invalid operand " + op); + throw new IllegalArgumentException("Invalid operand " + op); } } @@ -366,7 +388,7 @@ case '>': return op.equals(">>>") ? InstructionConst.LUSHR : InstructionConst.LSHR; default: - throw new RuntimeException("Invalid operand " + op); + throw new IllegalArgumentException("Invalid operand " + op); } } @@ -384,7 +406,7 @@ case '%': return InstructionConst.FREM; default: - throw new RuntimeException("Invalid operand " + op); + throw new IllegalArgumentException("Invalid operand " + op); } } @@ -402,7 +424,7 @@ case '%': return InstructionConst.DREM; default: - throw new RuntimeException("Invalid operand " + op); + throw new IllegalArgumentException("Invalid operand " + op); } } @@ -427,7 +449,7 @@ case Const.T_DOUBLE: return createBinaryDoubleOp(first); default: - throw new RuntimeException("Invalid type " + type); + throw new IllegalArgumentException("Invalid type " + type); } } @@ -485,7 +507,7 @@ case Const.T_OBJECT: return new ASTORE(index); default: - throw new RuntimeException("Invalid type " + type); + throw new IllegalArgumentException("Invalid type " + type); } } @@ -511,7 +533,7 @@ case Const.T_OBJECT: return new ALOAD(index); default: - throw new RuntimeException("Invalid type " + type); + throw new IllegalArgumentException("Invalid type " + type); } } @@ -540,7 +562,7 @@ case Const.T_OBJECT: return InstructionConst.AALOAD; default: - throw new RuntimeException("Invalid type " + type); + throw new IllegalArgumentException("Invalid type " + type); } } @@ -569,7 +591,7 @@ case Const.T_OBJECT: return InstructionConst.AASTORE; default: - throw new RuntimeException("Invalid type " + type); + throw new IllegalArgumentException("Invalid type " + type); } } @@ -592,7 +614,7 @@ try { i = (Instruction) java.lang.Class.forName(name).getDeclaredConstructor().newInstance(); } catch (final Exception e) { - throw new RuntimeException("Could not find instruction: " + name, e); + throw new IllegalArgumentException("Could not find instruction: " + name, e); } return i; } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { @@ -601,7 +623,7 @@ } return new CHECKCAST(cp.addClass(((ObjectType) dest_type).getClassName())); } else { - throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); + throw new IllegalArgumentException("Cannot cast " + src_type + " to " + dest_type); } } @@ -699,7 +721,7 @@ case Const.T_VOID: return InstructionConst.NOP; default: - throw new RuntimeException("Invalid type: " + type); + throw new IllegalArgumentException("Invalid type: " + type); } } @@ -751,7 +773,7 @@ case Const.JSR_W: return new JSR_W(target); default: - throw new RuntimeException("Invalid opcode: " + opcode); + throw new IllegalArgumentException("Invalid opcode: " + opcode); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java index 25008e6..bdf7802 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,7 +42,7 @@ * @see Instruction * @see BranchHandle * @see InstructionList - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class InstructionHandle { @@ -295,7 +295,7 @@ /** * @param next the next to set - * @ since 6.0 + * @since 6.0 */ final InstructionHandle setNext(final InstructionHandle next) { this.next = next; @@ -305,7 +305,7 @@ /** * @param prev the prev to set - * @ since 6.0 + * @since 6.0 */ final InstructionHandle setPrev(final InstructionHandle prev) { this.prev = prev;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java index 0e90723..28c5322 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -47,14 +47,14 @@ * @see Instruction * @see InstructionHandle * @see BranchHandle - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class InstructionList implements Iterable<InstructionHandle> { private InstructionHandle start = null; private InstructionHandle end = null; private int length = 0; // number of elements in list - private int[] byte_positions; // byte code offsets corresponding to instructions + private int[] bytePositions; // byte code offsets corresponding to instructions /** * Create (empty) instruction list. @@ -145,7 +145,7 @@ * @return target position's instruction handle if available */ public InstructionHandle findHandle(final int pos) { - final int[] positions = byte_positions; + final int[] positions = bytePositions; InstructionHandle ih = start; for (int i = 0; i < length; i++) { if (positions[i] == pos) { @@ -193,8 +193,8 @@ } catch (final IOException e) { throw new ClassGenException(e.toString(), e); } - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); + bytePositions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, bytePositions, 0, count); /* * Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles. */ @@ -204,7 +204,7 @@ int target = bi.getPosition() + bi.getIndex(); /* * Byte code position: relative -> absolute. - */ + */ // Search for target position InstructionHandle ih = findHandle(ihs, pos, count, target); if (ih == null) { @@ -797,10 +797,8 @@ } /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be - * reused! + * Remove instructions from instruction `from' to instruction `to' contained in this list. The user must ensure that `from' is an instruction before `to', + * or risk havoc. The corresponding Instruction handles must not be reused! * * @param from * where to start deleting (inclusive) @@ -960,8 +958,8 @@ pos[count++] = index; index += i.getLength(); } - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); + bytePositions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, bytePositions, 0, count); } /** @@ -1074,7 +1072,7 @@ * @return array containing all instruction's offset in byte code */ public int[] getInstructionPositions() { - return byte_positions; + return bytePositions; } /**
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java index b679d6b..f999d5c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java
@@ -74,7 +74,7 @@ while (ih != null) { ih = ih.getNext(); if ((ih != null) && (ih.getInstruction() == this)) { - throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); + throw new IllegalStateException("physicalSuccessor() called on a shared JsrInstruction."); } } // Return the physical successor
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java index 3b7ceec..92c490a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * * <PRE>Stack: ... -> ..., item</PRE> * - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower { @@ -112,7 +112,7 @@ c = cpg.getConstantPool().getConstant(nameIndex); return new ObjectType(((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes()); default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); } } @@ -129,7 +129,7 @@ case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: return Type.CLASS; default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java index 544b879..ade9b29 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -25,7 +25,7 @@ * * <PRE>Stack: ... -> ..., item.word1, item.word2</PRE> * - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class LDC2_W extends CPInstruction implements PushInstruction { @@ -50,7 +50,7 @@ case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: return Type.DOUBLE; default: // Never reached - throw new RuntimeException("Unknown constant type " + super.getOpcode()); + throw new IllegalArgumentException("Unknown constant type " + super.getOpcode()); } } @@ -63,7 +63,7 @@ case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: return ((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes(); default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java index a9ab4a8..b5ac6cd 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java
@@ -21,6 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; +import java.util.Objects; + import com.sun.org.apache.bcel.internal.classfile.LineNumber; /** @@ -33,8 +35,7 @@ public class LineNumberGen implements InstructionTargeter, Cloneable { private InstructionHandle ih; - private int src_line; - + private int srcLine; /** * Create a line number. @@ -76,16 +77,14 @@ * or that the `setPositions' methods has been called for the instruction list. */ public LineNumber getLineNumber() { - return new LineNumber(ih.getPosition(), src_line); + return new LineNumber(ih.getPosition(), srcLine); } - public void setInstruction( final InstructionHandle ih ) { // TODO could be package-protected? - if (ih == null) { - throw new NullPointerException("InstructionHandle may not be null"); - } - BranchInstruction.notifyTarget(this.ih, ih, this); - this.ih = ih; + public void setInstruction( final InstructionHandle instructionHandle ) { // TODO could be package-protected? + Objects.requireNonNull(instructionHandle, "instructionHandle"); + BranchInstruction.notifyTarget(this.ih, instructionHandle, this); + this.ih = instructionHandle; } @@ -105,11 +104,11 @@ public void setSourceLine( final int src_line ) { // TODO could be package-protected? - this.src_line = src_line; + this.srcLine = src_line; } public int getSourceLine() { - return src_line; + return srcLine; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java index 57961f3..4693af7 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
@@ -39,8 +39,8 @@ private Type type; private InstructionHandle start; private InstructionHandle end; - private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries - private boolean live_to_end; + private int origIndex; // never changes; used to match up with LocalVariableTypeTable entries + private boolean liveToEnd; /** @@ -63,8 +63,8 @@ this.index = index; setStart(start); setEnd(end); - this.orig_index = index; - this.live_to_end = end == null; + this.origIndex = index; + this.liveToEnd = end == null; } @@ -77,12 +77,12 @@ * @param type its type * @param start from where the instruction is valid (null means from the start) * @param end until where the instruction is valid (null means to the end) - * @param orig_index index of local variable prior to any changes to index + * @param origIndex index of local variable prior to any changes to index */ public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start, - final InstructionHandle end, final int orig_index) { + final InstructionHandle end, final int origIndex) { this(index, name, type, start, end); - this.orig_index = orig_index; + this.origIndex = origIndex; } @@ -95,7 +95,7 @@ * Note that due to the conversion from byte code offset to InstructionHandle, * it is impossible to tell the difference between a live range that ends BEFORE * the last insturction of the method or a live range that ends AFTER the last - * instruction of the method. Hence the live_to_end flag to differentiate + * instruction of the method. Hence the liveToEnd flag to differentiate * between these two cases. * * @param cp constant pool @@ -106,14 +106,14 @@ if ((start != null) && (end != null)) { start_pc = start.getPosition(); length = end.getPosition() - start_pc; - if ((end.getNext() == null) && live_to_end) { + if ((end.getNext() == null) && liveToEnd) { length += end.getInstruction().getLength(); } } final int name_index = cp.addUtf8(name); final int signature_index = cp.addUtf8(type.getSignature()); return new LocalVariable(start_pc, length, name_index, signature_index, index, cp - .getConstantPool(), orig_index); + .getConstantPool(), origIndex); } @@ -128,17 +128,17 @@ public int getOrigIndex() { - return orig_index; + return origIndex; } public void setLiveToEnd( final boolean live_to_end) { - this.live_to_end = live_to_end; + this.liveToEnd = live_to_end; } public boolean getLiveToEnd() { - return live_to_end; + return liveToEnd; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java index 5f009b2..fb4d754 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -28,14 +28,14 @@ /** * Abstract super class for instructions dealing with local variables. * - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction, IndexedInstruction { private int n = -1; // index of referenced variable - private short c_tag = -1; // compact version, such as ILOAD_0 - private short canon_tag = -1; // canonical tag such as ILOAD + private short cTag = -1; // compact version, such as ILOAD_0 + private short canonTag = -1; // canonical tag such as ILOAD private boolean wide() { @@ -50,8 +50,8 @@ */ LocalVariableInstruction(final short canon_tag, final short c_tag) { super(); - this.canon_tag = canon_tag; - this.c_tag = c_tag; + this.canonTag = canon_tag; + this.cTag = c_tag; } @@ -65,13 +65,13 @@ /** * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. + * @param cTag Instruction number for compact version, ALOAD_0, e.g. * @param n local variable index (unsigned short) */ - protected LocalVariableInstruction(final short opcode, final short c_tag, final int n) { + protected LocalVariableInstruction(final short opcode, final short cTag, final int n) { super(opcode, (short) 2); - this.c_tag = c_tag; - canon_tag = opcode; + this.cTag = cTag; + canonTag = opcode; setIndex(n); } @@ -167,10 +167,10 @@ this.n = n; // Cannot be < 0 as this is checked above if (n <= 3) { // Use more compact instruction xLOAD_n - super.setOpcode((short) (c_tag + n)); + super.setOpcode((short) (cTag + n)); super.setLength(1); } else { - super.setOpcode(canon_tag); + super.setOpcode(canonTag); if (wide()) { super.setLength(4); } else { @@ -183,7 +183,7 @@ /** @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 */ public short getCanonicalTag() { - return canon_tag; + return canonTag; } @@ -197,7 +197,7 @@ */ @Override public Type getType( final ConstantPoolGen cp ) { - switch (canon_tag) { + switch (canonTag) { case Const.ILOAD: case Const.ISTORE: return Type.INT; @@ -214,7 +214,7 @@ case Const.ASTORE: return Type.OBJECT; default: - throw new ClassGenException("Oops: unknown case in switch" + canon_tag); + throw new ClassGenException("Unknown case in switch" + canonTag); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java index 478082c..f787b44 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -57,25 +57,25 @@ * * @see InstructionList * @see Method - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class MethodGen extends FieldGenOrMethodGen { - private String class_name; - private Type[] arg_types; - private String[] arg_names; - private int max_locals; - private int max_stack; + private String className; + private Type[] argTypes; + private String[] argNames; + private int maxLocals; + private int maxStack; private InstructionList il; - private boolean strip_attributes; - private LocalVariableTypeTable local_variable_type_table = null; - private final List<LocalVariableGen> variable_vec = new ArrayList<>(); - private final List<LineNumberGen> line_number_vec = new ArrayList<>(); - private final List<CodeExceptionGen> exception_vec = new ArrayList<>(); - private final List<String> throws_vec = new ArrayList<>(); - private final List<Attribute> code_attrs_vec = new ArrayList<>(); + private boolean stripAttributes; + private LocalVariableTypeTable localVariableTypeTable = null; + private final List<LocalVariableGen> variableList = new ArrayList<>(); + private final List<LineNumberGen> lineNumberList = new ArrayList<>(); + private final List<CodeExceptionGen> exceptionList = new ArrayList<>(); + private final List<String> throwsList = new ArrayList<>(); + private final List<Attribute> codeAttrsList = new ArrayList<>(); - private List<AnnotationEntryGen>[] param_annotations; // Array of lists containing AnnotationGen objects + private List<AnnotationEntryGen>[] paramAnnotations; // Array of lists containing AnnotationGen objects private boolean hasParameterAnnotations = false; private boolean haveUnpackedParameterAnnotations = false; @@ -111,23 +111,23 @@ * * @param access_flags access qualifiers * @param return_type method type - * @param arg_types argument types - * @param arg_names argument names (if this is null, default names will be provided + * @param argTypes argument types + * @param argNames argument names (if this is null, default names will be provided * for them) * @param method_name name of method - * @param class_name class name containing this method (may be null, if you don't care) + * @param className class name containing this method (may be null, if you don't care) * @param il instruction list associated with this method, may be null only for * abstract or native methods * @param cp constant pool */ - public MethodGen(final int access_flags, final Type return_type, final Type[] arg_types, String[] arg_names, - final String method_name, final String class_name, final InstructionList il, final ConstantPoolGen cp) { + public MethodGen(final int access_flags, final Type return_type, final Type[] argTypes, String[] argNames, + final String method_name, final String className, final InstructionList il, final ConstantPoolGen cp) { super(access_flags); setType(return_type); - setArgumentTypes(arg_types); - setArgumentNames(arg_names); + setArgumentTypes(argTypes); + setArgumentNames(argNames); setName(method_name); - setClassName(class_name); + setClassName(className); setInstructionList(il); setConstantPool(cp); final boolean abstract_ = isAbstract() || isNative(); @@ -138,32 +138,32 @@ // end == null => live to end of method /* Add local variables, namely the implicit `this' and the arguments */ - if (!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0 - addLocalVariable("this", ObjectType.getInstance(class_name), start, end); + if (!isStatic() && (className != null)) { // Instance method -> `this' is local var 0 + addLocalVariable("this", ObjectType.getInstance(className), start, end); } } - if (arg_types != null) { - final int size = arg_types.length; - for (final Type arg_type : arg_types) { + if (argTypes != null) { + final int size = argTypes.length; + for (final Type arg_type : argTypes) { if (Type.VOID == arg_type) { throw new ClassGenException("'void' is an illegal argument type for a method"); } } - if (arg_names != null) { // Names for variables provided? - if (size != arg_names.length) { + if (argNames != null) { // Names for variables provided? + if (size != argNames.length) { throw new ClassGenException("Mismatch in argument array lengths: " + size - + " vs. " + arg_names.length); + + " vs. " + argNames.length); } } else { // Give them dummy names - arg_names = new String[size]; + argNames = new String[size]; for (int i = 0; i < size; i++) { - arg_names[i] = "arg" + i; + argNames[i] = "arg" + i; } - setArgumentNames(arg_names); + setArgumentNames(argNames); } if (!abstract_) { for (int i = 0; i < size; i++) { - addLocalVariable(arg_names[i], arg_types[i], start, end); + addLocalVariable(argNames[i], argTypes[i], start, end); } } } @@ -173,18 +173,19 @@ /** * Instantiate from existing method. * - * @param m method - * @param class_name class name containing this method + * @param method method + * @param className class name containing this method * @param cp constant pool */ - public MethodGen(final Method m, final String class_name, final ConstantPoolGen cp) { - this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), Type.getArgumentTypes(m - .getSignature()), null /* may be overridden anyway */ - , m.getName(), class_name, - ((m.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0) - ? new InstructionList(m.getCode().getCode()) - : null, cp); - final Attribute[] attributes = m.getAttributes(); + public MethodGen(final Method method, final String className, final ConstantPoolGen cp) { + this(method.getAccessFlags(), Type.getReturnType(method.getSignature()), + Type.getArgumentTypes(method.getSignature()), null /* may be overridden anyway */ + , method.getName(), className, + ((method.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0) + ? new InstructionList(getByteCodes(method)) + : null, + cp); + final Attribute[] attributes = method.getAttributes(); for (final Attribute attribute : attributes) { Attribute a = attribute; if (a instanceof Code) { @@ -197,12 +198,12 @@ final int type = ce.getCatchType(); ObjectType c_type = null; if (type > 0) { - final String cen = m.getConstantPool().getConstantString(type, + final String cen = method.getConstantPool().getConstantString(type, Const.CONSTANT_Class); c_type = ObjectType.getInstance(cen); } final int end_pc = ce.getEndPC(); - final int length = m.getCode().getCode().length; + final int length = getByteCodes(method).length; InstructionHandle end; if (length == end_pc) { // May happen, because end_pc is exclusive end = il.getEnd(); @@ -210,8 +211,8 @@ end = il.findHandle(end_pc); end = end.getPrev(); // Make it inclusive } - addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce - .getHandlerPC()), c_type); + addExceptionHandler(il.findHandle(ce.getStartPC()), end, + il.findHandle(ce.getHandlerPC()), c_type); } } final Attribute[] c_attributes = c.getAttributes(); @@ -228,7 +229,7 @@ } else if (a instanceof LocalVariableTable) { updateLocalVariableTable((LocalVariableTable) a); } else if (a instanceof LocalVariableTypeTable) { - this.local_variable_type_table = (LocalVariableTypeTable) a.copy(cp.getConstantPool()); + this.localVariableTypeTable = (LocalVariableTypeTable) a.copy(cp.getConstantPool()); } else { addCodeAttribute(a); } @@ -250,6 +251,15 @@ } } + + private static byte[] getByteCodes(final Method method) { + final Code code = method.getCode(); + if (code == null) { + throw new IllegalStateException(String.format("The method '%s' has no code.", method)); + } + return code.getCode(); + } + /** * Adds a local variable to this method. * @@ -268,15 +278,15 @@ final byte t = type.getType(); if (t != Const.T_ADDRESS) { final int add = type.getSize(); - if (slot + add > max_locals) { - max_locals = slot + add; + if (slot + add > maxLocals) { + maxLocals = slot + add; } final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end, orig_index); int i; - if ((i = variable_vec.indexOf(l)) >= 0) { - variable_vec.set(i, l); + if ((i = variableList.indexOf(l)) >= 0) { + variableList.set(i, l); } else { - variable_vec.add(l); + variableList.add(l); } return l; } @@ -316,7 +326,7 @@ */ public LocalVariableGen addLocalVariable( final String name, final Type type, final InstructionHandle start, final InstructionHandle end ) { - return addLocalVariable(name, type, max_locals, start, end); + return addLocalVariable(name, type, maxLocals, start, end); } @@ -325,7 +335,7 @@ * addLocalVariable with an explicit index argument. */ public void removeLocalVariable(final LocalVariableGen l) { - variable_vec.remove(l); + variableList.remove(l); } @@ -333,7 +343,7 @@ * Remove all local variables. */ public void removeLocalVariables() { - variable_vec.clear(); + variableList.clear(); } @@ -344,9 +354,9 @@ * @return array of declared local variables sorted by index */ public LocalVariableGen[] getLocalVariables() { - final int size = variable_vec.size(); + final int size = variableList.size(); final LocalVariableGen[] lg = new LocalVariableGen[size]; - variable_vec.toArray(lg); + variableList.toArray(lg); for (int i = 0; i < size; i++) { if ((lg[i].getStart() == null) && (il != null)) { lg[i].setStart(il.getStart()); @@ -380,7 +390,7 @@ * @return `LocalVariableTypeTable' attribute of this method. */ public LocalVariableTypeTable getLocalVariableTypeTable() { - return local_variable_type_table; + return localVariableTypeTable; } /** @@ -390,9 +400,9 @@ * @return new line number object * @see LineNumber */ - public LineNumberGen addLineNumber( final InstructionHandle ih, final int src_line ) { - final LineNumberGen l = new LineNumberGen(ih, src_line); - line_number_vec.add(l); + public LineNumberGen addLineNumber( final InstructionHandle ih, final int srcLine ) { + final LineNumberGen l = new LineNumberGen(ih, srcLine); + lineNumberList.add(l); return l; } @@ -401,7 +411,7 @@ * Remove a line number. */ public void removeLineNumber( final LineNumberGen l ) { - line_number_vec.remove(l); + lineNumberList.remove(l); } @@ -409,7 +419,7 @@ * Remove all line numbers. */ public void removeLineNumbers() { - line_number_vec.clear(); + lineNumberList.clear(); } @@ -417,8 +427,8 @@ * @return array of line numbers */ public LineNumberGen[] getLineNumbers() { - final LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()]; - line_number_vec.toArray(lg); + final LineNumberGen[] lg = new LineNumberGen[lineNumberList.size()]; + lineNumberList.toArray(lg); return lg; } @@ -427,10 +437,10 @@ * @return `LineNumberTable' attribute of all the local variables of this method. */ public LineNumberTable getLineNumberTable( final ConstantPoolGen cp ) { - final int size = line_number_vec.size(); + final int size = lineNumberList.size(); final LineNumber[] ln = new LineNumber[size]; for (int i = 0; i < size; i++) { - ln[i] = line_number_vec.get(i).getLineNumber(); + ln[i] = lineNumberList.get(i).getLineNumber(); } return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp .getConstantPool()); @@ -454,7 +464,7 @@ throw new ClassGenException("Exception handler target is null instruction"); } final CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type); - exception_vec.add(c); + exceptionList.add(c); return c; } @@ -463,7 +473,7 @@ * Remove an exception handler. */ public void removeExceptionHandler( final CodeExceptionGen c ) { - exception_vec.remove(c); + exceptionList.remove(c); } @@ -471,7 +481,7 @@ * Remove all line numbers. */ public void removeExceptionHandlers() { - exception_vec.clear(); + exceptionList.clear(); } @@ -479,8 +489,8 @@ * @return array of declared exception handlers */ public CodeExceptionGen[] getExceptionHandlers() { - final CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()]; - exception_vec.toArray(cg); + final CodeExceptionGen[] cg = new CodeExceptionGen[exceptionList.size()]; + exceptionList.toArray(cg); return cg; } @@ -489,10 +499,10 @@ * @return code exceptions for `Code' attribute */ private CodeException[] getCodeExceptions() { - final int size = exception_vec.size(); + final int size = exceptionList.size(); final CodeException[] c_exc = new CodeException[size]; for (int i = 0; i < size; i++) { - final CodeExceptionGen c = exception_vec.get(i); + final CodeExceptionGen c = exceptionList.get(i); c_exc[i] = c.getCodeException(super.getConstantPool()); } return c_exc; @@ -502,10 +512,10 @@ /** * Add an exception possibly thrown by this method. * - * @param class_name (fully qualified) name of exception + * @param className (fully qualified) name of exception */ - public void addException( final String class_name ) { - throws_vec.add(class_name); + public void addException( final String className ) { + throwsList.add(className); } @@ -513,7 +523,7 @@ * Remove an exception. */ public void removeException( final String c ) { - throws_vec.remove(c); + throwsList.remove(c); } @@ -521,7 +531,7 @@ * Remove all exceptions. */ public void removeExceptions() { - throws_vec.clear(); + throwsList.clear(); } @@ -529,9 +539,7 @@ * @return array of thrown exceptions */ public String[] getExceptions() { - final String[] e = new String[throws_vec.size()]; - throws_vec.toArray(e); - return e; + return throwsList.toArray(new String[0]); } @@ -539,10 +547,10 @@ * @return `Exceptions' attribute of all the exceptions thrown by this method. */ private ExceptionTable getExceptionTable( final ConstantPoolGen cp ) { - final int size = throws_vec.size(); + final int size = throwsList.size(); final int[] ex = new int[size]; for (int i = 0; i < size; i++) { - ex[i] = cp.addClass(throws_vec.get(i)); + ex[i] = cp.addClass(throwsList.get(i)); } return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp.getConstantPool()); } @@ -558,7 +566,7 @@ * @param a attribute to be added */ public void addCodeAttribute( final Attribute a ) { - code_attrs_vec.add(a); + codeAttrsList.add(a); } @@ -566,14 +574,14 @@ * Remove the LocalVariableTypeTable */ public void removeLocalVariableTypeTable( ) { - local_variable_type_table = null; + localVariableTypeTable = null; } /** * Remove a code attribute. */ public void removeCodeAttribute( final Attribute a ) { - code_attrs_vec.remove(a); + codeAttrsList.remove(a); } @@ -581,8 +589,8 @@ * Remove all code attributes. */ public void removeCodeAttributes() { - local_variable_type_table = null; - code_attrs_vec.clear(); + localVariableTypeTable = null; + codeAttrsList.clear(); } @@ -590,35 +598,63 @@ * @return all attributes of this method. */ public Attribute[] getCodeAttributes() { - final Attribute[] attributes = new Attribute[code_attrs_vec.size()]; - code_attrs_vec.toArray(attributes); - return attributes; + return codeAttrsList.toArray(new Attribute[0]); } /** * @since 6.0 */ public void addAnnotationsAsAttribute(final ConstantPoolGen cp) { - final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); + final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); for (final Attribute attr : attrs) { addAttribute(attr); } - } + } /** * @since 6.0 */ - public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { - if (!hasParameterAnnotations) { - return; - } - final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp,param_annotations); - if (attrs != null) { - for (final Attribute attr : attrs) { - addAttribute(attr); - } - } - } + public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { + if (!hasParameterAnnotations) { + return; + } + final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, paramAnnotations); + if (attrs != null) { + for (final Attribute attr : attrs) { + addAttribute(attr); + } + } + } + + private Attribute[] addRuntimeAnnotationsAsAttribute(final ConstantPoolGen cp) { + final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); + for (final Attribute attr : attrs) { + addAttribute(attr); + } + return attrs; + } + + private Attribute[] addRuntimeParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { + if (!hasParameterAnnotations) { + return new Attribute[0]; + } + final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, paramAnnotations); + for (final Attribute attr : attrs) { + addAttribute(attr); + } + return attrs; + } + + /** + * Would prefer to make this private, but need a way to test if client is + * using BCEL version 6.5.0 or later that contains fix for BCEL-329. + * @since 6.5.0 + */ + public void removeRuntimeAttributes(final Attribute[] attrs) { + for (final Attribute attr : attrs) { + removeAttribute(attr); + } + } /** @@ -642,18 +678,18 @@ LocalVariableTable lvt = null; /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.) */ - if ((variable_vec.size() > 0) && !strip_attributes) { + if ((variableList.size() > 0) && !stripAttributes) { updateLocalVariableTable(getLocalVariableTable(_cp)); addCodeAttribute(lvt = getLocalVariableTable(_cp)); } - if (local_variable_type_table != null) { + if (localVariableTypeTable != null) { // LocalVariable length in LocalVariableTypeTable is not updated automatically. It's a difference with LocalVariableTable. if (lvt != null) { adjustLocalVariableTypeTable(lvt); } - addCodeAttribute(local_variable_type_table); + addCodeAttribute(localVariableTypeTable); } - if ((line_number_vec.size() > 0) && !strip_attributes) { + if ((lineNumberList.size() > 0) && !stripAttributes) { addCodeAttribute(lnt = getLineNumberTable(_cp)); } final Attribute[] code_attrs = getCodeAttributes(); @@ -677,13 +713,13 @@ code = new Code(_cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code 2 + exc_len + // exceptions 2 + attrs_len, // attributes - max_stack, max_locals, byte_code, c_exc, code_attrs, _cp.getConstantPool()); + maxStack, maxLocals, byte_code, c_exc, code_attrs, _cp.getConstantPool()); addAttribute(code); } - addAnnotationsAsAttribute(_cp); - addParameterAnnotationsAsAttribute(_cp); + final Attribute[] annotations = addRuntimeAnnotationsAsAttribute(_cp); + final Attribute[] parameterAnnotations = addRuntimeParameterAnnotationsAsAttribute(_cp); ExceptionTable et = null; - if (throws_vec.size() > 0) { + if (throwsList.size() > 0) { addAttribute(et = getExceptionTable(_cp)); // Add `Exceptions' if there are "throws" clauses } @@ -693,8 +729,8 @@ if (lvt != null) { removeCodeAttribute(lvt); } - if (local_variable_type_table != null) { - removeCodeAttribute(local_variable_type_table); + if (localVariableTypeTable != null) { + removeCodeAttribute(localVariableTypeTable); } if (lnt != null) { removeCodeAttribute(lnt); @@ -705,6 +741,8 @@ if (et != null) { removeAttribute(et); } + removeRuntimeAttributes(annotations); + removeRuntimeAttributes(parameterAnnotations); return m; } @@ -728,7 +766,7 @@ private void adjustLocalVariableTypeTable(final LocalVariableTable lvt) { final LocalVariable[] lv = lvt.getLocalVariableTable(); - final LocalVariable[] lvg = local_variable_type_table.getLocalVariableTypeTable(); + final LocalVariable[] lvg = localVariableTypeTable.getLocalVariableTypeTable(); for (final LocalVariable element : lvg) { for (final LocalVariable l : lv) { @@ -775,12 +813,12 @@ * Set maximum number of local variables. */ public void setMaxLocals( final int m ) { - max_locals = m; + maxLocals = m; } public int getMaxLocals() { - return max_locals; + return maxLocals; } @@ -788,24 +826,24 @@ * Set maximum stack size for this method. */ public void setMaxStack( final int m ) { // TODO could be package-protected? - max_stack = m; + maxStack = m; } public int getMaxStack() { - return max_stack; + return maxStack; } /** @return class that contains this method */ public String getClassName() { - return class_name; + return className; } public void setClassName( final String class_name ) { // TODO could be package-protected? - this.class_name = class_name; + this.className = class_name; } @@ -820,42 +858,42 @@ public void setArgumentTypes( final Type[] arg_types ) { - this.arg_types = arg_types; + this.argTypes = arg_types; } public Type[] getArgumentTypes() { - return arg_types.clone(); + return argTypes.clone(); } public void setArgumentType( final int i, final Type type ) { - arg_types[i] = type; + argTypes[i] = type; } public Type getArgumentType( final int i ) { - return arg_types[i]; + return argTypes[i]; } public void setArgumentNames( final String[] arg_names ) { - this.arg_names = arg_names; + this.argNames = arg_names; } public String[] getArgumentNames() { - return arg_names.clone(); + return argNames.clone(); } public void setArgumentName( final int i, final String name ) { - arg_names[i] = name; + argNames[i] = name; } public String getArgumentName( final int i ) { - return arg_names[i]; + return argNames[i]; } @@ -871,7 +909,7 @@ @Override public String getSignature() { - return Type.getMethodSignature(super.getType(), arg_types); + return Type.getMethodSignature(super.getType(), argTypes); } @@ -880,9 +918,9 @@ */ public void setMaxStack() { // TODO could be package-protected? (some tests would need repackaging) if (il != null) { - max_stack = getMaxStack(super.getConstantPool(), il, getExceptionHandlers()); + maxStack = getMaxStack(super.getConstantPool(), il, getExceptionHandlers()); } else { - max_stack = 0; + maxStack = 0; } } @@ -893,8 +931,8 @@ public void setMaxLocals() { // TODO could be package-protected? (some tests would need repackaging) if (il != null) { int max = isStatic() ? 0 : 1; - if (arg_types != null) { - for (final Type arg_type : arg_types) { + if (argTypes != null) { + for (final Type arg_type : argTypes) { max += arg_type.getSize(); } } @@ -909,9 +947,9 @@ } } } - max_locals = max; + maxLocals = max; } else { - max_locals = 0; + maxLocals = 0; } } @@ -920,7 +958,7 @@ * LocalVariableTable, like javac -O */ public void stripAttributes( final boolean flag ) { - strip_attributes = flag; + stripAttributes = flag; } static final class BranchTarget { @@ -1091,7 +1129,7 @@ @Override public final String toString() { final String access = Utility.accessToString(super.getAccessFlags()); - String signature = Type.getMethodSignature(super.getType(), arg_types); + String signature = Type.getMethodSignature(super.getType(), argTypes); signature = Utility.methodSignatureToString(signature, super.getName(), access, true, getLocalVariableTable(super.getConstantPool())); final StringBuilder buf = new StringBuilder(signature); @@ -1101,8 +1139,8 @@ } } - if (throws_vec.size() > 0) { - for (final String throwsDescriptor : throws_vec) { + if (throwsList.size() > 0) { + for (final String throwsDescriptor : throwsList) { buf.append("\n\t\tthrows ").append(throwsDescriptor); } } @@ -1112,9 +1150,9 @@ /** @return deep copy of this method */ - public MethodGen copy( final String class_name, final ConstantPoolGen cp ) { + public MethodGen copy( final String className, final ConstantPoolGen cp ) { final Method m = ((MethodGen) clone()).getMethod(); - final MethodGen mg = new MethodGen(m, class_name, super.getConstantPool()); + final MethodGen mg = new MethodGen(m, className, super.getConstantPool()); if (super.getConstantPool() != cp) { mg.setConstantPool(cp); mg.getInstructionList().replaceConstantPool(super.getConstantPool(), cp); @@ -1122,7 +1160,7 @@ return mg; } - //J5TODO: Should param_annotations be an array of arrays? Rather than an array of lists, this + //J5TODO: Should paramAnnotations be an array of arrays? Rather than an array of lists, this // is more likely to suggest to the caller it is readonly (which a List does not). /** * Return a list of AnnotationGen objects representing parameter annotations @@ -1130,10 +1168,10 @@ */ public List<AnnotationEntryGen> getAnnotationsOnParameter(final int i) { ensureExistingParameterAnnotationsUnpacked(); - if (!hasParameterAnnotations || i > arg_types.length) { + if (!hasParameterAnnotations || i > argTypes.length) { return null; } - return param_annotations[i]; + return paramAnnotations[i]; } /** @@ -1156,14 +1194,14 @@ for (final Attribute attribute : attrs) { if (attribute instanceof ParameterAnnotations) { - // Initialize param_annotations + // Initialize paramAnnotations if (!hasParameterAnnotations) { - @SuppressWarnings({"rawtypes", "unchecked"}) - final List<AnnotationEntryGen>[] parmList = new List[arg_types.length]; - param_annotations = parmList; - for (int j = 0; j < arg_types.length; j++) { - param_annotations[j] = new ArrayList<>(); + @SuppressWarnings({"rawtypes", "unchecked"}) // OK + final List<AnnotationEntryGen>[] parmList = new List[argTypes.length]; + paramAnnotations = parmList; + for (int j = 0; j < argTypes.length; j++) { + paramAnnotations[j] = new ArrayList<>(); } } hasParameterAnnotations = true; @@ -1181,7 +1219,7 @@ // ... which needs transforming into an AnnotationGen[] ... final List<AnnotationEntryGen> mutable = makeMutableVersion(immutableArray.getAnnotationEntries()); // ... then add these to any we already know about - param_annotations[j].addAll(mutable); + paramAnnotations[j].addAll(mutable); } } } @@ -1211,11 +1249,11 @@ if (!hasParameterAnnotations) { @SuppressWarnings({"rawtypes", "unchecked"}) - final List<AnnotationEntryGen>[] parmList = new List[arg_types.length]; - param_annotations = parmList; + final List<AnnotationEntryGen>[] parmList = new List[argTypes.length]; + paramAnnotations = parmList; hasParameterAnnotations = true; } - final List<AnnotationEntryGen> existingAnnotations = param_annotations[parameterIndex]; + final List<AnnotationEntryGen> existingAnnotations = paramAnnotations[parameterIndex]; if (existingAnnotations != null) { existingAnnotations.add(annotation); @@ -1224,7 +1262,7 @@ { final List<AnnotationEntryGen> l = new ArrayList<>(); l.add(annotation); - param_annotations[parameterIndex] = l; + paramAnnotations[parameterIndex] = l; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java index bca1199..13cb8ea 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java
@@ -31,28 +31,28 @@ */ public class ObjectType extends ReferenceType { - private final String class_name; // Class name of type + private final String className; // Class name of type /** * @since 6.0 */ - public static ObjectType getInstance(final String class_name) { - return new ObjectType(class_name); + public static ObjectType getInstance(final String className) { + return new ObjectType(className); } /** - * @param class_name fully qualified class name, e.g. java.lang.String + * @param className fully qualified class name, e.g. java.lang.String */ - public ObjectType(final String class_name) { - super(Const.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); - this.class_name = class_name.replace('/', '.'); + public ObjectType(final String className) { + super(Const.T_REFERENCE, "L" + className.replace('.', '/') + ";"); + this.className = className.replace('/', '.'); } /** @return name of referenced class */ public String getClassName() { - return class_name; + return className; } @@ -60,7 +60,7 @@ */ @Override public int hashCode() { - return class_name.hashCode(); + return className.hashCode(); } @@ -69,7 +69,7 @@ @Override public boolean equals( final Object type ) { return (type instanceof ObjectType) - ? ((ObjectType) type).class_name.equals(class_name) + ? ((ObjectType) type).className.equals(className) : false; } @@ -84,7 +84,7 @@ @Deprecated public boolean referencesClass() { try { - final JavaClass jc = Repository.lookupClass(class_name); + final JavaClass jc = Repository.lookupClass(className); return jc.isClass(); } catch (final ClassNotFoundException e) { return false; @@ -102,7 +102,7 @@ @Deprecated public boolean referencesInterface() { try { - final JavaClass jc = Repository.lookupClass(class_name); + final JavaClass jc = Repository.lookupClass(className); return !jc.isClass(); } catch (final ClassNotFoundException e) { return false; @@ -119,7 +119,7 @@ * referenced by this type can't be found */ public boolean referencesClassExact() throws ClassNotFoundException { - final JavaClass jc = Repository.lookupClass(class_name); + final JavaClass jc = Repository.lookupClass(className); return jc.isClass(); } @@ -133,7 +133,7 @@ * referenced by this type can't be found */ public boolean referencesInterfaceExact() throws ClassNotFoundException { - final JavaClass jc = Repository.lookupClass(class_name); + final JavaClass jc = Repository.lookupClass(className); return !jc.isClass(); } @@ -147,7 +147,7 @@ if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) { return false; } - return Repository.instanceOf(this.class_name, superclass.class_name); + return Repository.instanceOf(this.className, superclass.className); } @@ -157,11 +157,11 @@ * can't be found */ public boolean accessibleTo( final ObjectType accessor ) throws ClassNotFoundException { - final JavaClass jc = Repository.lookupClass(class_name); + final JavaClass jc = Repository.lookupClass(className); if (jc.isPublic()) { return true; } - final JavaClass acc = Repository.lookupClass(accessor.class_name); + final JavaClass acc = Repository.lookupClass(accessor.className); return acc.getPackageName().equals(jc.getPackageName()); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java index 6f7c7a8..bd2f254 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java
@@ -32,7 +32,7 @@ private int[] match; private InstructionHandle[] targets; private Select instruction; - private int match_length; + private int matchLength; /** @@ -53,10 +53,10 @@ public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target, final int max_gap) { this.match = match.clone(); this.targets = targets.clone(); - if ((match_length = match.length) < 2) { + if ((matchLength = match.length) < 2) { instruction = new TABLESWITCH(match, targets, target); } else { - sort(0, match_length - 1); + sort(0, matchLength - 1); if (matchIsOrdered(max_gap)) { fillup(max_gap, target); instruction = new TABLESWITCH(this.match, this.targets, target); @@ -73,13 +73,13 @@ private void fillup( final int max_gap, final InstructionHandle target ) { - final int max_size = match_length + match_length * max_gap; + final int max_size = matchLength + matchLength * max_gap; final int[] m_vec = new int[max_size]; final InstructionHandle[] t_vec = new InstructionHandle[max_size]; int count = 1; m_vec[0] = match[0]; t_vec[0] = targets[0]; - for (int i = 1; i < match_length; i++) { + for (int i = 1; i < matchLength; i++) { final int prev = match[i - 1]; final int gap = match[i] - prev; for (int j = 1; j < gap; j++) { @@ -138,7 +138,7 @@ * @return match is sorted in ascending order with no gap bigger than max_gap? */ private boolean matchIsOrdered( final int max_gap ) { - for (int i = 1; i < match_length; i++) { + for (int i = 1; i < matchLength; i++) { if (match[i] - match[i - 1] > max_gap) { return false; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java index 244507a..a9dc01e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -27,12 +27,12 @@ /** * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions. * - * <p>We use our super's <code>target</code> property as the default target. + * <p>We use our super's {@code target} property as the default target. * * @see LOOKUPSWITCH * @see TABLESWITCH * @see InstructionList - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public abstract class Select extends BranchInstruction implements VariableLengthInstruction, StackConsumer /* @since 6.0 */, StackProducer {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java index 946d962..bccb59c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java
@@ -166,7 +166,7 @@ idx = cpool.addInteger(value.getValueShort()); break; default: - throw new RuntimeException( + throw new IllegalArgumentException( "SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType()); } } @@ -189,7 +189,7 @@ public String getValueString() { if (super.getElementValueType() != STRING) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueString() on a non STRING ElementValue"); } final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx); @@ -199,7 +199,7 @@ public int getValueInt() { if (super.getElementValueType() != PRIMITIVE_INT) { - throw new RuntimeException( + throw new IllegalStateException( "Dont call getValueString() on a non STRING ElementValue"); } final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); @@ -243,7 +243,7 @@ final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); return cu8.getBytes(); default: - throw new RuntimeException( + throw new IllegalStateException( "SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType()); } } @@ -266,7 +266,7 @@ dos.writeShort(idx); break; default: - throw new RuntimeException( + throw new IllegalStateException( "SimpleElementValueGen doesnt know how to write out type " + super.getElementValueType()); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java index ced2f18..2e366df 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -30,7 +30,7 @@ * Abstract super class for all possible java types, namely basic types * such as int, object types like String and array types, e.g. int[] * - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public abstract class Type { @@ -295,7 +295,7 @@ } else if (cl == Character.TYPE) { return CHAR; } else { - throw new IllegalStateException("Ooops, what primitive type is " + cl); + throw new IllegalStateException("Unknown primitive type " + cl); } } else { // "Real" class return ObjectType.getInstance(cl.getName());
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java index 18f9d5a..ae7f740 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -64,7 +64,7 @@ * A helper class for BCELifier. * * @see BCELifier - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ class BCELFactory extends EmptyVisitor { @@ -201,7 +201,7 @@ + ", (short) " + dim + "));"); break; default: - throw new RuntimeException("Oops: " + opcode); + throw new IllegalArgumentException("Unhandled opcode: " + opcode); } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java index 0ed26e4..fe8e938 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java
@@ -48,21 +48,21 @@ */ final class CodeHTML { - private final String class_name; // name of current class + private final String className; // name of current class // private Method[] methods; // Methods to print private final PrintWriter file; // file to write to - private BitSet goto_set; - private final ConstantPool constant_pool; - private final ConstantHTML constant_html; + private BitSet gotoSet; + private final ConstantPool constantPool; + private final ConstantHTML constantHtml; private static boolean wide = false; CodeHTML(final String dir, final String class_name, final Method[] methods, final ConstantPool constant_pool, final ConstantHTML constant_html) throws IOException { - this.class_name = class_name; + this.className = class_name; // this.methods = methods; - this.constant_pool = constant_pool; - this.constant_html = constant_html; + this.constantPool = constant_pool; + this.constantHtml = constant_html; file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html")); file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\">"); for (int i = 0; i < methods.length; i++) { @@ -231,19 +231,19 @@ case Const.PUTFIELD: case Const.PUTSTATIC: index = bytes.readShort(); - final ConstantFieldref c1 = (ConstantFieldref) constant_pool.getConstant(index, + final ConstantFieldref c1 = (ConstantFieldref) constantPool.getConstant(index, Const.CONSTANT_Fieldref); class_index = c1.getClassIndex(); - name = constant_pool.getConstantString(class_index, Const.CONSTANT_Class); + name = constantPool.getConstantString(class_index, Const.CONSTANT_Class); name = Utility.compactClassName(name, false); index = c1.getNameAndTypeIndex(); - final String field_name = constant_pool.constantToString(index, Const.CONSTANT_NameAndType); - if (name.equals(class_name)) { // Local field - buf.append("<A HREF=\"").append(class_name).append("_methods.html#field") + final String field_name = constantPool.constantToString(index, Const.CONSTANT_NameAndType); + if (name.equals(className)) { // Local field + buf.append("<A HREF=\"").append(className).append("_methods.html#field") .append(field_name).append("\" TARGET=Methods>").append(field_name) .append("</A>\n"); } else { - buf.append(constant_html.referenceConstant(class_index)).append(".").append( + buf.append(constantHtml.referenceConstant(class_index)).append(".").append( field_name); } break; @@ -253,7 +253,7 @@ case Const.INSTANCEOF: case Const.NEW: index = bytes.readShort(); - buf.append(constant_html.referenceConstant(index)); + buf.append(constantHtml.referenceConstant(index)); break; /* Operands are references to methods in constant pool */ @@ -269,7 +269,7 @@ bytes.readUnsignedByte(); // Reserved // int nargs = bytes.readUnsignedByte(); // Redundant // int reserved = bytes.readUnsignedByte(); // Reserved - final ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constant_pool + final ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constantPool .getConstant(m_index, Const.CONSTANT_InterfaceMethodref); class_index = c.getClassIndex(); index = c.getNameAndTypeIndex(); @@ -277,7 +277,7 @@ } else if (opcode == Const.INVOKEDYNAMIC) { // Special treatment needed bytes.readUnsignedByte(); // Reserved bytes.readUnsignedByte(); // Reserved - final ConstantInvokeDynamic c = (ConstantInvokeDynamic) constant_pool + final ConstantInvokeDynamic c = (ConstantInvokeDynamic) constantPool .getConstant(m_index, Const.CONSTANT_InvokeDynamic); index = c.getNameAndTypeIndex(); name = "#" + c.getBootstrapMethodAttrIndex(); @@ -285,21 +285,21 @@ // UNDONE: Java8 now allows INVOKESPECIAL and INVOKESTATIC to // reference EITHER a Methodref OR an InterfaceMethodref. // Not sure if that affects this code or not. (markro) - final ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(m_index, + final ConstantMethodref c = (ConstantMethodref) constantPool.getConstant(m_index, Const.CONSTANT_Methodref); class_index = c.getClassIndex(); index = c.getNameAndTypeIndex(); name = Class2HTML.referenceClass(class_index); } - str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant( + str = Class2HTML.toHTML(constantPool.constantToString(constantPool.getConstant( index, Const.CONSTANT_NameAndType))); // Get signature, i.e., types - final ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant(index, + final ConstantNameAndType c2 = (ConstantNameAndType) constantPool.getConstant(index, Const.CONSTANT_NameAndType); - signature = constant_pool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); + signature = constantPool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); final String[] args = Utility.methodSignatureArgumentTypes(signature, false); final String type = Utility.methodSignatureReturnType(signature, false); - buf.append(name).append(".<A HREF=\"").append(class_name).append("_cp.html#cp") + buf.append(name).append(".<A HREF=\"").append(className).append("_cp.html#cp") .append(m_index).append("\" TARGET=ConstantPool>").append(str).append( "</A>").append("("); // List arguments @@ -317,30 +317,30 @@ case Const.LDC_W: case Const.LDC2_W: index = bytes.readShort(); - buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index) + buf.append("<A HREF=\"").append(className).append("_cp.html#cp").append(index) .append("\" TARGET=\"ConstantPool\">").append( - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool.getConstant(index).getTag()))).append("</a>"); + Class2HTML.toHTML(constantPool.constantToString(index, + constantPool.getConstant(index).getTag()))).append("</a>"); break; case Const.LDC: index = bytes.readUnsignedByte(); - buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index) + buf.append("<A HREF=\"").append(className).append("_cp.html#cp").append(index) .append("\" TARGET=\"ConstantPool\">").append( - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool.getConstant(index).getTag()))).append("</a>"); + Class2HTML.toHTML(constantPool.constantToString(index, + constantPool.getConstant(index).getTag()))).append("</a>"); break; /* Array of references. */ case Const.ANEWARRAY: index = bytes.readShort(); - buf.append(constant_html.referenceConstant(index)); + buf.append(constantHtml.referenceConstant(index)); break; /* Multidimensional array of references. */ case Const.MULTIANEWARRAY: index = bytes.readShort(); final int dimensions = bytes.readByte(); - buf.append(constant_html.referenceConstant(index)).append(":").append(dimensions) + buf.append(constantHtml.referenceConstant(index)).append(":").append(dimensions) .append("-dimensional"); break; /* Increment local variable. @@ -389,7 +389,7 @@ */ private void findGotos( final ByteSequence bytes, final Code code ) throws IOException { int index; - goto_set = new BitSet(bytes.available()); + gotoSet = new BitSet(bytes.available()); int opcode; /* First get Code attribute from method and the exceptions handled * (try .. catch) in this method. We only need the line number here. @@ -397,9 +397,9 @@ if (code != null) { final CodeException[] ce = code.getExceptionTable(); for (final CodeException cex : ce) { - goto_set.set(cex.getStartPC()); - goto_set.set(cex.getEndPC()); - goto_set.set(cex.getHandlerPC()); + gotoSet.set(cex.getStartPC()); + gotoSet.set(cex.getEndPC()); + gotoSet.set(cex.getHandlerPC()); } // Look for local variables and their range final Attribute[] attributes = code.getAttributes(); @@ -410,8 +410,8 @@ for (final LocalVariable var : vars) { final int start = var.getStartPC(); final int end = start + var.getLength(); - goto_set.set(start); - goto_set.set(end); + gotoSet.set(start); + gotoSet.set(end); } break; } @@ -439,21 +439,21 @@ final int high = bytes.readInt(); offset = bytes.getIndex() - 12 - no_pad_bytes - 1; default_offset += offset; - goto_set.set(default_offset); + gotoSet.set(default_offset); for (int j = 0; j < (high - low + 1); j++) { index = offset + bytes.readInt(); - goto_set.set(index); + gotoSet.set(index); } } else { // LOOKUPSWITCH final int npairs = bytes.readInt(); offset = bytes.getIndex() - 8 - no_pad_bytes - 1; default_offset += offset; - goto_set.set(default_offset); + gotoSet.set(default_offset); for (int j = 0; j < npairs; j++) { // int match = bytes.readInt(); bytes.readInt(); index = offset + bytes.readInt(); - goto_set.set(index); + gotoSet.set(index); } } break; @@ -477,13 +477,13 @@ case Const.JSR: //bytes.readByte(); // Skip already read byte index = bytes.getIndex() + bytes.readShort() - 1; - goto_set.set(index); + gotoSet.set(index); break; case Const.GOTO_W: case Const.JSR_W: //bytes.readByte(); // Skip already read byte index = bytes.getIndex() + bytes.readInt() - 1; - goto_set.set(index); + gotoSet.set(index); break; default: bytes.unreadByte(); @@ -513,7 +513,7 @@ final Attribute[] attributes = method.getAttributes(); file.print("<P><B><FONT COLOR=\"#FF0000\">" + access + "</FONT> " + "<A NAME=method" + method_number + ">" + Class2HTML.referenceType(type) + "</A> <A HREF=\"" - + class_name + "_methods.html#method" + method_number + "\" TARGET=Methods>" + + className + "_methods.html#method" + method_number + "\" TARGET=Methods>" + html_name + "</A>("); for (int i = 0; i < args.length; i++) { file.print(Class2HTML.referenceType(args[i])); @@ -529,7 +529,7 @@ for (int i = 0; i < attributes.length; i++) { byte tag = attributes[i].getTag(); if (tag != Const.ATTR_UNKNOWN) { - file.print("<LI><A HREF=\"" + class_name + "_attributes.html#method" + file.print("<LI><A HREF=\"" + className + "_attributes.html#method" + method_number + "@" + i + "\" TARGET=Attributes>" + Const.getAttributeName(tag) + "</A></LI>\n"); } else { @@ -542,7 +542,7 @@ file.print("<UL>"); for (int j = 0; j < attributes2.length; j++) { tag = attributes2[j].getTag(); - file.print("<LI><A HREF=\"" + class_name + "_attributes.html#" + "method" + file.print("<LI><A HREF=\"" + className + "_attributes.html#" + "method" + method_number + "@" + i + "@" + j + "\" TARGET=Attributes>" + Const.getAttributeName(tag) + "</A></LI>\n"); } @@ -552,7 +552,7 @@ file.println("</UL>"); } if (code != null) { // No code, an abstract method, e.g. - //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1)); + //System.out.println(name + "\n" + Utility.codeToString(code, constantPool, 0, -1)); // Print the byte code try (ByteSequence stream = new ByteSequence(code)) { stream.mark(stream.available()); @@ -568,7 +568,7 @@ * Set an anchor mark if this line is targetted by a goto, jsr, etc. Defining an anchor for every * line is very inefficient! */ - if (goto_set.get(offset)) { + if (gotoSet.get(offset)) { anchor = "<A NAME=code" + method_number + "@" + offset + "></A>"; } String anchor2;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java index eeafbcf..e2d5b4b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java
@@ -44,25 +44,25 @@ */ final class ConstantHTML { - private final String class_name; // name of current class - private final String class_package; // name of package - private final ConstantPool constant_pool; // reference to constant pool + private final String className; // name of current class + private final String classPackage; // name of package + private final ConstantPool constantPool; // reference to constant pool private final PrintWriter file; // file to write to - private final String[] constant_ref; // String to return for cp[i] + private final String[] constantRef; // String to return for cp[i] private final Constant[] constants; // The constants in the cp private final Method[] methods; ConstantHTML(final String dir, final String class_name, final String class_package, final Method[] methods, final ConstantPool constant_pool) throws IOException { - this.class_name = class_name; - this.class_package = class_package; - this.constant_pool = constant_pool; + this.className = class_name; + this.classPackage = class_package; + this.constantPool = constant_pool; this.methods = methods; constants = constant_pool.getConstantPool(); file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); - constant_ref = new String[constants.length]; - constant_ref[0] = "<unknown>"; + constantRef = new String[constants.length]; + constantRef[0] = "<unknown>"; file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>"); // Loop through constants, constants[0] is reserved for (int i = 1; i < constants.length; i++) { @@ -82,7 +82,7 @@ String referenceConstant( final int index ) { - return constant_ref[index]; + return constantRef[index]; } @@ -101,29 +101,29 @@ case Const.CONSTANT_Methodref: // Get class_index and name_and_type_index, depending on type if (tag == Const.CONSTANT_Methodref) { - final ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(index, + final ConstantMethodref c = (ConstantMethodref) constantPool.getConstant(index, Const.CONSTANT_Methodref); class_index = c.getClassIndex(); name_index = c.getNameAndTypeIndex(); } else { - final ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constant_pool + final ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constantPool .getConstant(index, Const.CONSTANT_InterfaceMethodref); class_index = c1.getClassIndex(); name_index = c1.getNameAndTypeIndex(); } // Get method name and its class - final String method_name = constant_pool.constantToString(name_index, + final String method_name = constantPool.constantToString(name_index, Const.CONSTANT_NameAndType); final String html_method_name = Class2HTML.toHTML(method_name); // Partially compacted class name, i.e., / -> . - final String method_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); + final String method_class = constantPool.constantToString(class_index, Const.CONSTANT_Class); String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(short_method_class, class_package + short_method_class = Utility.compactClassName(short_method_class, classPackage + ".", true); // Remove class package prefix // Get method signature - final ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant( + final ConstantNameAndType c2 = (ConstantNameAndType) constantPool.getConstant( name_index, Const.CONSTANT_NameAndType); - final String signature = constant_pool.constantToString(c2.getSignatureIndex(), + final String signature = constantPool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); // Get array of strings containing the argument types final String[] args = Utility.methodSignatureArgumentTypes(signature, false); @@ -139,17 +139,17 @@ } buf.append(")"); final String arg_types = buf.toString(); - if (method_class.equals(class_name)) { - ref = "<A HREF=\"" + class_name + "_code.html#method" + if (method_class.equals(className)) { + ref = "<A HREF=\"" + className + "_code.html#method" + getMethodNumber(method_name + signature) + "\" TARGET=Code>" + html_method_name + "</A>"; } else { ref = "<A HREF=\"" + method_class + ".html" + "\" TARGET=_top>" + short_method_class + "</A>." + html_method_name; } - constant_ref[index] = ret_type + " <A HREF=\"" + class_name + "_cp.html#cp" + constantRef[index] = ret_type + " <A HREF=\"" + className + "_cp.html#cp" + class_index + "\" TARGET=Constants>" + short_method_class - + "</A>.<A HREF=\"" + class_name + "_cp.html#cp" + index + + "</A>.<A HREF=\"" + className + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + html_method_name + "</A> " + arg_types; file.println("<P><TT>" + ret_type + " " + ref + arg_types + " </TT>\n<UL>" + "<LI><A HREF=\"#cp" + class_index @@ -158,27 +158,27 @@ break; case Const.CONSTANT_Fieldref: // Get class_index and name_and_type_index - final ConstantFieldref c3 = (ConstantFieldref) constant_pool.getConstant(index, + final ConstantFieldref c3 = (ConstantFieldref) constantPool.getConstant(index, Const.CONSTANT_Fieldref); class_index = c3.getClassIndex(); name_index = c3.getNameAndTypeIndex(); // Get method name and its class (compacted) - final String field_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); + final String field_class = constantPool.constantToString(class_index, Const.CONSTANT_Class); String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. short_field_class = Utility.compactClassName(short_field_class, - class_package + ".", true); // Remove class package prefix - final String field_name = constant_pool + classPackage + ".", true); // Remove class package prefix + final String field_name = constantPool .constantToString(name_index, Const.CONSTANT_NameAndType); - if (field_class.equals(class_name)) { + if (field_class.equals(className)) { ref = "<A HREF=\"" + field_class + "_methods.html#field" + field_name + "\" TARGET=Methods>" + field_name + "</A>"; } else { ref = "<A HREF=\"" + field_class + ".html\" TARGET=_top>" + short_field_class + "</A>." + field_name + "\n"; } - constant_ref[index] = "<A HREF=\"" + class_name + "_cp.html#cp" + class_index + constantRef[index] = "<A HREF=\"" + className + "_cp.html#cp" + class_index + "\" TARGET=Constants>" + short_field_class + "</A>.<A HREF=\"" - + class_name + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + + className + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + field_name + "</A>"; file.println("<P><TT>" + ref + "</TT><BR>\n" + "<UL>" + "<LI><A HREF=\"#cp" + class_index + "\">Class(" + class_index + ")</A><BR>\n" @@ -186,40 +186,40 @@ + ")</A></UL>"); break; case Const.CONSTANT_Class: - final ConstantClass c4 = (ConstantClass) constant_pool.getConstant(index, Const.CONSTANT_Class); + final ConstantClass c4 = (ConstantClass) constantPool.getConstant(index, Const.CONSTANT_Class); name_index = c4.getNameIndex(); - final String class_name2 = constant_pool.constantToString(index, tag); // / -> . + final String class_name2 = constantPool.constantToString(index, tag); // / -> . String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. - short_class_name = Utility.compactClassName(short_class_name, class_package + ".", + short_class_name = Utility.compactClassName(short_class_name, classPackage + ".", true); // Remove class package prefix ref = "<A HREF=\"" + class_name2 + ".html\" TARGET=_top>" + short_class_name + "</A>"; - constant_ref[index] = "<A HREF=\"" + class_name + "_cp.html#cp" + index + constantRef[index] = "<A HREF=\"" + className + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + short_class_name + "</A>"; file.println("<P><TT>" + ref + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index + "\">Name index(" + name_index + ")</A></UL>\n"); break; case Const.CONSTANT_String: - final ConstantString c5 = (ConstantString) constant_pool.getConstant(index, + final ConstantString c5 = (ConstantString) constantPool.getConstant(index, Const.CONSTANT_String); name_index = c5.getStringIndex(); - final String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag)); + final String str = Class2HTML.toHTML(constantPool.constantToString(index, tag)); file.println("<P><TT>" + str + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index + "\">Name index(" + name_index + ")</A></UL>\n"); break; case Const.CONSTANT_NameAndType: - final ConstantNameAndType c6 = (ConstantNameAndType) constant_pool.getConstant(index, + final ConstantNameAndType c6 = (ConstantNameAndType) constantPool.getConstant(index, Const.CONSTANT_NameAndType); name_index = c6.getNameIndex(); final int signature_index = c6.getSignatureIndex(); file.println("<P><TT>" - + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + + Class2HTML.toHTML(constantPool.constantToString(index, tag)) + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index + "\">Name index(" + name_index + ")</A>\n" + "<LI><A HREF=\"#cp" + signature_index + "\">Signature index(" + signature_index + ")</A></UL>\n"); break; default: - file.println("<P><TT>" + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "</TT>\n"); + file.println("<P><TT>" + Class2HTML.toHTML(constantPool.constantToString(index, tag)) + "</TT>\n"); } // switch }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java index b9b4815..46d2237 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -64,7 +64,7 @@ * * @see com.sun.org.apache.bcel.internal.generic.Instruction * @see InstructionList - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class InstructionFinder { @@ -72,7 +72,7 @@ private static final int NO_OPCODES = 256; // Potential number, some are not used private static final Map<String, String> map = new HashMap<>(); private final InstructionList il; - private String il_string; // instruction list as string + private String ilString; // instruction list as string private InstructionHandle[] handles; // map instruction @@ -99,7 +99,7 @@ for (int i = 0; i < size; i++) { buf[i] = makeChar(handles[i].getInstruction().getOpcode()); } - il_string = new String(buf); + ilString = new String(buf); } @@ -120,7 +120,7 @@ return "" + makeChar(i); } } - throw new RuntimeException("Instruction unknown: " + pattern); + throw new IllegalArgumentException("Instruction unknown: " + pattern); } @@ -221,8 +221,8 @@ } final Pattern regex = Pattern.compile(search); final List<InstructionHandle[]> matches = new ArrayList<>(); - final Matcher matcher = regex.matcher(il_string); - while (start < il_string.length() && matcher.find(start)) { + final Matcher matcher = regex.matcher(ilString); + while (start < ilString.length() && matcher.find(start)) { final int startExpr = matcher.start(); final int endExpr = matcher.end(); final int lenExpr = endExpr - startExpr;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java index 26210d7..05f25ed 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java
@@ -41,17 +41,17 @@ */ final class MethodHTML { - private final String class_name; // name of current class + private final String className; // name of current class private final PrintWriter file; // file to write to - private final ConstantHTML constant_html; + private final ConstantHTML constantHtml; private final AttributeHTML attribute_html; MethodHTML(final String dir, final String class_name, final Method[] methods, final Field[] fields, final ConstantHTML constant_html, final AttributeHTML attribute_html) throws IOException { - this.class_name = class_name; + this.className = class_name; this.attribute_html = attribute_html; - this.constant_html = constant_html; + this.constantHtml = constant_html; file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html")); file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>"); file.println("<TR><TH ALIGN=LEFT>Access flags</TH><TH ALIGN=LEFT>Type</TH>" @@ -95,7 +95,7 @@ if (attributes[i].getTag() == Const.ATTR_CONSTANT_VALUE) { // Default value final String str = ((ConstantValue) attributes[i]).toString(); // Reference attribute in _attributes.html - file.print("<TD>= <A HREF=\"" + class_name + "_attributes.html#" + name + "@" + i + file.print("<TD>= <A HREF=\"" + className + "_attributes.html#" + name + "@" + i + "\" TARGET=\"Attributes\">" + str + "</TD>\n"); break; } @@ -125,7 +125,7 @@ html_name = Class2HTML.toHTML(name); file.print("<TR VALIGN=TOP><TD><FONT COLOR=\"#FF0000\"><A NAME=method" + method_number + ">" + access + "</A></FONT></TD>"); - file.print("<TD>" + Class2HTML.referenceType(type) + "</TD><TD>" + "<A HREF=" + class_name + file.print("<TD>" + Class2HTML.referenceType(type) + "</TD><TD>" + "<A HREF=" + className + "_code.html#method" + method_number + " TARGET=Code>" + html_name + "</A></TD>\n<TD>("); for (int i = 0; i < args.length; i++) { @@ -144,7 +144,7 @@ file.print("<TR VALIGN=TOP><TD COLSPAN=2></TD><TH ALIGN=LEFT>throws</TH><TD>"); final int[] exceptions = ((ExceptionTable) attributes[i]).getExceptionIndexTable(); for (int j = 0; j < exceptions.length; j++) { - file.print(constant_html.referenceConstant(exceptions[j])); + file.print(constantHtml.referenceConstant(exceptions[j])); if (j < exceptions.length - 1) { file.print(", "); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java index 19eaa7f..c0c7082 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java +++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -39,7 +39,7 @@ * * @see com.sun.org.apache.bcel.internal.Repository * - * @LastModified: Jan 2020 + * @LastModified: May 2021 */ public class SyntheticRepository implements Repository { @@ -60,7 +60,7 @@ public void storeClass(final JavaClass clazz) { loadedClasses.put(clazz.getClassName(), new SoftReference<>(clazz)); clazz.setRepository(this); - } + } /** * Remove class from repository @@ -78,7 +78,7 @@ final SoftReference<JavaClass> ref = loadedClasses.get(className); if (ref == null) { return null; - } +} return ref.get(); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java index 82caed9..7e75dc3 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java
@@ -107,6 +107,21 @@ ORACLE_JAXP_PROPERTY_PREFIX + "maxElementDepth"; /** + * JDK XPath Expression group limit + */ + public static final String XPATH_GROUP_LIMIT = "jdk.xml.xpathExprGrpLimit"; + + /** + * JDK XPath Expression operators limit + */ + public static final String XPATH_OP_LIMIT = "jdk.xml.xpathExprOpLimit"; + + /** + * JDK XSL XPath limit or Total Number of Operators Permitted in an XSL Stylesheet + */ + public static final String XPATH_TOTALOP_LIMIT = "jdk.xml.xpathTotalOpLimit"; + + /** * JDK property indicating whether the parser shall print out entity * count information * Value: a string "yes" means print, "no" or any other string means not.
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java deleted file mode 100644 index 30245d6..0000000 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java +++ /dev/null
@@ -1,467 +0,0 @@ -/* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.org.apache.xalan.internal.utils; - -import com.sun.org.apache.xalan.internal.XalanConstants; -import java.util.concurrent.CopyOnWriteArrayList; -import jdk.xml.internal.SecuritySupport; -import org.xml.sax.SAXException; - - -/** - * This class is not the same as that in Xerces. It is used to manage the - * state of corresponding Xerces properties and pass the values over to - * the Xerces Security Manager. - * - * @author Joe Wang Oracle Corp. - * - */ -public final class XMLSecurityManager { - - /** - * States of the settings of a property, in the order: default value, value - * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system - * properties, and jaxp api properties - */ - public static enum State { - //this order reflects the overriding order - - DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"), - JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"), - APIPROPERTY("property"); - - final String literal; - State(String literal) { - this.literal = literal; - } - - String literal() { - return literal; - } - } - - /** - * Limits managed by the security manager - */ - public static enum Limit { - - ENTITY_EXPANSION_LIMIT("EntityExpansionLimit", XalanConstants.JDK_ENTITY_EXPANSION_LIMIT, - XalanConstants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000), - MAX_OCCUR_NODE_LIMIT("MaxOccurLimit", XalanConstants.JDK_MAX_OCCUR_LIMIT, - XalanConstants.SP_MAX_OCCUR_LIMIT, 0, 5000), - ELEMENT_ATTRIBUTE_LIMIT("ElementAttributeLimit", XalanConstants.JDK_ELEMENT_ATTRIBUTE_LIMIT, - XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000), - TOTAL_ENTITY_SIZE_LIMIT("TotalEntitySizeLimit", XalanConstants.JDK_TOTAL_ENTITY_SIZE_LIMIT, - XalanConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000), - GENERAL_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", XalanConstants.JDK_GENERAL_ENTITY_SIZE_LIMIT, - XalanConstants.SP_GENERAL_ENTITY_SIZE_LIMIT, 0, 0), - PARAMETER_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", XalanConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, - XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000), - MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit", XalanConstants.JDK_MAX_ELEMENT_DEPTH, - XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0), - MAX_NAME_LIMIT("MaxXMLNameLimit", XalanConstants.JDK_XML_NAME_LIMIT, - XalanConstants.SP_XML_NAME_LIMIT, 1000, 1000), - ENTITY_REPLACEMENT_LIMIT("EntityReplacementLimit", XalanConstants.JDK_ENTITY_REPLACEMENT_LIMIT, - XalanConstants.SP_ENTITY_REPLACEMENT_LIMIT, 0, 3000000); - - final String key; - final String apiProperty; - final String systemProperty; - final int defaultValue; - final int secureValue; - - Limit(String key, String apiProperty, String systemProperty, int value, int secureValue) { - this.key = key; - this.apiProperty = apiProperty; - this.systemProperty = systemProperty; - this.defaultValue = value; - this.secureValue = secureValue; - } - - public boolean equalsAPIPropertyName(String propertyName) { - return (propertyName == null) ? false : apiProperty.equals(propertyName); - } - - public boolean equalsSystemPropertyName(String propertyName) { - return (propertyName == null) ? false : systemProperty.equals(propertyName); - } - - public String key() { - return key; - } - - public String apiProperty() { - return apiProperty; - } - - String systemProperty() { - return systemProperty; - } - - public int defaultValue() { - return defaultValue; - } - - int secureValue() { - return secureValue; - } - } - - /** - * Map old property names with the new ones - */ - public static enum NameMap { - - ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT, - XalanConstants.ENTITY_EXPANSION_LIMIT), - MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT, - XalanConstants.MAX_OCCUR_LIMIT), - ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, - XalanConstants.ELEMENT_ATTRIBUTE_LIMIT); - final String newName; - final String oldName; - - NameMap(String newName, String oldName) { - this.newName = newName; - this.oldName = oldName; - } - - String getOldName(String newName) { - if (newName.equals(this.newName)) { - return oldName; - } - return null; - } - } - /** - * Values of the properties - */ - private final int[] values; - /** - * States of the settings for each property - */ - private State[] states; - /** - * States that determine if properties are set explicitly - */ - private boolean[] isSet; - - - /** - * Index of the special entityCountInfo property - */ - private final int indexEntityCountInfo = 10000; - private String printEntityCountInfo = ""; - - /** - * Default constructor. Establishes default values for known security - * vulnerabilities. - */ - public XMLSecurityManager() { - this(false); - } - - /** - * Instantiate Security Manager in accordance with the status of - * secure processing - * @param secureProcessing - */ - public XMLSecurityManager(boolean secureProcessing) { - values = new int[Limit.values().length]; - states = new State[Limit.values().length]; - isSet = new boolean[Limit.values().length]; - for (Limit limit : Limit.values()) { - if (secureProcessing) { - values[limit.ordinal()] = limit.secureValue(); - states[limit.ordinal()] = State.FSP; - } else { - values[limit.ordinal()] = limit.defaultValue(); - states[limit.ordinal()] = State.DEFAULT; - } - } - //read system properties or jaxp.properties - readSystemProperties(); - } - - /** - * Setting FEATURE_SECURE_PROCESSING explicitly - */ - public void setSecureProcessing(boolean secure) { - for (Limit limit : Limit.values()) { - if (secure) { - setLimit(limit.ordinal(), State.FSP, limit.secureValue()); - } else { - setLimit(limit.ordinal(), State.FSP, limit.defaultValue()); - } - } - } - - /** - * Set limit by property name and state - * @param propertyName property name - * @param state the state of the property - * @param value the value of the property - * @return true if the property is managed by the security manager; false - * if otherwise. - */ - public boolean setLimit(String propertyName, State state, Object value) { - int index = getIndex(propertyName); - if (index > -1) { - setLimit(index, state, value); - return true; - } - return false; - } - - /** - * Set the value for a specific limit. - * - * @param limit the limit - * @param state the state of the property - * @param value the value of the property - */ - public void setLimit(Limit limit, State state, int value) { - setLimit(limit.ordinal(), state, value); - } - - /** - * Set the value of a property by its index - * - * @param index the index of the property - * @param state the state of the property - * @param value the value of the property - */ - public void setLimit(int index, State state, Object value) { - if (index == indexEntityCountInfo) { - //if it's explicitly set, it's treated as yes no matter the value - printEntityCountInfo = (String)value; - } else { - int temp = 0; - try { - temp = Integer.parseInt((String) value); - if (temp < 0) { - temp = 0; - } - } catch (NumberFormatException e) {} - setLimit(index, state, temp); } - } - - /** - * Set the value of a property by its index - * - * @param index the index of the property - * @param state the state of the property - * @param value the value of the property - */ - public void setLimit(int index, State state, int value) { - if (index == indexEntityCountInfo) { - //if it's explicitly set, it's treated as yes no matter the value - printEntityCountInfo = XalanConstants.JDK_YES; - } else { - //only update if it shall override - if (state.compareTo(states[index]) >= 0) { - values[index] = value; - states[index] = state; - isSet[index] = true; - } - } - } - - - /** - * Return the value of the specified property. - * - * @param propertyName the property name - * @return the value of the property as a string. If a property is managed - * by this manager, its value shall not be null. - */ - public String getLimitAsString(String propertyName) { - int index = getIndex(propertyName); - if (index > -1) { - return getLimitValueByIndex(index); - } - - return null; - } - - /** - * Return the value of a property by its ordinal - * - * @param limit the property - * @return value of a property - */ - public String getLimitValueAsString(Limit limit) { - return Integer.toString(values[limit.ordinal()]); - } - - /** - * Return the value of the specified property - * - * @param limit the property - * @return the value of the property - */ - public int getLimit(Limit limit) { - return values[limit.ordinal()]; - } - - /** - * Return the value of a property by its ordinal - * - * @param index the index of a property - * @return value of a property - */ - public int getLimitByIndex(int index) { - return values[index]; - } - /** - * Return the value of a property by its index - * - * @param index the index of a property - * @return limit of a property as a string - */ - public String getLimitValueByIndex(int index) { - if (index == indexEntityCountInfo) { - return printEntityCountInfo; - } - - return Integer.toString(values[index]); - } - /** - * Return the state of the limit property - * - * @param limit the limit - * @return the state of the limit property - */ - public State getState(Limit limit) { - return states[limit.ordinal()]; - } - - /** - * Return the state of the limit property - * - * @param limit the limit - * @return the state of the limit property - */ - public String getStateLiteral(Limit limit) { - return states[limit.ordinal()].literal(); - } - - /** - * Get the index by property name - * - * @param propertyName property name - * @return the index of the property if found; return -1 if not - */ - public int getIndex(String propertyName) { - for (Limit limit : Limit.values()) { - if (limit.equalsAPIPropertyName(propertyName)) { - //internally, ordinal is used as index - return limit.ordinal(); - } - } - //special property to return entity count info - if (propertyName.equals(XalanConstants.JDK_ENTITY_COUNT_INFO)) { - return indexEntityCountInfo; - } - return -1; - } - - /** - * Indicate if a property is set explicitly - * @param index - * @return - */ - public boolean isSet(int index) { - return isSet[index]; - } - - public boolean printEntityCountInfo() { - return printEntityCountInfo.equals(XalanConstants.JDK_YES); - } - /** - * Read from system properties, or those in jaxp.properties - */ - private void readSystemProperties() { - - for (Limit limit : Limit.values()) { - if (!getSystemProperty(limit, limit.systemProperty())) { - //if system property is not found, try the older form if any - for (NameMap nameMap : NameMap.values()) { - String oldName = nameMap.getOldName(limit.systemProperty()); - if (oldName != null) { - getSystemProperty(limit, oldName); - } - } - } - } - - } - - // Array list to store printed warnings for each SAX parser used - private static final CopyOnWriteArrayList<String> printedWarnings = new CopyOnWriteArrayList<>(); - - /** - * Prints out warnings if a parser does not support the specified feature/property. - * - * @param parserClassName the name of the parser class - * @param propertyName the property name - * @param exception the exception thrown by the parser - */ - public static void printWarning(String parserClassName, String propertyName, SAXException exception) { - String key = parserClassName+":"+propertyName; - if (printedWarnings.addIfAbsent(key)) { - System.err.println( "Warning: "+parserClassName+": "+exception.getMessage()); - } - } - - /** - * Read from system properties, or those in jaxp.properties - * - * @param property the type of the property - * @param sysPropertyName the name of system property - */ - private boolean getSystemProperty(Limit limit, String sysPropertyName) { - try { - String value = SecuritySupport.getSystemProperty(sysPropertyName); - if (value != null && !value.equals("")) { - values[limit.ordinal()] = Integer.parseInt(value); - states[limit.ordinal()] = State.SYSTEMPROPERTY; - return true; - } - - value = SecuritySupport.readJAXPProperty(sysPropertyName); - if (value != null && !value.equals("")) { - values[limit.ordinal()] = Integer.parseInt(value); - states[limit.ordinal()] = State.JAXPDOTPROPERTIES; - return true; - } - } catch (NumberFormatException e) { - //invalid setting - throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty()); - } - return false; - } -}
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java index 5a78f2b..400b940 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,7 +23,6 @@ import com.sun.java_cup.internal.runtime.Symbol; import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; -import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; @@ -45,6 +44,7 @@ import jdk.xml.internal.JdkXmlFeatures; import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.SecuritySupport; +import jdk.xml.internal.XMLSecurityManager; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; @@ -61,7 +61,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author Erwin Bolwidt <ejb@klomp.org> - * @LastModified: Nov 2017 + * @LastModified: Jan 2022 */ public class Parser implements Constants, ContentHandler { @@ -494,8 +494,10 @@ XMLSecurityManager securityManager = (XMLSecurityManager)_xsltc.getProperty(XalanConstants.SECURITY_MANAGER); for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { - lastProperty = limit.apiProperty(); - reader.setProperty(lastProperty, securityManager.getLimitValueAsString(limit)); + if (limit.isSupported(XMLSecurityManager.Processor.PARSER)) { + lastProperty = limit.apiProperty(); + reader.setProperty(lastProperty, securityManager.getLimitValueAsString(limit)); + } } if (securityManager.printEntityCountInfo()) { lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO; @@ -1159,6 +1161,9 @@ expression, parent)); } catch (Exception e) { + if (ErrorMsg.XPATH_LIMIT.equals(e.getMessage())) { + throw new RuntimeException(ErrorMsg.XPATH_LIMIT); + } if (_xsltc.debug()) e.printStackTrace(); reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR, expression, parent));
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java index ab12a27..7905c99 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XPathParser.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,14 +34,21 @@ import java.util.ArrayList; import java.util.List; import java.util.Stack; +import com.sun.org.apache.xalan.internal.XalanConstants; +import jdk.xml.internal.XMLLimitAnalyzer; +import jdk.xml.internal.XMLSecurityManager; +import jdk.xml.internal.XMLSecurityManager.Limit; /** * CUP v0.11b generated parser. * This class was generated by CUP v0.11b on Nov 12, 2019. * - * @LastModified: Nov 2019 + * @LastModified: Jan 2022 */ public class XPathParser extends lr_parser { + private int grpLimit = 0; + private int opLimit = 0; + private int totalOpLimit = 0; /** * Default constructor. @@ -953,10 +960,19 @@ */ public SymbolTable _symbolTable; + private XMLSecurityManager _xmlSM; + private XMLLimitAnalyzer _limitAnalyzer = null; + public XPathParser(Parser parser) { _parser = parser; _xsltc = parser.getXSLTC(); _symbolTable = parser.getSymbolTable(); + _xmlSM = (XMLSecurityManager)_xsltc.getProperty(XalanConstants.SECURITY_MANAGER); + _limitAnalyzer = new XMLLimitAnalyzer(); + // no limits if _xmlSM is null + grpLimit = (_xmlSM != null) ? _xmlSM.getLimit(Limit.XPATH_GROUP_LIMIT) : 0; + opLimit = (_xmlSM != null) ? _xmlSM.getLimit(Limit.XPATH_OP_LIMIT) : 0; + totalOpLimit = (_xmlSM != null) ? _xmlSM.getLimit(Limit.XPATH_TOTALOP_LIMIT) : 0; } public int getLineNumber() { @@ -1101,7 +1117,32 @@ try { _expression = expression; _lineNumber = lineNumber; - return super.parse(); + Symbol s = super.parse(); + int grpCount = getCount(ID_GROUP); + int opCount = getCount(ID_OPERATOR); + int totalOpCount = getCount(ID_TOTAL_OPERATOR); + + String errCode = null; + Object[] params = null; + if (grpLimit > 0 && grpCount > grpLimit) { + errCode = ErrorMsg.XPATH_GROUP_LIMIT; + params = new Object[]{grpCount, grpLimit, + _xmlSM.getStateLiteral(Limit.XPATH_GROUP_LIMIT)}; + } else if (opLimit > 0 && opCount > opLimit) { + errCode = ErrorMsg.XPATH_OPERATOR_LIMIT; + params = new Object[]{opCount, opLimit, + _xmlSM.getStateLiteral(Limit.XPATH_OP_LIMIT)}; + } else if (totalOpLimit > 0 && totalOpCount > totalOpLimit) { + errCode = ErrorMsg.XPATH_TOTAL_OPERATOR_LIMIT; + params = new Object[]{totalOpCount, totalOpLimit, + _xmlSM.getStateLiteral(Limit.XPATH_TOTALOP_LIMIT)}; + } + if (errCode != null) { + _parser.reportError(Constants.FATAL, + new ErrorMsg(errCode, lineNumber, params)); + throw new RuntimeException(ErrorMsg.XPATH_LIMIT); + } + return s; } catch (IllegalCharException e) { ErrorMsg err = new ErrorMsg(ErrorMsg.ILLEGAL_CHAR_ERR, lineNumber, e.getMessage());
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java index 5159c6a..71fb527 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,7 +22,6 @@ import com.sun.org.apache.bcel.internal.classfile.JavaClass; import com.sun.org.apache.xalan.internal.XalanConstants; -import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; import com.sun.org.apache.xml.internal.dtm.DTM; @@ -49,6 +48,7 @@ import jdk.xml.internal.JdkXmlFeatures; import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.SecuritySupport; +import jdk.xml.internal.XMLSecurityManager; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; @@ -58,7 +58,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author John Howard (johnh@schemasoft.com) - * @LastModified: Oct 2017 + * @LastModified: Jan 2022 */ public final class XSLTC { @@ -505,7 +505,10 @@ } } catch (Exception e) { - /*if (_debug)*/ e.printStackTrace(); + if (_debug) e.printStackTrace(); + if (ErrorMsg.XPATH_LIMIT.equals(e.getMessage())) { + return !_parser.errorsFound(); + } _parser.reportError(Constants.FATAL, new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR, e)); } catch (Error e) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java index 843521e..be41e5d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/sym.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,13 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler; +import java.util.Arrays; + /** * CUP generated class containing symbol constants. * This class was generated by CUP v0.10j on Fri Feb 27 13:01:50 PST 2004. + * + * @LastModified: Jan 2022 */ public class sym { /* terminals */ @@ -85,4 +89,12 @@ public static final int ATTRIBUTE = 41; public static final int GT = 19; public static final int NODE = 31; + /* + AXES: count once at DCOLON, + these axes names are therefore not counted: + NAMESPACE, FOLLOWINGSIBLING, CHILD, DESCENDANTORSELF, DESCENDANT + , PRECEDINGSIBLING, SELF, ANCESTORORSELF, PRECEDING, ANCESTOROR, PARENT, FOLLOWING, ATTRIBUTE + */ + public static final int[] OPERATORS = {GE, SLASH, ATSIGN, LPAREN, DCOLON, + MINUS, STAR, LT, OR, DIV, PLUS, LE, VBAR, MOD, EQ, LBRACK, DOLLAR, NE, GT}; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java index 581d3cc..0c20a0a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,6 +24,7 @@ /** * @author Morten Jorgensen + * @LastModified: Jan 2022 */ public class ErrorMessages extends ListResourceBundle { @@ -1027,12 +1028,22 @@ "smaller templates." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "When Java security is enabled, " + - "support for deserializing TemplatesImpl is disabled." + - "This can be overridden by setting the jdk.xml.enableTemplatesImplDeserialization" + - " system property to true."} + {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "When Java security is enabled, " + + "support for deserializing TemplatesImpl is disabled. This can be " + + "overridden by setting the jdk.xml.enableTemplatesImplDeserialization" + + " system property to true."}, - }; + {ErrorMsg.XPATH_GROUP_LIMIT, + "JAXP0801001: the compiler encountered an XPath expression containing " + + "''{0}'' groups that exceeds the ''{1}'' limit set by ''{2}''."}, + + {ErrorMsg.XPATH_OPERATOR_LIMIT, + "JAXP0801002: the compiler encountered an XPath expression containing " + + "''{0}'' operators that exceeds the ''{1}'' limit set by ''{2}''."}, + {ErrorMsg.XPATH_TOTAL_OPERATOR_LIMIT, + "JAXP0801003: the compiler encountered XPath expressions with an accumulated " + + "''{0}'' operators that exceeds the ''{1}'' limit set by ''{2}''."}, + }; } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java index e66c090..698cbad 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -33,7 +33,7 @@ * @author G. Todd Miller * @author Erwin Bolwidt <ejb@klomp.org> * @author Morten Jorgensen - * @LastModified: Sep 2017 + * @LastModified: Jan 2022 */ public final class ErrorMsg { @@ -171,6 +171,11 @@ public static final String DESERIALIZE_TRANSLET_ERR = "DESERIALIZE_TEMPLATES_ERR"; + public static final String XPATH_LIMIT = "XPATH_LIMIT"; + public static final String XPATH_GROUP_LIMIT = "XPATH_GROUP_LIMIT"; + public static final String XPATH_OPERATOR_LIMIT = "XPATH_OPERATOR_LIMIT"; + public static final String XPATH_TOTAL_OPERATOR_LIMIT = "XPATH_TOTAL_OPERATOR_LIMIT"; + // All error messages are localized and are stored in resource bundles. // This array and the following 4 strings are read from that bundle. private static ResourceBundle _bundle; @@ -207,7 +212,11 @@ public ErrorMsg(String code, int line, Object param) { _code = code; _line = line; - _params = new Object[] { param }; + if (param instanceof Object[]) { + _params = (Object[])param; + } else { + _params = new Object[] { param }; + } } public ErrorMsg(String code, Object param) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java index e0aa231..9d705b7 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/LoadDocument.java
@@ -39,7 +39,7 @@ /** * @author Morten Jorgensen - * @LastModified: Sep 2017 + * @LastModified: Sept 2021 */ public final class LoadDocument { @@ -190,6 +190,9 @@ if (cache != null) { newdom = cache.retrieveDocument(base, originalUri, translet); if (newdom == null) { + if (translet.getAccessError() != null) { + throw new Exception(translet.getAccessError()); + } final Exception e = new FileNotFoundException(originalUri); throw new TransletException(e); }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java index 27fab8c..0f27ab0 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java
@@ -54,7 +54,7 @@ * @author Morten Jorgensen * @author G. Todd Miller * @author John Howard, JohnH@schemasoft.com - * @LastModified: Oct 2017 + * @LastModified: Sept 2021 */ public abstract class AbstractTranslet implements Translet { @@ -116,6 +116,9 @@ */ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + // The error message when access to exteranl resources is rejected + private String _accessErr = null; + /************************************************************************ * Debugging ************************************************************************/ @@ -786,6 +789,20 @@ _accessExternalStylesheet = protocols; } + /** + * Returns the access error. + */ + public String getAccessError() { + return _accessErr; + } + + /** + * Sets the access error. + */ + public void setAccessError(String accessErr) { + this._accessErr = accessErr; + } + /************************************************************************ * DOMImplementation caching for basis library ************************************************************************/
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index eda5ac3..82e5f0e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
@@ -23,7 +23,7 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; -import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; +import jdk.xml.internal.XMLSecurityManager; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property; import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java index c23477f..8f232b8 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,7 +21,6 @@ package com.sun.org.apache.xalan.internal.xsltc.trax; import com.sun.org.apache.xalan.internal.XalanConstants; -import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.DOM; import com.sun.org.apache.xalan.internal.xsltc.DOMCache; import com.sun.org.apache.xalan.internal.xsltc.StripFilter; @@ -82,6 +81,8 @@ import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import jdk.xml.internal.JdkXmlFeatures; +import jdk.xml.internal.XMLSecurityManager; +import jdk.xml.internal.SecuritySupport; import jdk.xml.internal.JdkXmlUtils; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; @@ -93,7 +94,7 @@ * @author Morten Jorgensen * @author G. Todd Miller * @author Santiago Pericas-Geertsen - * @LastModified: Feb 2019 + * @LastModified: Jan 2022 */ public final class TransformerImpl extends Transformer implements DOMCache, ErrorListener @@ -1338,8 +1339,33 @@ } if (resolvedSource == null) { - StreamSource streamSource = new StreamSource( - SystemIDResolver.getAbsoluteURI(href, baseURI)); + /** + * Uses the translet to carry over error msg. + * Performs the access check without any interface changes + * (e.g. Translet and DOMCache). + */ + @SuppressWarnings("unchecked") //AbstractTranslet is the sole impl. + AbstractTranslet t = (AbstractTranslet)translet; + String systemId = SystemIDResolver.getAbsoluteURI(href, baseURI); + String errMsg = null; + try { + String accessError = SecuritySupport.checkAccess(systemId, + t.getAllowedProtocols(), + XalanConstants.ACCESS_EXTERNAL_ALL); + if (accessError != null) { + ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR, + SecuritySupport.sanitizePath(href), accessError); + errMsg = msg.toString(); + } + } catch (IOException ioe) { + errMsg = ioe.getMessage(); + } + if (errMsg != null) { + t.setAccessError(errMsg); + return null; + } + + StreamSource streamSource = new StreamSource(systemId); return getDOM(streamSource) ; }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java index 8c6f103..8790178 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,7 +21,6 @@ package com.sun.org.apache.xalan.internal.xsltc.trax; import com.sun.org.apache.xalan.internal.XalanConstants; -import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import java.io.InputStream; @@ -39,6 +38,7 @@ import javax.xml.transform.stream.StreamSource; import jdk.xml.internal.JdkXmlFeatures; import jdk.xml.internal.JdkXmlUtils; +import jdk.xml.internal.XMLSecurityManager; import jdk.xml.internal.SecuritySupport; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -112,9 +112,11 @@ (XMLSecurityManager)xsltc.getProperty(XalanConstants.SECURITY_MANAGER); if (securityManager != null) { for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { - lastProperty = limit.apiProperty(); - reader.setProperty(lastProperty, - securityManager.getLimitValueAsString(limit)); + if (limit.isSupported(XMLSecurityManager.Processor.PARSER)) { + lastProperty = limit.apiProperty(); + reader.setProperty(lastProperty, + securityManager.getLimitValueAsString(limit)); + } } if (securityManager.printEntityCountInfo()) { lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java index 5894424..9804314 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java index e9b2fb3..4421bdd 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,7 +42,7 @@ * @xerces.internal * * @since PR-DOM-Level-1-19980818. - * @LastModified: Oct 2017 + * @LastModified: May 2019 */ public class DeferredDocumentImpl extends DocumentImpl @@ -69,7 +69,7 @@ // protected /** Chunk shift. */ - protected static final int CHUNK_SHIFT = 11; // 2^11 = 2k + protected static final int CHUNK_SHIFT = 8; // 2^8 = 256 /** Chunk size. */ protected static final int CHUNK_SIZE = (1 << CHUNK_SHIFT); @@ -78,7 +78,7 @@ protected static final int CHUNK_MASK = CHUNK_SIZE - 1; /** Initial chunk size. */ - protected static final int INITIAL_CHUNK_COUNT = (1 << (16 - CHUNK_SHIFT)); // 2^16 = 64k + protected static final int INITIAL_CHUNK_COUNT = (1 << (13 - CHUNK_SHIFT)); // 32 // // Data
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java index ca2a5b1..85dba51 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java index e0f808d..c0e19f8 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java index 1ec084e..67f6478 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -54,7 +54,7 @@ * @author Andy Clark, IBM * @author Arnaud Le Hors, IBM * @author Eric Ye, IBM - * + * @LastModified: Aug 2021 */ public class XML11DocumentScannerImpl extends XMLDocumentScannerImpl { @@ -278,16 +278,6 @@ + fStringBuffer.toString() + "\""); } } - // note that none of these characters should ever get through - // XML11EntityScanner. Not sure why - // this check was originally necessary. - NG - else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) { - fEntityScanner.scanChar(null); - fStringBuffer.append(' '); - if (entityDepth == fEntityDepth) { - fStringBuffer2.append('\n'); - } - } else if (c != -1 && XMLChar.isHighSurrogate(c)) { fStringBuffer3.clear(); if (scanSurrogates(fStringBuffer3)) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java index 4be8d68..332aeb5 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
@@ -21,6 +21,7 @@ package com.sun.org.apache.xerces.internal.impl; +import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_1; import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.util.XML11Char; @@ -40,7 +41,7 @@ * @author Michael Glavassevich, IBM * @author Neil Graham, IBM * - * @LastModified: Apr 2021 + * @LastModified: Aug 2021 */ public class XML11EntityScanner @@ -116,7 +117,7 @@ load(1, false, false); offset = 0; } - if (c == '\r' && external) { + if (c == '\r' && external && fCurrentEntity.position < fCurrentEntity.count) { int cc = fCurrentEntity.ch[fCurrentEntity.position++]; if (cc != '\n' && cc != 0x85) { fCurrentEntity.position--; @@ -761,71 +762,12 @@ } // normalize newlines - int offset = fCurrentEntity.position; - int c = fCurrentEntity.ch[offset]; - int newlines = 0; - boolean counted = false; - boolean external = fCurrentEntity.isExternal(); - if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { - do { - c = fCurrentEntity.ch[fCurrentEntity.position++]; - if ((c == '\r' ) && external) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - checkEntityLimit(null, fCurrentEntity, offset, newlines); - offset = 0; - fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); - fCurrentEntity.position = newlines; - fCurrentEntity.startPosition = newlines; - if (load(newlines, false, true)) { - counted = true; - break; - } - } - int cc = fCurrentEntity.ch[fCurrentEntity.position]; - if (cc == '\n' || cc == 0x85) { - fCurrentEntity.position++; - offset++; - } - /*** NEWLINE NORMALIZATION ***/ - else { - newlines++; - } - } - else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - checkEntityLimit(null, fCurrentEntity, offset, newlines); - offset = 0; - fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); - fCurrentEntity.position = newlines; - fCurrentEntity.startPosition = newlines; - if (load(newlines, false, true)) { - counted = true; - break; - } - } - } - else { - fCurrentEntity.position--; - break; - } - } while (fCurrentEntity.position < fCurrentEntity.count - 1); - for (int i = offset; i < fCurrentEntity.position; i++) { - fCurrentEntity.ch[i] = '\n'; - } - int length = fCurrentEntity.position - offset; - if (fCurrentEntity.position == fCurrentEntity.count - 1) { - checkEntityLimit(null, fCurrentEntity, offset, length); - content.setValues(fCurrentEntity.ch, offset, length); - return -1; - } + if (normalizeNewlines(XML_VERSION_1_1, content, false, false, null)) { + return -1; } + int c; + boolean external = fCurrentEntity.isExternal(); // inner loop, scanning for content if (external) { while (fCurrentEntity.position < fCurrentEntity.count) { @@ -913,65 +855,12 @@ } // normalize newlines - int offset = fCurrentEntity.position; - int c = fCurrentEntity.ch[offset]; - int newlines = 0; - boolean external = fCurrentEntity.isExternal(); - if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { - do { - c = fCurrentEntity.ch[fCurrentEntity.position++]; - if ((c == '\r' ) && external) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); - fCurrentEntity.position = newlines; - fCurrentEntity.startPosition = newlines; - if (load(newlines, false, true)) { - break; - } - } - int cc = fCurrentEntity.ch[fCurrentEntity.position]; - if (cc == '\n' || cc == 0x85) { - fCurrentEntity.position++; - offset++; - } - /*** NEWLINE NORMALIZATION ***/ - else { - newlines++; - } - } - else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); - fCurrentEntity.position = newlines; - fCurrentEntity.startPosition = newlines; - if (load(newlines, false, true)) { - break; - } - } - } - else { - fCurrentEntity.position--; - break; - } - } while (fCurrentEntity.position < fCurrentEntity.count - 1); - for (int i = offset; i < fCurrentEntity.position; i++) { - fCurrentEntity.ch[i] = '\n'; - } - int length = fCurrentEntity.position - offset; - if (fCurrentEntity.position == fCurrentEntity.count - 1) { - content.setValues(fCurrentEntity.ch, offset, length); - return -1; - } + if (normalizeNewlines(XML_VERSION_1_1, content, false, true, null)) { + return -1; } + int c; + boolean external = fCurrentEntity.isExternal(); // scan literal value if (external) { while (fCurrentEntity.position < fCurrentEntity.count) { @@ -1093,66 +982,11 @@ } // normalize newlines - int offset = fCurrentEntity.position; - int c = fCurrentEntity.ch[offset]; - int newlines = 0; - if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { - do { - c = fCurrentEntity.ch[fCurrentEntity.position++]; - if ((c == '\r' ) && external) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); - fCurrentEntity.position = newlines; - fCurrentEntity.startPosition = newlines; - if (load(newlines, false, true)) { - break; - } - } - int cc = fCurrentEntity.ch[fCurrentEntity.position]; - if (cc == '\n' || cc == 0x85) { - fCurrentEntity.position++; - offset++; - } - /*** NEWLINE NORMALIZATION ***/ - else { - newlines++; - } - } - else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); - fCurrentEntity.position = newlines; - fCurrentEntity.startPosition = newlines; - fCurrentEntity.count = newlines; - if (load(newlines, false, true)) { - break; - } - } - } - else { - fCurrentEntity.position--; - break; - } - } while (fCurrentEntity.position < fCurrentEntity.count - 1); - for (int i = offset; i < fCurrentEntity.position; i++) { - fCurrentEntity.ch[i] = '\n'; - } - int length = fCurrentEntity.position - offset; - if (fCurrentEntity.position == fCurrentEntity.count - 1) { - checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); - buffer.append(fCurrentEntity.ch, offset, length); - return true; - } + if (normalizeNewlines(XML_VERSION_1_1, buffer, true, false, NameType.COMMENT)) { + return true; } + int c; // iterate over buffer looking for delimiter OUTER: while (fCurrentEntity.position < fCurrentEntity.count) { c = fCurrentEntity.ch[fCurrentEntity.position++]; @@ -1256,22 +1090,6 @@ checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); return true; } - else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) { - // handle newlines - if (fCurrentEntity.position == fCurrentEntity.count) { - invokeListeners(1); - fCurrentEntity.ch[0] = (char)cc; - load(1, false, false); - } - int ccc = fCurrentEntity.ch[++fCurrentEntity.position]; - if (ccc == '\n' || ccc == 0x85) { - fCurrentEntity.position++; - } - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); - return true; - } // character was not skipped return false;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index 38c32f1..b7a7f1f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
@@ -90,7 +90,7 @@ * @author K.Venugopal SUN Microsystems * @author Neeraj Bajaj SUN Microsystems * @author Sunitha Reddy SUN Microsystems - * @LastModified: Apr 2019 + * @LastModified: Aug 2021 */ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { @@ -1234,7 +1234,7 @@ externalEntity = (Entity.ExternalEntity)entity; extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null); extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null); - expandedSystemId = expandSystemId(extLitSysId, extBaseSysId); + expandedSystemId = expandSystemId(extLitSysId, extBaseSysId, fStrictURI); boolean unparsed = entity.isUnparsed(); boolean parameter = entityName.startsWith("%"); boolean general = !parameter; @@ -1311,15 +1311,13 @@ */ xmlInputSource = staxInputSource.getXMLInputSource() ; if (!fISCreatedByResolver) { - //let the not-LoadExternalDTD or not-SupportDTD process to handle the situation - if (fLoadExternalDTD) { - String accessError = SecuritySupport.checkAccess(expandedSystemId, fAccessExternalDTD, Constants.ACCESS_EXTERNAL_ALL); - if (accessError != null) { - fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, - "AccessExternalEntity", - new Object[] { SecuritySupport.sanitizePath(expandedSystemId), accessError }, - XMLErrorReporter.SEVERITY_FATAL_ERROR); - } + String accessError = SecuritySupport.checkAccess(expandedSystemId, + fAccessExternalDTD, Constants.ACCESS_EXTERNAL_ALL); + if (accessError != null) { + fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, + "AccessExternalEntity", + new Object[] { SecuritySupport.sanitizePath(expandedSystemId), accessError }, + XMLErrorReporter.SEVERITY_FATAL_ERROR); } } }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java index c48ed8f..33ffe98 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
@@ -21,6 +21,8 @@ package com.sun.org.apache.xerces.internal.impl; +import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_0; +import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_1; import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType; import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader; @@ -55,7 +57,7 @@ * @author Arnaud Le Hors, IBM * @author K.Venugopal Sun Microsystems * - * @LastModified: Apr 2021 + * @LastModified: Sep 2021 */ public class XMLEntityScanner implements XMLLocator { @@ -149,6 +151,15 @@ // indicates that the operation is for detecting XML version boolean detectingVersion = false; + // offset of the current cursor position + int offset = 0; + + // number of newlines in the current process + int newlines = 0; + + // indicating whether the content has been counted towards limit + boolean counted = false; + // // Constructors // @@ -553,7 +564,7 @@ } // scan character - int offset = fCurrentEntity.position; + offset = fCurrentEntity.position; int c = fCurrentEntity.ch[fCurrentEntity.position++]; if (c == '\n' || (c == '\r' && isExternal)) { fCurrentEntity.lineNumber++; @@ -561,10 +572,10 @@ if (fCurrentEntity.position == fCurrentEntity.count) { invokeListeners(1); fCurrentEntity.ch[0] = (char)c; - load(1, false, false); + load(1, true, false); offset = 0; } - if (c == '\r' && isExternal) { + if (c == '\r' && isExternal && fCurrentEntity.position < fCurrentEntity.count) { if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') { fCurrentEntity.position--; } @@ -614,7 +625,7 @@ } // scan nmtoken - int offset = fCurrentEntity.position; + offset = fCurrentEntity.position; boolean vc = false; char c; while (true){ @@ -695,7 +706,7 @@ } // scan name - int offset = fCurrentEntity.position; + offset = fCurrentEntity.position; int length; if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) { if (++fCurrentEntity.position == fCurrentEntity.count) { @@ -788,7 +799,7 @@ } // scan qualified name - int offset = fCurrentEntity.position; + offset = fCurrentEntity.position; //making a check if if the specified character is a valid name start character //as defined by production [5] in the XML 1.0 specification. @@ -1043,81 +1054,11 @@ } // normalize newlines - int offset = fCurrentEntity.position; - int c = fCurrentEntity.ch[offset]; - int newlines = 0; - boolean counted = false; - if (c == '\n' || (c == '\r' && isExternal)) { - if (DEBUG_BUFFER) { - System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } - do { - c = fCurrentEntity.ch[fCurrentEntity.position++]; - if (c == '\r' && isExternal) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - checkEntityLimit(null, fCurrentEntity, offset, newlines); - offset = 0; - fCurrentEntity.position = newlines; - if (load(newlines, false, true)) { - counted = true; - break; - } - } - if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') { - fCurrentEntity.position++; - offset++; - } - /*** NEWLINE NORMALIZATION ***/ - else { - newlines++; - } - } else if (c == '\n') { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - checkEntityLimit(null, fCurrentEntity, offset, newlines); - offset = 0; - fCurrentEntity.position = newlines; - if (load(newlines, false, true)) { - counted = true; - break; - } - } - } else { - fCurrentEntity.position--; - break; - } - } while (fCurrentEntity.position < fCurrentEntity.count - 1); - for (int i = offset; i < fCurrentEntity.position; i++) { - fCurrentEntity.ch[i] = '\n'; - } - int length = fCurrentEntity.position - offset; - if (fCurrentEntity.position == fCurrentEntity.count - 1) { - checkEntityLimit(null, fCurrentEntity, offset, length); - //CHANGED: dont replace the value.. append to the buffer. This gives control to the callee - //on buffering the data.. - content.setValues(fCurrentEntity.ch, offset, length); - //content.append(fCurrentEntity.ch, offset, length); - if (DEBUG_BUFFER) { - System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } - return -1; - } - if (DEBUG_BUFFER) { - System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } + if (normalizeNewlines(XML_VERSION_1_0, content, false, false, null)) { + return -1; } + int c; while (fCurrentEntity.position < fCurrentEntity.count) { c = fCurrentEntity.ch[fCurrentEntity.position++]; if (!XMLChar.isContent(c)) { @@ -1202,85 +1143,14 @@ } // normalize newlines - int offset = fCurrentEntity.position; - int c = fCurrentEntity.ch[offset]; - int newlines = 0; if(whiteSpaceInfoNeeded) whiteSpaceLen=0; - if (c == '\n' || (c == '\r' && isExternal)) { - if (DEBUG_BUFFER) { - System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } - do { - c = fCurrentEntity.ch[fCurrentEntity.position++]; - if (c == '\r' && isExternal) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.position = newlines; - if (load(newlines, false, true)) { - break; - } - } - if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') { - fCurrentEntity.position++; - offset++; - } - /*** NEWLINE NORMALIZATION ***/ - else { - newlines++; - } - /***/ - } else if (c == '\n') { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.position = newlines; - if (load(newlines, false, true)) { - break; - } - } - /*** NEWLINE NORMALIZATION *** - * if (fCurrentEntity.ch[fCurrentEntity.position] == '\r' - * && external) { - * fCurrentEntity.position++; - * offset++; - * } - * /***/ - } else { - fCurrentEntity.position--; - break; - } - } while (fCurrentEntity.position < fCurrentEntity.count - 1); - int i=0; - for ( i = offset; i < fCurrentEntity.position; i++) { - fCurrentEntity.ch[i] = '\n'; - storeWhiteSpace(i); - } - int length = fCurrentEntity.position - offset; - if (fCurrentEntity.position == fCurrentEntity.count - 1) { - content.setValues(fCurrentEntity.ch, offset, length); - if (DEBUG_BUFFER) { - System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } - return -1; - } - if (DEBUG_BUFFER) { - System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } + if (normalizeNewlines(XML_VERSION_1_0, content, false, true, null)) { + return -1; } + int c; // scan literal value for (; fCurrentEntity.position<fCurrentEntity.count; fCurrentEntity.position++) { c = fCurrentEntity.ch[fCurrentEntity.position]; @@ -1331,7 +1201,7 @@ * * @param whiteSpacePos position of a whitespace in the scanner entity buffer */ - private void storeWhiteSpace(int whiteSpacePos) { + void storeWhiteSpace(int whiteSpacePos) { if (whiteSpaceLen >= whiteSpaceLookup.length) { int [] tmp = new int[whiteSpaceLookup.length + 100]; System.arraycopy(whiteSpaceLookup, 0, tmp, 0, whiteSpaceLookup.length); @@ -1415,75 +1285,11 @@ return false; } - // normalize newlines - int offset = fCurrentEntity.position; - int c = fCurrentEntity.ch[offset]; - int newlines = 0; - if (c == '\n' || (c == '\r' && isExternal)) { - if (DEBUG_BUFFER) { - System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } - do { - c = fCurrentEntity.ch[fCurrentEntity.position++]; - if (c == '\r' && isExternal) { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.position = newlines; - if (load(newlines, false, true)) { - break; - } - } - if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') { - fCurrentEntity.position++; - offset++; - } - /*** NEWLINE NORMALIZATION ***/ - else { - newlines++; - } - } else if (c == '\n') { - newlines++; - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (fCurrentEntity.position == fCurrentEntity.count) { - offset = 0; - fCurrentEntity.position = newlines; - fCurrentEntity.count = newlines; - if (load(newlines, false, true)) { - break; - } - } - } else { - fCurrentEntity.position--; - break; - } - } while (fCurrentEntity.position < fCurrentEntity.count - 1); - for (int i = offset; i < fCurrentEntity.position; i++) { - fCurrentEntity.ch[i] = '\n'; - } - int length = fCurrentEntity.position - offset; - if (fCurrentEntity.position == fCurrentEntity.count - 1) { - checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); - buffer.append(fCurrentEntity.ch, offset, length); - if (DEBUG_BUFFER) { - System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } - return true; - } - if (DEBUG_BUFFER) { - System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); - print(); - System.out.println(); - } + if (normalizeNewlines(XML_VERSION_1_0, buffer, true, false, NameType.COMMENT)) { + return true; } + int c; // iterate over buffer looking for delimiter OUTER: while (fCurrentEntity.position < fCurrentEntity.count) { c = fCurrentEntity.ch[fCurrentEntity.position++]; @@ -1570,7 +1376,7 @@ } // skip character - int offset = fCurrentEntity.position; + offset = fCurrentEntity.position; int cc = fCurrentEntity.ch[fCurrentEntity.position]; if (cc == c) { fCurrentEntity.position++; @@ -1587,26 +1393,6 @@ } checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); return true; - } else if (c == '\n' && cc == '\r' && isExternal) { - // handle newlines - if (fCurrentEntity.position == fCurrentEntity.count) { - invokeListeners(1); - fCurrentEntity.ch[0] = (char)cc; - load(1, false, false); - } - fCurrentEntity.position++; - if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') { - fCurrentEntity.position++; - } - fCurrentEntity.lineNumber++; - fCurrentEntity.columnNumber = 1; - if (DEBUG_BUFFER) { - System.out.print(")skipChar, '"+(char)c+"': "); - print(); - System.out.println(" -> true"); - } - checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); - return true; } // character was not skipped @@ -1659,7 +1445,7 @@ // skip spaces int c = fCurrentEntity.ch[fCurrentEntity.position]; - int offset = fCurrentEntity.position - 1; + offset = fCurrentEntity.position - 1; if (XMLChar.isSpace(c)) { do { boolean entityChanged = false; @@ -2332,5 +2118,86 @@ } // skipDeclSpaces():boolean + /** + * Normalizes newlines. As specified in XML specification, this method + * converts newlines, '\n', '\r' and '\r\n' to '\n' as 2.11 End-of-Line Handling. + * Further, it may put them in a cache for later process as needed, for example + * as specified in 3.3.3 Attribute-Value Normalization. + * + * @ImplNote this method does not limit to processing external parsed entities + * as 2.11 required. It handles all cases where newlines need to be processed. + * + * @param buffer the current content buffer + * @param append a flag indicating whether to append to the buffer + * @param storeWS a flag indicating whether the whitespaces need to be stored + * for later processing + * @param nt the type of the entity + * @return true if the cursor is at the end of the current entity, false otherwise. + * @throws IOException + */ + protected boolean normalizeNewlines(short version, XMLString buffer, boolean append, + boolean storeWS, NameType nt) + throws IOException { + // normalize newlines + offset = fCurrentEntity.position; + int c = fCurrentEntity.ch[offset]; + newlines = 0; + // how this information is used is determined by the caller of this method + counted = false; + if ((c == '\n' || c == '\r') || + (version == XML_VERSION_1_1 && (c == 0x85 || c == 0x2028) && isExternal)) { + do { + c = fCurrentEntity.ch[fCurrentEntity.position++]; + if ((c == '\n' || c == '\r') || + (version == XML_VERSION_1_1 && (c == 0x85 || c == 0x2028))) { + newlines++; + fCurrentEntity.lineNumber++; + fCurrentEntity.columnNumber = 1; + if (fCurrentEntity.position == fCurrentEntity.count) { + checkEntityLimit(nt, fCurrentEntity, offset, newlines); + offset = 0; + fCurrentEntity.position = newlines; + if (load(newlines, false, true)) { + counted = true; + break; + } + } + if (c == '\r') { + int cc = fCurrentEntity.ch[fCurrentEntity.position]; + if (cc == '\n' || (version == XML_VERSION_1_1 && cc == 0x85)) { + fCurrentEntity.position++; + offset++; + } + /*** NEWLINE NORMALIZATION ***/ + else { + newlines++; + } + } + } else { + fCurrentEntity.position--; + break; + } + } while (fCurrentEntity.position < fCurrentEntity.count - 1); + for (int i = offset; i < fCurrentEntity.position; i++) { + fCurrentEntity.ch[i] = '\n'; + if (storeWS) { + storeWhiteSpace(i); + } + } + + int length = fCurrentEntity.position - offset; + if (fCurrentEntity.position == fCurrentEntity.count - 1) { + checkEntityLimit(nt, fCurrentEntity, offset, length); + if (append) { + buffer.append(fCurrentEntity.ch, offset, length); + } else { + buffer.setValues(fCurrentEntity.ch, offset, length); + } + + return true; + } + } + return false; + } } // class XMLEntityScanner
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index 6a63621..2102b85 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -67,7 +67,7 @@ * @author Eric Ye, IBM * @author K.Venugopal SUN Microsystems * @author Sunitha Reddy, SUN Microsystems - * @LastModified: Feb 2020 + * @LastModified: Aug 2021 */ public abstract class XMLScanner implements XMLComponent { @@ -956,12 +956,6 @@ System.out.println("** valueF: \"" + stringBuffer.toString() + "\""); } - } else if (c == '\n' || c == '\r') { - fEntityScanner.scanChar(null); - stringBuffer.append(' '); - if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { - fStringBuffer2.append('\n'); - } } else if (c != -1 && XMLChar.isHighSurrogate(c)) { fStringBuffer3.clear(); if (scanSurrogates(fStringBuffer3)) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java index 0d49469..827669f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -56,6 +56,7 @@ import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; import java.util.Locale; import java.util.Stack; +import jdk.xml.internal.JdkXmlUtils; import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; @@ -84,7 +85,7 @@ * @author Andy Clark, IBM * @author Elena Litani, IBM * - * @LastModified: Nov 2017 + * @LastModified: July 2021 */ public class AbstractDOMParser extends AbstractXMLDocumentParser { @@ -2031,17 +2032,8 @@ else { fInternalSubset.append (name); } - fInternalSubset.append (' '); - if (publicId != null) { - fInternalSubset.append ("PUBLIC '"); - fInternalSubset.append (publicId); - fInternalSubset.append ("' '"); - } - else { - fInternalSubset.append ("SYSTEM '"); - } - fInternalSubset.append (literalSystemId); - fInternalSubset.append ("'>\n"); + fInternalSubset.append (JdkXmlUtils.getDTDExternalDecl(publicId, literalSystemId)); + fInternalSubset.append (">\n"); } // NOTE: We only know how to create these nodes for the Xerces @@ -2171,20 +2163,8 @@ if (fInternalSubset != null && !fInDTDExternalSubset) { fInternalSubset.append ("<!ENTITY "); fInternalSubset.append (name); - fInternalSubset.append (' '); - if (publicId != null) { - fInternalSubset.append ("PUBLIC '"); - fInternalSubset.append (publicId); - if (literalSystemId != null) { - fInternalSubset.append ("' '"); - fInternalSubset.append (literalSystemId); - } - } - else { - fInternalSubset.append ("SYSTEM '"); - fInternalSubset.append (literalSystemId); - } - fInternalSubset.append ("' NDATA "); + fInternalSubset.append (JdkXmlUtils.getDTDExternalDecl(publicId, literalSystemId)); + fInternalSubset.append (" NDATA "); fInternalSubset.append (notation); fInternalSubset.append (">\n"); } @@ -2251,19 +2231,8 @@ if (fInternalSubset != null && !fInDTDExternalSubset) { fInternalSubset.append ("<!NOTATION "); fInternalSubset.append (name); - if (publicId != null) { - fInternalSubset.append (" PUBLIC '"); - fInternalSubset.append (publicId); - if (literalSystemId != null) { - fInternalSubset.append ("' '"); - fInternalSubset.append (literalSystemId); - } - } - else { - fInternalSubset.append (" SYSTEM '"); - fInternalSubset.append (literalSystemId); - } - fInternalSubset.append ("'>\n"); + fInternalSubset.append (JdkXmlUtils.getDTDExternalDecl(publicId, literalSystemId)); + fInternalSubset.append (">\n"); } // NOTE: We only know how to create these nodes for the Xerces
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java index 9e91573..118aeb7 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLStringBuffer.java
@@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -41,20 +40,12 @@ * * @author Andy Clark, IBM * @author Eric Ye, IBM - * + * @LastModified: Aug 2021 */ public class XMLStringBuffer extends XMLString { // - // Constants - // - - - /** Default buffer size (32). */ - public static final int DEFAULT_SIZE = 32; - - // // Data // @@ -112,79 +103,4 @@ length = 0; } - /** - * append - * - * @param c - */ - public void append(char c) { - if(this.length + 1 > this.ch.length){ - int newLength = this.ch.length * 2 ; - if(newLength < this.ch.length + DEFAULT_SIZE){ - newLength = this.ch.length + DEFAULT_SIZE; - } - char [] tmp = new char[newLength]; - System.arraycopy(this.ch, 0, tmp, 0, this.length); - this.ch = tmp; - } - this.ch[this.length] = c ; - this.length++; - } // append(char) - - /** - * append - * - * @param s - */ - public void append(String s) { - int length = s.length(); - if (this.length + length > this.ch.length) { - int newLength = this.ch.length * 2 ; - if(newLength < this.ch.length + length + DEFAULT_SIZE){ - newLength = this.ch.length + length+ DEFAULT_SIZE; - } - - char[] newch = new char[newLength]; - System.arraycopy(this.ch, 0, newch, 0, this.length); - this.ch = newch; - } - s.getChars(0, length, this.ch, this.length); - this.length += length; - } // append(String) - - /** - * append - * - * @param ch - * @param offset - * @param length - */ - public void append(char[] ch, int offset, int length) { - if (this.length + length > this.ch.length) { - int newLength = this.ch.length * 2 ; - if(newLength < this.ch.length + length + DEFAULT_SIZE){ - newLength = this.ch.length + length + DEFAULT_SIZE; - } - char[] newch = new char[newLength]; - System.arraycopy(this.ch, 0, newch, 0, this.length); - this.ch = newch; - } - //making the code more robust as it would handle null or 0 length data, - //add the data only when it contains some thing - if(ch != null && length > 0){ - System.arraycopy(ch, offset, this.ch, this.length, length); - this.length += length; - } - } // append(char[],int,int) - - /** - * append - * - * @param s - */ - public void append(XMLString s) { - append(s.ch, s.offset, s.length); - } // append(XMLString) - - } // class XMLStringBuffer
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java index f63e1d2..9d26c25 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xni/XMLString.java
@@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,9 +41,11 @@ * * @author Eric Ye, IBM * @author Andy Clark, IBM - * + * @LastModified: Aug 2021 */ public class XMLString { + /** Default buffer size (32). */ + public static final int DEFAULT_SIZE = 32; // // Data @@ -189,4 +190,78 @@ return length > 0 ? new String(ch, offset, length) : ""; } // toString():String + /** + * Appends a char to the buffer. + * + * @param c the char + */ + public void append(char c) { + if(this.length + 1 > this.ch.length){ + int newLength = this.ch.length * 2 ; + if(newLength < this.ch.length + DEFAULT_SIZE){ + newLength = this.ch.length + DEFAULT_SIZE; + } + char [] tmp = new char[newLength]; + System.arraycopy(this.ch, 0, tmp, 0, this.length); + this.ch = tmp; + } + this.ch[this.length] = c ; + this.length++; + } // append(char) + + /** + * Appends a string to the buffer. + * + * @param s the string + */ + public void append(String s) { + int length = s.length(); + if (this.length + length > this.ch.length) { + int newLength = this.ch.length * 2 ; + if(newLength < this.ch.length + length + DEFAULT_SIZE){ + newLength = this.ch.length + length+ DEFAULT_SIZE; + } + + char[] newch = new char[newLength]; + System.arraycopy(this.ch, 0, newch, 0, this.length); + this.ch = newch; + } + s.getChars(0, length, this.ch, this.length); + this.length += length; + } // append(String) + + /** + * Appends a number of characters to the buffer. + * + * @param ch the char array + * @param offset the offset + * @param length the length + */ + public void append(char[] ch, int offset, int length) { + if (this.length + length > this.ch.length) { + int newLength = this.ch.length * 2 ; + if(newLength < this.ch.length + length + DEFAULT_SIZE){ + newLength = this.ch.length + length + DEFAULT_SIZE; + } + char[] newch = new char[newLength]; + System.arraycopy(this.ch, 0, newch, 0, this.length); + this.ch = newch; + } + //making the code more robust as it would handle null or 0 length data, + //add the data only when it contains some thing + if(ch != null && length > 0){ + System.arraycopy(ch, offset, this.ch, this.length, length); + this.length += length; + } + } // append(char[],int,int) + + /** + * Appends another buffer to this buffer + * + * @param s another buffer + */ + public void append(XMLString s) { + append(s.ch, s.offset, s.length); + } // append(XMLString) + } // class XMLString
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/ElementState.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/ElementState.java index 16136db..629878f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/ElementState.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/ElementState.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLSerializer.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLSerializer.java index c0656a7..3ac96fc 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLSerializer.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLSerializer.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLdtd.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLdtd.java index 68f7a89..eb1f99b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLdtd.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/HTMLdtd.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java index 3d63273..f619b32 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java index 791cbb0..11c3508 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java
@@ -30,6 +30,7 @@ import com.sun.org.apache.xml.internal.serializer.utils.MsgKey; import com.sun.org.apache.xml.internal.serializer.utils.Utils; +import jdk.xml.internal.JdkXmlUtils; /** * This serializer takes a series of SAX or @@ -40,7 +41,7 @@ * because it is used from another package. * * @xsl.usage internal - * @LastModified: Sept 2018 + * @LastModified: July 2021 */ public final class ToHTMLStream extends ToStream { @@ -675,28 +676,10 @@ final java.io.Writer writer = m_writer; try { - writer.write("<!DOCTYPE html"); - - if (null != doctypePublic) - { - writer.write(" PUBLIC \""); - writer.write(doctypePublic); - writer.write('"'); - } - - if (null != doctypeSystem) - { - if (null == doctypePublic) - writer.write(" SYSTEM \""); - else - writer.write(" \""); - - writer.write(doctypeSystem); - writer.write('"'); - } - - writer.write('>'); - outputLineSep(); + writer.write("<!DOCTYPE html"); + writer.write(JdkXmlUtils.getDTDExternalDecl(doctypePublic, doctypeSystem)); + writer.write('>'); + outputLineSep(); } catch(IOException e) {
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java index 4ec7747..a7ac797 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java
@@ -53,7 +53,7 @@ * serializers (xml, html, text ...) that write output to a stream. * * @xsl.usage internal - * @LastModified: Apr 2021 + * @LastModified: July 2021 */ abstract public class ToStream extends SerializerBase { @@ -904,16 +904,8 @@ m_writer.write("<!ENTITY "); m_writer.write(name); - if (publicId != null) { - m_writer.write(" PUBLIC \""); - m_writer.write(publicId); - - } - else { - m_writer.write(" SYSTEM \""); - m_writer.write(systemId); - } - m_writer.write("\" >"); + m_writer.write(JdkXmlUtils.getDTDExternalDecl(publicId, systemId)); + m_writer.write(">"); m_writer.write(m_lineSep, 0, m_lineSepLen); } catch (IOException e) { // TODO Auto-generated catch block @@ -1971,27 +1963,11 @@ final Writer writer = m_writer; writer.write("<!DOCTYPE "); writer.write(name); + String systemId = getDoctypeSystem(); + writer.write(JdkXmlUtils.getDTDExternalDecl(getDoctypePublic(), systemId)); - String doctypePublic = getDoctypePublic(); - if (null != doctypePublic) + if (null != systemId) { - writer.write(" PUBLIC \""); - writer.write(doctypePublic); - writer.write('\"'); - } - - String doctypeSystem = getDoctypeSystem(); - if (null != doctypeSystem) - { - char quote = JdkXmlUtils.getQuoteChar(doctypeSystem); - if (null == doctypePublic) { - writer.write(" SYSTEM"); - } - writer.write(" "); - writer.write(quote); - - writer.write(doctypeSystem); - writer.write(quote); if (closeDecl) { writer.write(">"); @@ -1999,17 +1975,6 @@ closeDecl = false; // done closing } } - boolean dothis = false; - if (dothis) - { - // at one point this code seemed right, - // but not anymore - Brian M. - if (closeDecl) - { - writer.write('>'); - writer.write(m_lineSep, 0, m_lineSepLen); - } - } } catch (IOException e) { @@ -3575,16 +3540,8 @@ m_writer.write("<!NOTATION "); m_writer.write(name); - if (pubID != null) { - m_writer.write(" PUBLIC \""); - m_writer.write(pubID); - - } - else { - m_writer.write(" SYSTEM \""); - m_writer.write(sysID); - } - m_writer.write("\" >"); + m_writer.write(JdkXmlUtils.getDTDExternalDecl(pubID, sysID)); + m_writer.write(">"); m_writer.write(m_lineSep, 0, m_lineSepLen); } catch (IOException e) { // TODO Auto-generated catch block @@ -3605,16 +3562,8 @@ m_writer.write("<!ENTITY "); m_writer.write(name); - if (pubID != null) { - m_writer.write(" PUBLIC \""); - m_writer.write(pubID); - - } - else { - m_writer.write(" SYSTEM \""); - m_writer.write(sysID); - } - m_writer.write("\" NDATA "); + m_writer.write(JdkXmlUtils.getDTDExternalDecl(pubID, sysID)); + m_writer.write(" NDATA "); m_writer.write(notationName); m_writer.write(" >"); m_writer.write(m_lineSep, 0, m_lineSepLen);
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOM3TreeWalker.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOM3TreeWalker.java index 519235d..2f7d41a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOM3TreeWalker.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOM3TreeWalker.java
@@ -63,7 +63,7 @@ * parameters and filters if any during serialization. * * @xsl.usage internal - * @LastModified: Apr 2021 + * @LastModified: July 2021 */ final class DOM3TreeWalker { @@ -506,23 +506,7 @@ dtd.append("<!DOCTYPE "); dtd.append(docTypeName); - if (null != publicId) { - dtd.append(" PUBLIC \""); - dtd.append(publicId); - dtd.append('\"'); - } - - if (null != systemId) { - char quote = JdkXmlUtils.getQuoteChar(systemId); - if (null == publicId) { - dtd.append(" SYSTEM ").append(quote); - } else { - dtd.append(" ").append(quote); - } - dtd.append(systemId); - dtd.append(quote); - } - + dtd.append(JdkXmlUtils.getDTDExternalDecl(publicId, systemId)); dtd.append(" [ "); dtd.append(fNewLine);
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java index de383ca..caf2a4b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java
@@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -35,6 +34,8 @@ * fact that it's declared to throw TransformerException. Please * see code comments for details on how resolution is performed.</p> * @xsl.usage internal + * + * @LastModified: Sept 2021 */ public class SystemIDResolver { @@ -275,7 +276,7 @@ public static String getAbsoluteURI(String urlString, String base) throws TransformerException { - if (base == null) + if (base == null || base.length() == 0) return getAbsoluteURI(urlString); String absoluteBase = getAbsoluteURI(base);
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index 6974f60..d5c038f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,13 +21,13 @@ package com.sun.org.apache.xml.internal.utils; import com.sun.org.apache.xalan.internal.XalanConstants; -import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import java.util.HashMap; import javax.xml.XMLConstants; import javax.xml.catalog.CatalogFeatures; import jdk.xml.internal.JdkXmlFeatures; import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.SecuritySupport; +import jdk.xml.internal.XMLSecurityManager; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; @@ -37,7 +37,7 @@ * Creates XMLReader objects and caches them for re-use. * This class follows the singleton pattern. * - * @LastModified: Sep 2017 + * @LastModified: Jan 2022 */ public class XMLReaderManager { @@ -143,9 +143,11 @@ try { if (_xmlSecurityManager != null) { for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) { - lastProperty = limit.apiProperty(); - reader.setProperty(lastProperty, - _xmlSecurityManager.getLimitValueAsString(limit)); + if (limit.isSupported(XMLSecurityManager.Processor.PARSER)) { + lastProperty = limit.apiProperty(); + reader.setProperty(lastProperty, + _xmlSecurityManager.getLimitValueAsString(limit)); + } } if (_xmlSecurityManager.printEntityCountInfo()) { lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java index f610277..18632ea 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,6 +22,7 @@ import com.sun.org.apache.xalan.internal.res.XSLMessages; import com.sun.org.apache.xml.internal.dtm.DTM; +import com.sun.org.apache.xml.internal.utils.DefaultErrorHandler; import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xml.internal.utils.QName; import com.sun.org.apache.xml.internal.utils.SAXSourceLocator; @@ -35,12 +36,13 @@ import javax.xml.transform.ErrorListener; import javax.xml.transform.SourceLocator; import javax.xml.transform.TransformerException; +import jdk.xml.internal.XMLSecurityManager; /** * The XPath class wraps an expression object and provides general services * for execution of that expression. * @xsl.usage advanced - * @LastModified: May 2019 + * @LastModified: Jan 2022 */ public class XPath implements Serializable, ExpressionOwner { @@ -160,40 +162,11 @@ * * @throws javax.xml.transform.TransformerException if syntax or other error. */ - public XPath( - String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type, - ErrorListener errorListener) - throws javax.xml.transform.TransformerException + public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver, + int type, ErrorListener errorListener) + throws TransformerException { - initFunctionTable(); - if(null == errorListener) - errorListener = new com.sun.org.apache.xml.internal.utils.DefaultErrorHandler(); - - m_patternString = exprString; - - XPathParser parser = new XPathParser(errorListener, locator); - Compiler compiler = new Compiler(errorListener, locator, m_funcTable); - - if (SELECT == type) - parser.initXPath(compiler, exprString, prefixResolver); - else if (MATCH == type) - parser.initMatchPattern(compiler, exprString, prefixResolver); - else - throw new RuntimeException(XSLMessages.createXPATHMessage( - XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, - new Object[]{Integer.toString(type)})); - - // System.out.println("----------------"); - Expression expr = compiler.compileExpression(0); - - // System.out.println("expr: "+expr); - this.setExpression(expr); - - if((null != locator) && locator instanceof ExpressionNode) - { - expr.exprSetParent((ExpressionNode)locator); - } - + this(exprString, locator, prefixResolver, type, errorListener, null); } /** @@ -207,22 +180,27 @@ * namespace URIs. * @param type one of {@link #SELECT} or {@link #MATCH}. * @param errorListener The error listener, or null if default should be used. + * @param funcTable the function table + * @param xmlSecMgr the XML security manager * * @throws javax.xml.transform.TransformerException if syntax or other error. */ - public XPath( - String exprString, SourceLocator locator, - PrefixResolver prefixResolver, int type, - ErrorListener errorListener, FunctionTable aTable) - throws javax.xml.transform.TransformerException + public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver, + int type, ErrorListener errorListener, FunctionTable funcTable, + XMLSecurityManager xmlSecMgr) + throws TransformerException { - m_funcTable = aTable; + if (funcTable == null) { + initFunctionTable(); + } else { + m_funcTable = funcTable; + } if(null == errorListener) - errorListener = new com.sun.org.apache.xml.internal.utils.DefaultErrorHandler(); + errorListener = new DefaultErrorHandler(); m_patternString = exprString; - XPathParser parser = new XPathParser(errorListener, locator); + XPathParser parser = new XPathParser(errorListener, locator, xmlSecMgr); Compiler compiler = new Compiler(errorListener, locator, m_funcTable); if (SELECT == type) @@ -261,14 +239,33 @@ * * @throws javax.xml.transform.TransformerException if syntax or other error. */ - public XPath( - String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type) - throws javax.xml.transform.TransformerException + public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver, + int type) + throws TransformerException { this(exprString, locator, prefixResolver, type, null); } /** + * Constructs an XPath object. + * + * @param exprString The XPath expression. + * @param locator The location of the expression, may be null. + * @param prefixResolver A prefix resolver to use to resolve prefixes to + * namespace URIs. + * @param type one of {@link #SELECT} or {@link #MATCH}. + * @param errorListener The error listener, or null if default should be used. + * @param funcTable the function table + * @throws TransformerException + */ + public XPath(String exprString, SourceLocator locator, PrefixResolver prefixResolver, + int type, ErrorListener errorListener, FunctionTable funcTable) + throws TransformerException + { + this(exprString, locator, prefixResolver, type, errorListener, funcTable, null); + } + + /** * Construct an XPath object. * * @param expr The Expression object.
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java index 44422a8..41b58da 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Lexer.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,15 +20,19 @@ package com.sun.org.apache.xpath.internal.compiler; +import com.sun.org.apache.xalan.internal.res.XSLMessages; import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; import java.util.List; +import javax.xml.transform.TransformerException; +import jdk.xml.internal.XMLSecurityManager; +import jdk.xml.internal.XMLSecurityManager.Limit; /** * This class is in charge of lexical processing of the XPath * expression into tokens. * - * @LastModified: Nov 2017 + * @LastModified: Jan 2022 */ class Lexer { @@ -70,6 +74,24 @@ */ private int m_patternMapSize; + // XML security manager + XMLSecurityManager m_xmlSecMgr; + + // operator limit + private int m_opCountLimit; + + // group limit + private int m_grpCountLimit; + + // count of operators + private int m_opCount; + + // count of groups + private int m_grpCount; + + // indicate whether the current token is a literal + private boolean isLiteral = false; + /** * Create a Lexer object. * @@ -77,14 +99,22 @@ * @param resolver The prefix resolver for mapping qualified name prefixes * to namespace URIs. * @param xpathProcessor The parser that is processing strings to opcodes. + * @param xmlSecMgr the XML security manager */ Lexer(Compiler compiler, PrefixResolver resolver, - XPathParser xpathProcessor) + XPathParser xpathProcessor, XMLSecurityManager xmlSecMgr) { - m_compiler = compiler; m_namespaceContext = resolver; m_processor = xpathProcessor; + m_xmlSecMgr = xmlSecMgr; + /** + * No limits if XML Security Manager is null. Applications using XPath through + * the public API always have a XMLSecurityManager. Applications invoking + * the internal XPath API shall consider using the public API instead. + */ + m_opCountLimit = (xmlSecMgr != null) ? xmlSecMgr.getLimit(Limit.XPATH_OP_LIMIT) : 0; + m_grpCountLimit = (xmlSecMgr != null) ? xmlSecMgr.getLimit(Limit.XPATH_GROUP_LIMIT) : 0; } /** @@ -92,7 +122,7 @@ * elements. * @param pat XSLT Expression. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ void tokenize(String pat) throws javax.xml.transform.TransformerException { @@ -105,13 +135,14 @@ * @param pat XSLT Expression. * @param targetStrings a list to hold Strings, may be null. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ @SuppressWarnings("fallthrough") // on purpose at case '-', '(' and default void tokenize(String pat, List<String> targetStrings) - throws javax.xml.transform.TransformerException + throws TransformerException { + boolean isGroup = false; m_compiler.m_currentPattern = pat; m_patternMapSize = 0; @@ -136,7 +167,7 @@ switch (c) { - case '\"' : + case Token.DQ : { if (startSubstring != -1) { @@ -171,7 +202,7 @@ } } break; - case '\'' : + case Token.SQ : if (startSubstring != -1) { isNum = false; @@ -190,9 +221,9 @@ startSubstring = i; - for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\''); i++); + for (i++; (i < nChars) && ((c = pat.charAt(i)) != Token.SQ); i++); - if (c == '\'' && i < nChars) + if (c == Token.SQ && i < nChars) { addToTokenQueue(pat.substring(startSubstring, i + 1)); @@ -220,18 +251,24 @@ } else { - addToTokenQueue(pat.substring(startSubstring, i)); + // check operator symbol + String s = pat.substring(startSubstring, i); + if (Token.contains(s)) { + m_opCount++; + isLiteral = false; + } + addToTokenQueue(s); } startSubstring = -1; } break; - case '@' : + case Token.AT : isAttrName = true; // fall-through on purpose - case '-' : - if ('-' == c) + case Token.MINUS : + if (Token.MINUS == c) { if (!(isNum || (startSubstring == -1))) { @@ -242,22 +279,22 @@ } // fall-through on purpose - case '(' : - case '[' : - case ')' : - case ']' : - case '|' : - case '/' : - case '*' : - case '+' : - case '=' : - case ',' : + case Token.LPAREN : + case Token.LBRACK : + case Token.RPAREN : + case Token.RBRACK : + case Token.VBAR : + case Token.SLASH : + case Token.STAR : + case Token.PLUS : + case Token.EQ : + case Token.COMMA : case '\\' : // Unused at the moment case '^' : // Unused at the moment - case '!' : // Unused at the moment - case '$' : - case '<' : - case '>' : + case Token.EM : // Unused at the moment + case Token.DOLLAR : + case Token.LT : + case Token.GT : if (startSubstring != -1) { isNum = false; @@ -275,11 +312,11 @@ startSubstring = -1; } - else if (('/' == c) && isStartOfPat) + else if ((Token.SLASH == c) && isStartOfPat) { isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName); } - else if ('*' == c) + else if (Token.STAR == c) { isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName); isAttrName = false; @@ -287,7 +324,7 @@ if (0 == nesting) { - if ('|' == c) + if (Token.VBAR == c) { if (null != targetStrings) { @@ -298,18 +335,32 @@ } } - if ((')' == c) || (']' == c)) + if ((Token.RPAREN == c) || (Token.RBRACK == c)) { nesting--; } - else if (('(' == c) || ('[' == c)) + else if ((Token.LPAREN == c) || (Token.LBRACK == c)) { nesting++; + if (!isLiteral && (Token.LPAREN == c)) { + m_grpCount++; + m_opCount++; + isLiteral = false; + } + } + + if ((Token.GT == c || Token.LT == c || Token.EQ == c) && Token.EQ != peekNext(pat, i)) { + m_opCount++; + isLiteral = false; + } + else if ((Token.LPAREN != c) && (Token.RPAREN != c) && (Token.RBRACK != c)) { + m_opCount++; + isLiteral = false; } addToTokenQueue(pat.substring(i, i + 1)); break; - case ':' : + case Token.COLON_CHAR: if (i>0) { if (posOfNSSep == (i - 1)) @@ -324,7 +375,7 @@ isAttrName = false; startSubstring = -1; posOfNSSep = -1; - + m_opCount++; addToTokenQueue(pat.substring(i - 1, i + 1)); break; @@ -337,6 +388,7 @@ // fall through on purpose default : + isLiteral = true; if (-1 == startSubstring) { startSubstring = i; @@ -347,6 +399,20 @@ isNum = Character.isDigit(c); } } + if (m_grpCountLimit > 0 && m_grpCount > m_grpCountLimit) { + throw new TransformerException(XSLMessages.createXPATHMessage( + XPATHErrorResources.ER_XPATH_GROUP_LIMIT, + new Object[]{Integer.toString(m_grpCount), + Integer.toString(m_grpCountLimit), + m_xmlSecMgr.getStateLiteral(Limit.XPATH_GROUP_LIMIT)})); + } + if (m_opCountLimit > 0 && m_opCount > m_opCountLimit) { + throw new TransformerException(XSLMessages.createXPATHMessage( + XPATHErrorResources.ER_XPATH_OPERATOR_LIMIT, + new Object[]{Integer.toString(m_opCount), + Integer.toString(m_opCountLimit), + m_xmlSecMgr.getStateLiteral(Limit.XPATH_OP_LIMIT)})); + } } if (startSubstring != -1) @@ -378,6 +444,19 @@ } /** + * Peeks at the next character without advancing the index. + * @param s the input string + * @param index the current index + * @return the next char + */ + private char peekNext(String s, int index) { + if (index >= 0 && index < s.length() - 1) { + return s.charAt(index + 1); + } + return 0; + } + + /** * Record the current position on the token queue as long as * this is a top-level element. Must be called before the * next token is added to the m_tokenQueue. @@ -499,7 +578,7 @@ resetTokenMark(tokPos + 1); - if (m_processor.lookahead('(', 1)) + if (m_processor.lookahead(Token.LPAREN, 1)) { int tok = getKeywordToken(m_processor.m_token); @@ -529,14 +608,14 @@ } else { - if (m_processor.tokenIs('@')) + if (m_processor.tokenIs(Token.AT)) { tokPos++; resetTokenMark(tokPos + 1); } - if (m_processor.lookahead(':', 1)) + if (m_processor.lookahead(Token.COLON_CHAR, 1)) { tokPos += 2; } @@ -565,13 +644,13 @@ * @param posOfNSSep The position of the namespace seperator (':'). * @param posOfScan The end of the name index. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException * * @return -1 always. */ private int mapNSTokens(String pat, int startSubstring, int posOfNSSep, int posOfScan) - throws javax.xml.transform.TransformerException + throws TransformerException { String prefix = "";
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Token.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Token.java new file mode 100644 index 0000000..7bce14e --- /dev/null +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Token.java
@@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xpath.internal.compiler; + +import java.util.Arrays; + +/** + * XPath tokens + */ +public final class Token { + static final char EM = '!'; + static final char EQ = '='; + static final char LT = '<'; + static final char GT = '>'; + static final char PLUS = '+'; + static final char MINUS = '-'; + static final char STAR = '*'; + static final char VBAR = '|'; + static final char SLASH = '/'; + static final char LBRACK = '['; + static final char RBRACK = ']'; + static final char LPAREN = '('; + static final char RPAREN = ')'; + static final char COMMA = ','; + static final char AT = '@'; + static final char US = '_'; + static final char COLON_CHAR = ':'; + static final char SQ = '\''; + static final char DQ = '"'; + static final char DOLLAR = '$'; + + static final String OR = "or"; + static final String AND = "and"; + static final String DIV = "div"; + static final String MOD = "mod"; + static final String QUO = "quo"; + static final String DOT = "."; + static final String DDOT = ".."; + static final String DCOLON = "::"; + static final String ATTR = "attribute"; + static final String CHILD = "child"; + + static final String[] OPERATORS = {OR, AND, DIV, MOD, QUO, + DDOT, DCOLON, ATTR, CHILD}; + + public static boolean contains(String str) { + return Arrays.stream(OPERATORS).anyMatch(str::equals); + } + + private Token() { + //to prevent instantiation + } +}
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java index dcf0445..22192fd 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,21 +20,22 @@ package com.sun.org.apache.xpath.internal.compiler; -import javax.xml.transform.ErrorListener; -import javax.xml.transform.TransformerException; - import com.sun.org.apache.xalan.internal.res.XSLMessages; import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xpath.internal.XPathProcessorException; import com.sun.org.apache.xpath.internal.objects.XNumber; import com.sun.org.apache.xpath.internal.objects.XString; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; +import javax.xml.transform.ErrorListener; +import javax.xml.transform.SourceLocator; +import javax.xml.transform.TransformerException; +import jdk.xml.internal.XMLSecurityManager; /** * Tokenizes and parses XPath expressions. This should really be named * XPathParserImpl, and may be renamed in the future. * @xsl.usage general - * @LastModified: May 2019 + * @LastModified: Jan 2022 */ public class XPathParser { @@ -75,13 +76,18 @@ // counts open predicates private int countPredicate; + // XML security manager + XMLSecurityManager m_xmlSecMgr; + /** * The parser constructor. */ - public XPathParser(ErrorListener errorListener, javax.xml.transform.SourceLocator sourceLocator) + public XPathParser(ErrorListener errorListener, SourceLocator sourceLocator, + XMLSecurityManager xmlSecMgr) { m_errorListener = errorListener; m_sourceLocator = sourceLocator; + m_xmlSecMgr = xmlSecMgr; } /** @@ -99,18 +105,18 @@ * @param namespaceContext An object that is able to resolve prefixes in * the XPath to namespaces. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ public void initXPath( Compiler compiler, String expression, PrefixResolver namespaceContext) - throws javax.xml.transform.TransformerException + throws TransformerException { m_ops = compiler; m_namespaceContext = namespaceContext; m_functionTable = compiler.getFunctionTable(); - Lexer lexer = new Lexer(compiler, namespaceContext, this); + Lexer lexer = new Lexer(compiler, namespaceContext, this, m_xmlSecMgr); lexer.tokenize(expression); @@ -178,18 +184,18 @@ * @param namespaceContext An object that is able to resolve prefixes in * the XPath to namespaces. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ public void initMatchPattern( Compiler compiler, String expression, PrefixResolver namespaceContext) - throws javax.xml.transform.TransformerException + throws TransformerException { m_ops = compiler; m_namespaceContext = namespaceContext; m_functionTable = compiler.getFunctionTable(); - Lexer lexer = new Lexer(compiler, namespaceContext, this); + Lexer lexer = new Lexer(compiler, namespaceContext, this, m_xmlSecMgr); lexer.tokenize(expression); @@ -382,9 +388,9 @@ if ((m_queueMark - n) > 0) { String lookbehind = (String) m_ops.m_tokenQueue.elementAt(m_queueMark - (n - 1)); - char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0); + char c0 = (lookbehind == null) ? Token.VBAR : lookbehind.charAt(0); - hasToken = (c0 == '|') ? false : true; + hasToken = (c0 == Token.VBAR) ? false : true; } else { @@ -496,10 +502,10 @@ * * @param expected The string to be expected. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ private final void consumeExpected(String expected) - throws javax.xml.transform.TransformerException + throws TransformerException { if (tokenIs(expected)) @@ -524,10 +530,10 @@ * * @param expected the character to be expected. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ private final void consumeExpected(char expected) - throws javax.xml.transform.TransformerException + throws TransformerException { if (tokenIs(expected)) @@ -749,9 +755,9 @@ * Expr ::= OrExpr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void Expr() throws javax.xml.transform.TransformerException + protected void Expr() throws TransformerException { OrExpr(); } @@ -763,16 +769,16 @@ * | OrExpr 'or' AndExpr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void OrExpr() throws javax.xml.transform.TransformerException + protected void OrExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); AndExpr(); - if ((null != m_token) && tokenIs("or")) + if ((null != m_token) && tokenIs(Token.OR)) { nextToken(); insertOp(opPos, 2, OpCodes.OP_OR); @@ -790,16 +796,16 @@ * | AndExpr 'and' EqualityExpr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void AndExpr() throws javax.xml.transform.TransformerException + protected void AndExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); EqualityExpr(-1); - if ((null != m_token) && tokenIs("and")) + if ((null != m_token) && tokenIs(Token.AND)) { nextToken(); insertOp(opPos, 2, OpCodes.OP_AND); @@ -823,9 +829,9 @@ * * @return the position at the end of the equality expression. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected int EqualityExpr(int addPos) throws javax.xml.transform.TransformerException + protected int EqualityExpr(int addPos) throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -837,7 +843,7 @@ if (null != m_token) { - if (tokenIs('!') && lookahead('=', 1)) + if (tokenIs(Token.EM) && lookahead(Token.EQ, 1)) { nextToken(); nextToken(); @@ -850,7 +856,7 @@ m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } - else if (tokenIs('=')) + else if (tokenIs(Token.EQ)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_EQUALS); @@ -883,9 +889,9 @@ * * @return the position at the end of the relational expression. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected int RelationalExpr(int addPos) throws javax.xml.transform.TransformerException + protected int RelationalExpr(int addPos) throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -897,11 +903,11 @@ if (null != m_token) { - if (tokenIs('<')) + if (tokenIs(Token.LT)) { nextToken(); - if (tokenIs('=')) + if (tokenIs(Token.EQ)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_LTE); @@ -918,11 +924,11 @@ m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } - else if (tokenIs('>')) + else if (tokenIs(Token.GT)) { nextToken(); - if (tokenIs('=')) + if (tokenIs(Token.EQ)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_GTE); @@ -958,9 +964,9 @@ * * @return the position at the end of the equality expression. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected int AdditiveExpr(int addPos) throws javax.xml.transform.TransformerException + protected int AdditiveExpr(int addPos) throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -972,7 +978,7 @@ if (null != m_token) { - if (tokenIs('+')) + if (tokenIs(Token.PLUS)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_PLUS); @@ -984,7 +990,7 @@ m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } - else if (tokenIs('-')) + else if (tokenIs(Token.MINUS)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_MINUS); @@ -1016,9 +1022,9 @@ * * @return the position at the end of the equality expression. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected int MultiplicativeExpr(int addPos) throws javax.xml.transform.TransformerException + protected int MultiplicativeExpr(int addPos) throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1030,7 +1036,7 @@ if (null != m_token) { - if (tokenIs('*')) + if (tokenIs(Token.STAR)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_MULT); @@ -1042,7 +1048,7 @@ m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } - else if (tokenIs("div")) + else if (tokenIs(Token.DIV)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_DIV); @@ -1054,7 +1060,7 @@ m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } - else if (tokenIs("mod")) + else if (tokenIs(Token.MOD)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_MOD); @@ -1066,7 +1072,7 @@ m_ops.getOp(addPos + opPlusLeftHandLen + 1) + opPlusLeftHandLen); addPos += 2; } - else if (tokenIs("quo")) + else if (tokenIs(Token.QUO)) { nextToken(); insertOp(addPos, 2, OpCodes.OP_QUO); @@ -1089,15 +1095,15 @@ * | '-' UnaryExpr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void UnaryExpr() throws javax.xml.transform.TransformerException + protected void UnaryExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); boolean isNeg = false; - if (m_tokenChar == '-') + if (m_tokenChar == Token.MINUS) { nextToken(); appendOp(2, OpCodes.OP_NEG); @@ -1117,9 +1123,9 @@ * StringExpr ::= Expr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void StringExpr() throws javax.xml.transform.TransformerException + protected void StringExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1137,9 +1143,9 @@ * StringExpr ::= Expr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void BooleanExpr() throws javax.xml.transform.TransformerException + protected void BooleanExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1163,9 +1169,9 @@ * NumberExpr ::= Expr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void NumberExpr() throws javax.xml.transform.TransformerException + protected void NumberExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1188,9 +1194,9 @@ * | UnionExpr '|' PathExpr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void UnionExpr() throws javax.xml.transform.TransformerException + protected void UnionExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1201,7 +1207,7 @@ { PathExpr(); - if (tokenIs('|')) + if (tokenIs(Token.VBAR)) { if (false == foundUnion) { @@ -1234,9 +1240,9 @@ * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide * the error condition is severe enough to halt processing. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void PathExpr() throws javax.xml.transform.TransformerException + protected void PathExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1249,7 +1255,7 @@ // have been inserted. boolean locationPathStarted = (filterExprMatch==FILTER_MATCH_PREDICATES); - if (tokenIs('/')) + if (tokenIs(Token.SLASH)) { nextToken(); @@ -1299,9 +1305,9 @@ * FilterExpr that was just a PrimaryExpr; or * FILTER_MATCH_FAILED, if this method did not match a FilterExpr * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected int FilterExpr() throws javax.xml.transform.TransformerException + protected int FilterExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1310,13 +1316,13 @@ if (PrimaryExpr()) { - if (tokenIs('[')) + if (tokenIs(Token.LBRACK)) { // int locationPathOpPos = opPos; insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH); - while (tokenIs('[')) + while (tokenIs(Token.LBRACK)) { Predicate(); } @@ -1354,16 +1360,16 @@ * * @return true if this method successfully matched a PrimaryExpr * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException * */ - protected boolean PrimaryExpr() throws javax.xml.transform.TransformerException + protected boolean PrimaryExpr() throws TransformerException { boolean matchFound; int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); - if ((m_tokenChar == '\'') || (m_tokenChar == '"')) + if ((m_tokenChar == Token.SQ) || (m_tokenChar == Token.DQ)) { appendOp(2, OpCodes.OP_LITERAL); Literal(); @@ -1373,7 +1379,7 @@ matchFound = true; } - else if (m_tokenChar == '$') + else if (m_tokenChar == Token.DOLLAR) { nextToken(); // consume '$' appendOp(2, OpCodes.OP_VARIABLE); @@ -1384,12 +1390,12 @@ matchFound = true; } - else if (m_tokenChar == '(') + else if (m_tokenChar == Token.LPAREN) { nextToken(); appendOp(2, OpCodes.OP_GROUP); Expr(); - consumeExpected(')'); + consumeExpected(Token.RPAREN); m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos); @@ -1407,7 +1413,7 @@ matchFound = true; } - else if (lookahead('(', 1) || (lookahead(':', 1) && lookahead('(', 3))) + else if (lookahead(Token.LPAREN, 1) || (lookahead(Token.COLON_CHAR, 1) && lookahead(Token.LPAREN, 3))) { matchFound = FunctionCall(); } @@ -1424,9 +1430,9 @@ * Argument ::= Expr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void Argument() throws javax.xml.transform.TransformerException + protected void Argument() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1444,14 +1450,14 @@ * * @return true if, and only if, a FunctionCall was matched * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected boolean FunctionCall() throws javax.xml.transform.TransformerException + protected boolean FunctionCall() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); - if (lookahead(':', 1)) + if (lookahead(Token.COLON_CHAR, 1)) { appendOp(4, OpCodes.OP_EXTFUNCTION); @@ -1491,22 +1497,23 @@ nextToken(); } - consumeExpected('('); + consumeExpected(Token.LPAREN); - while (!tokenIs(')') && m_token != null) + while (!tokenIs(Token.RPAREN) && m_token != null) { - if (tokenIs(',')) + if (tokenIs(Token.COMMA)) { - error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG, null); //"Found ',' but no preceding argument!"); + //"Found ',' but no preceding argument!"); + error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG, null); } Argument(); - if (!tokenIs(')')) + if (!tokenIs(Token.RPAREN)) { - consumeExpected(','); + consumeExpected(Token.COMMA); - if (tokenIs(')')) + if (tokenIs(Token.RPAREN)) { error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG, null); //"Found ',' but no following argument!"); @@ -1514,7 +1521,7 @@ } } - consumeExpected(')'); + consumeExpected(Token.RPAREN); // Terminate for safety. m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP); @@ -1533,9 +1540,9 @@ * | AbsoluteLocationPath * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void LocationPath() throws javax.xml.transform.TransformerException + protected void LocationPath() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1543,7 +1550,7 @@ // int locationPathOpPos = opPos; appendOp(2, OpCodes.OP_LOCATIONPATH); - boolean seenSlash = tokenIs('/'); + boolean seenSlash = tokenIs(Token.SLASH); if (seenSlash) { @@ -1584,17 +1591,17 @@ * * @returns true if, and only if, a RelativeLocationPath was matched * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ protected boolean RelativeLocationPath() - throws javax.xml.transform.TransformerException + throws TransformerException { if (!Step()) { return false; } - while (tokenIs('/')) + while (tokenIs(Token.SLASH)) { nextToken(); @@ -1616,13 +1623,13 @@ * * @returns false if step was empty (or only a '/'); true, otherwise * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected boolean Step() throws javax.xml.transform.TransformerException + protected boolean Step() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); - boolean doubleSlash = tokenIs('/'); + boolean doubleSlash = tokenIs(Token.SLASH); // At most a single '/' before each Step is consumed by caller; if the // first thing is a '/', that means we had '//' and the Step must not @@ -1654,11 +1661,11 @@ opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); } - if (tokenIs(".")) + if (tokenIs(Token.DOT)) { nextToken(); - if (tokenIs('[')) + if (tokenIs(Token.LBRACK)) { error(XPATHErrorResources.ER_PREDICATE_ILLEGAL_SYNTAX, null); //"'..[predicate]' or '.[predicate]' is illegal syntax. Use 'self::node()[predicate]' instead."); } @@ -1669,7 +1676,7 @@ m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 2,4); m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH) - 1, OpCodes.NODETYPE_NODE); } - else if (tokenIs("..")) + else if (tokenIs(Token.DDOT)) { nextToken(); appendOp(4, OpCodes.FROM_PARENT); @@ -1682,12 +1689,12 @@ // There is probably a better way to test for this // transition... but it gets real hairy if you try // to do it in basis(). - else if (tokenIs('*') || tokenIs('@') || tokenIs('_') + else if (tokenIs(Token.STAR) || tokenIs(Token.AT) || tokenIs(Token.US) || (m_token!= null && Character.isLetter(m_token.charAt(0)))) { Basis(); - while (tokenIs('[')) + while (tokenIs(Token.LBRACK)) { Predicate(); } @@ -1716,23 +1723,23 @@ * Basis ::= AxisName '::' NodeTest * | AbbreviatedBasis * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void Basis() throws javax.xml.transform.TransformerException + protected void Basis() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); int axesType; // The next blocks guarantee that a FROM_XXX will be added. - if (lookahead("::", 1)) + if (lookahead(Token.DCOLON, 1)) { axesType = AxisName(); nextToken(); nextToken(); } - else if (tokenIs('@')) + else if (tokenIs(Token.AT)) { axesType = OpCodes.FROM_ATTRIBUTES; @@ -1763,9 +1770,9 @@ * * @return FROM_XXX axes type, found in {@link com.sun.org.apache.xpath.internal.compiler.Keywords}. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected int AxisName() throws javax.xml.transform.TransformerException + protected int AxisName() throws TransformerException { Object val = Keywords.getAxisName(m_token); @@ -1791,12 +1798,12 @@ * * @param axesType FROM_XXX axes type, found in {@link com.sun.org.apache.xpath.internal.compiler.Keywords}. * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void NodeTest(int axesType) throws javax.xml.transform.TransformerException + protected void NodeTest(int axesType) throws TransformerException { - if (lookahead('(', 1)) + if (lookahead(Token.LPAREN, 1)) { Object nodeTestOp = Keywords.getNodeType(m_token); @@ -1814,17 +1821,17 @@ m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), nt); m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1); - consumeExpected('('); + consumeExpected(Token.LPAREN); if (OpCodes.NODETYPE_PI == nt) { - if (!tokenIs(')')) + if (!tokenIs(Token.RPAREN)) { Literal(); } } - consumeExpected(')'); + consumeExpected(Token.RPAREN); } } else @@ -1834,9 +1841,9 @@ m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.NODENAME); m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1); - if (lookahead(':', 1)) + if (lookahead(Token.COLON_CHAR, 1)) { - if (tokenIs('*')) + if (tokenIs(Token.STAR)) { m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ELEMWILDCARD); } @@ -1846,7 +1853,7 @@ // Minimalist check for an NCName - just check first character // to distinguish from other possible tokens - if (!Character.isLetter(m_tokenChar) && !tokenIs('_')) + if (!Character.isLetter(m_tokenChar) && !tokenIs(Token.US)) { // "Node test that matches either NCName:* or QName was expected." error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null); @@ -1863,7 +1870,7 @@ m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1); - if (tokenIs('*')) + if (tokenIs(Token.STAR)) { m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ELEMWILDCARD); } @@ -1873,7 +1880,7 @@ // Minimalist check for an NCName - just check first character // to distinguish from other possible tokens - if (!Character.isLetter(m_tokenChar) && !tokenIs('_')) + if (!Character.isLetter(m_tokenChar) && !tokenIs(Token.US)) { // "Node test that matches either NCName:* or QName was expected." error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null); @@ -1891,11 +1898,11 @@ * Predicate ::= '[' PredicateExpr ']' * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void Predicate() throws javax.xml.transform.TransformerException + protected void Predicate() throws TransformerException { - if (tokenIs('[')) + if (tokenIs(Token.LBRACK)) { countPredicate++; nextToken(); @@ -1910,9 +1917,9 @@ * PredicateExpr ::= Expr * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void PredicateExpr() throws javax.xml.transform.TransformerException + protected void PredicateExpr() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -1932,12 +1939,12 @@ * Prefix ::= NCName * LocalPart ::= NCName * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void QName() throws javax.xml.transform.TransformerException + protected void QName() throws TransformerException { // Namespace - if(lookahead(':', 1)) + if(lookahead(Token.COLON_CHAR, 1)) { m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), m_queueMark - 1); m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH) + 1); @@ -1979,16 +1986,16 @@ * | "'" [^']* "'" * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void Literal() throws javax.xml.transform.TransformerException + protected void Literal() throws TransformerException { int last = m_token.length() - 1; char c0 = m_tokenChar; char cX = m_token.charAt(last); - if (((c0 == '\"') && (cX == '\"')) || ((c0 == '\'') && (cX == '\''))) + if (((c0 == Token.DQ) && (cX == Token.DQ)) || ((c0 == Token.SQ) && (cX == Token.SQ))) { // Mutate the token to remove the quotes and have the XString object @@ -2019,9 +2026,9 @@ * Number ::= [0-9]+('.'[0-9]+)? | '.'[0-9]+ * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void Number() throws javax.xml.transform.TransformerException + protected void Number() throws TransformerException { if (null != m_token) @@ -2062,16 +2069,16 @@ * | Pattern '|' LocationPathPattern * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void Pattern() throws javax.xml.transform.TransformerException + protected void Pattern() throws TransformerException { while (true) { LocationPathPattern(); - if (tokenIs('|')) + if (tokenIs(Token.VBAR)) { nextToken(); } @@ -2090,9 +2097,9 @@ * | '//'? RelativePathPattern * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void LocationPathPattern() throws javax.xml.transform.TransformerException + protected void LocationPathPattern() throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -2105,17 +2112,17 @@ appendOp(2, OpCodes.OP_LOCATIONPATHPATTERN); - if (lookahead('(', 1) + if (lookahead(Token.LPAREN, 1) && (tokenIs(Keywords.FUNC_ID_STRING) || tokenIs(Keywords.FUNC_KEY_STRING))) { IdKeyPattern(); - if (tokenIs('/')) + if (tokenIs(Token.SLASH)) { nextToken(); - if (tokenIs('/')) + if (tokenIs(Token.SLASH)) { appendOp(4, OpCodes.MATCH_ANY_ANCESTOR); @@ -2133,9 +2140,9 @@ relativePathStatus = RELATIVE_PATH_REQUIRED; } } - else if (tokenIs('/')) + else if (tokenIs(Token.SLASH)) { - if (lookahead('/', 1)) + if (lookahead(Token.SLASH, 1)) { appendOp(4, OpCodes.MATCH_ANY_ANCESTOR); @@ -2168,7 +2175,7 @@ if (relativePathStatus != RELATIVE_PATH_NOT_PERMITTED) { - if (!tokenIs('|') && (null != m_token)) + if (!tokenIs(Token.VBAR) && (null != m_token)) { RelativePathPattern(); } @@ -2193,9 +2200,9 @@ * (Also handle doc()) * * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ - protected void IdKeyPattern() throws javax.xml.transform.TransformerException + protected void IdKeyPattern() throws TransformerException { FunctionCall(); } @@ -2206,17 +2213,17 @@ * | RelativePathPattern '/' StepPattern * | RelativePathPattern '//' StepPattern * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ protected void RelativePathPattern() - throws javax.xml.transform.TransformerException + throws TransformerException { // Caller will have consumed any '/' or '//' preceding the // RelativePathPattern, so let StepPattern know it can't begin with a '/' boolean trailingSlashConsumed = StepPattern(false); - while (tokenIs('/')) + while (tokenIs(Token.SLASH)) { nextToken(); @@ -2236,10 +2243,10 @@ * * @return boolean indicating whether a slash following the step was consumed * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ protected boolean StepPattern(boolean isLeadingSlashPermitted) - throws javax.xml.transform.TransformerException + throws TransformerException { return AbbreviatedNodeTestStep(isLeadingSlashPermitted); } @@ -2253,10 +2260,10 @@ * * @return boolean indicating whether a slash following the step was consumed * - * @throws javax.xml.transform.TransformerException + * @throws TransformerException */ protected boolean AbbreviatedNodeTestStep(boolean isLeadingSlashPermitted) - throws javax.xml.transform.TransformerException + throws TransformerException { int opPos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); @@ -2265,22 +2272,22 @@ // The next blocks guarantee that a MATCH_XXX will be added. int matchTypePos = -1; - if (tokenIs('@')) + if (tokenIs(Token.AT)) { axesType = OpCodes.MATCH_ATTRIBUTE; appendOp(2, axesType); nextToken(); } - else if (this.lookahead("::", 1)) + else if (this.lookahead(Token.DCOLON, 1)) { - if (tokenIs("attribute")) + if (tokenIs(Token.ATTR)) { axesType = OpCodes.MATCH_ATTRIBUTE; appendOp(2, axesType); } - else if (tokenIs("child")) + else if (tokenIs(Token.CHILD)) { matchTypePos = m_ops.getOp(OpMap.MAPINDEX_LENGTH); axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR; @@ -2298,7 +2305,7 @@ nextToken(); nextToken(); } - else if (tokenIs('/')) + else if (tokenIs(Token.SLASH)) { if (!isLeadingSlashPermitted) { @@ -2327,7 +2334,7 @@ m_ops.setOp(opPos + OpMap.MAPINDEX_LENGTH + 1, m_ops.getOp(OpMap.MAPINDEX_LENGTH) - opPos); - while (tokenIs('[')) + while (tokenIs(Token.LBRACK)) { Predicate(); } @@ -2346,7 +2353,7 @@ // If current step is on the attribute axis (e.g., "@x//b"), we won't // change the current step, and let following step be marked as // MATCH_ANY_ANCESTOR on next call instead. - if ((matchTypePos > -1) && tokenIs('/') && lookahead('/', 1)) + if ((matchTypePos > -1) && tokenIs(Token.SLASH) && lookahead(Token.SLASH, 1)) { m_ops.setOp(matchTypePos, OpCodes.MATCH_ANY_ANCESTOR);
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java index 562f776..d948a0a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -29,6 +29,7 @@ import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathVariableResolver; import jdk.xml.internal.JdkXmlFeatures; +import jdk.xml.internal.XMLSecurityManager; /** * The XPathFactory builds XPaths. @@ -67,6 +68,11 @@ private final JdkXmlFeatures _featureManager; /** + * The XML security manager + */ + private XMLSecurityManager _xmlSecMgr; + + /** * javax.xml.xpath.XPathFactory implementation. */ public XPathFactoryImpl() { @@ -75,7 +81,9 @@ _isNotSecureProcessing = false; } _featureManager = new JdkXmlFeatures(!_isNotSecureProcessing); + _xmlSecMgr = new XMLSecurityManager(true); } + /** * <p>Is specified object model supported by this * <code>XPathFactory</code>?</p> @@ -122,9 +130,8 @@ * @return New <code>XPath</code> */ public javax.xml.xpath.XPath newXPath() { - return new com.sun.org.apache.xpath.internal.jaxp.XPathImpl( - xPathVariableResolver, xPathFunctionResolver, - !_isNotSecureProcessing, _featureManager ); + return new XPathImpl(xPathVariableResolver, xPathFunctionResolver, + !_isNotSecureProcessing, _featureManager, _xmlSecMgr); } /**
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java index 8796587..bddc738 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,6 +32,7 @@ import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathVariableResolver; import jdk.xml.internal.JdkXmlFeatures; +import jdk.xml.internal.XMLSecurityManager; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -45,6 +46,8 @@ * Updated 12/04/2014: * New methods: evaluateExpression * Refactored to share code with XPathExpressionImpl. + * + * @LastModified: Jan 2022 */ public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath { @@ -54,18 +57,19 @@ private NamespaceContext namespaceContext=null; XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) { - this(vr, fr, false, new JdkXmlFeatures(false)); + this(vr, fr, false, new JdkXmlFeatures(false), new XMLSecurityManager(true)); } XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr, - boolean featureSecureProcessing, JdkXmlFeatures featureManager) { + boolean featureSecureProcessing, JdkXmlFeatures featureManager, + XMLSecurityManager xmlSecMgr) { this.origVariableResolver = this.variableResolver = vr; this.origFunctionResolver = this.functionResolver = fr; this.featureSecureProcessing = featureSecureProcessing; this.featureManager = featureManager; overrideDefaultParser = featureManager.getFeature( JdkXmlFeatures.XmlFeature.JDK_OVERRIDE_PARSER); - + this.xmlSecMgr = xmlSecMgr; } @@ -113,8 +117,8 @@ private XObject eval(String expression, Object contextItem) throws TransformerException { requireNonNull(expression, "XPath expression"); - com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath(expression, - null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT); + XPath xpath = new XPath(expression, null, prefixResolver, XPath.SELECT, + null, null, xmlSecMgr); return eval(contextItem, xpath); } @@ -159,8 +163,8 @@ throws XPathExpressionException { requireNonNull(expression, "XPath expression"); try { - com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null, - prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT); + XPath xpath = new XPath(expression, null, prefixResolver, XPath.SELECT, + null, null, xmlSecMgr); // Can have errorListener XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath, prefixResolver, functionResolver, variableResolver,
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java index 099a98b..14b47fd 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ import javax.xml.xpath.XPathVariableResolver; import jdk.xml.internal.JdkXmlFeatures; import jdk.xml.internal.JdkXmlUtils; +import jdk.xml.internal.XMLSecurityManager; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.traversal.NodeIterator; @@ -52,6 +53,8 @@ /** * This class contains several utility methods used by XPathImpl and * XPathExpressionImpl + * + * @LastModified: Jan 2022 */ class XPathImplUtil { XPathFunctionResolver functionResolver; @@ -63,6 +66,7 @@ // extensions function need to throw XPathFunctionException boolean featureSecureProcessing = false; JdkXmlFeatures featureManager; + XMLSecurityManager xmlSecMgr; /** * Evaluate an XPath context using the internal XPath engine
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathResultImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathResultImpl.java index 4953702..b30a27c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathResultImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathResultImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -171,7 +171,11 @@ case XObject.CLASS_RTREEFRAG: //NODE NodeIterator ni = resultObject.nodeset(); //Return the first node, or null - return type.cast(ni.nextNode()); + try { + return type.cast(ni.nextNode()); + } catch (RuntimeException e) { + throw new TransformerException(e.getMessage(), e.getCause()); + } } return null;
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java index 54e4fe7..1fa2cac 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2019 + * @LastModified: Jan 2022 */ public class XPATHErrorResources extends ListResourceBundle { @@ -322,6 +322,9 @@ public static final String ER_SECUREPROCESSING_FEATURE = "ER_SECUREPROCESSING_FEATURE"; public static final String ER_NULL_XPATH_FUNCTION_RESOLVER = "ER_NULL_XPATH_FUNCTION_RESOLVER"; public static final String ER_NULL_XPATH_VARIABLE_RESOLVER = "ER_NULL_XPATH_VARIABLE_RESOLVER"; + public static final String ER_XPATH_GROUP_LIMIT = "XPATH_GROUP_LIMIT"; + public static final String ER_XPATH_OPERATOR_LIMIT = "XPATH_OPERATOR_LIMIT"; + //END: Keys needed for exception messages of JAXP 1.3 XPath API implementation public static final String WG_LOCALE_NAME_NOT_HANDLED = @@ -836,6 +839,14 @@ { ER_NULL_XPATH_VARIABLE_RESOLVER, "Attempting to set a null XPathVariableResolver:{0}#setXPathVariableResolver(null)"}, + { ER_XPATH_GROUP_LIMIT, + "JAXP0801001: the compiler encountered an XPath expression containing " + + "''{0}'' groups that exceeds the ''{1}'' limit set by ''{2}''."}, + + { ER_XPATH_OPERATOR_LIMIT, + "JAXP0801002: the compiler encountered an XPath expression containing " + + "''{0}'' operators that exceeds the ''{1}'' limit set by ''{2}''."}, + //END: Definitions of error keys used in exception messages of JAXP 1.3 XPath API implementation // Warnings...
diff --git a/src/java.xml/share/classes/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java b/src/java.xml/share/classes/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java index e4b36ec..6380632 100644 --- a/src/java.xml/share/classes/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java +++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/events/EntityDeclarationImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import javax.xml.stream.events.EntityDeclaration; import javax.xml.stream.events.XMLEvent; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; +import jdk.xml.internal.JdkXmlUtils; /** * @@ -129,18 +130,12 @@ //escape quotes, lt and amps writer.write(" \""); charEncode(writer, fReplacementText); + writer.write("\""); } else { //external entity - String pubId = getPublicId(); - if (pubId != null) { - writer.write(" PUBLIC \""); - writer.write(pubId); - } else { - writer.write(" SYSTEM \""); - writer.write(getSystemId()); - } + writer.write(JdkXmlUtils.getDTDExternalDecl(getPublicId(), getSystemId())); } - writer.write("\""); + if (fNotationName != null) { writer.write(" NDATA "); writer.write(fNotationName);
diff --git a/src/java.xml/share/classes/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java b/src/java.xml/share/classes/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java index b8a22d9..2f980cc 100644 --- a/src/java.xml/share/classes/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java +++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/events/NotationDeclarationImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import javax.xml.stream.events.NotationDeclaration; import javax.xml.stream.events.XMLEvent; import com.sun.xml.internal.stream.dtd.nonvalidating.XMLNotationDecl; +import jdk.xml.internal.JdkXmlUtils; /** * Implementation of NotationDeclaration event. @@ -88,16 +89,7 @@ { writer.write("<!NOTATION "); writer.write(getName()); - if (fPublicId != null) { - writer.write(" PUBLIC \""); - writer.write(fPublicId); - writer.write("\""); - } else if (fSystemId != null) { - writer.write(" SYSTEM"); - writer.write(" \""); - writer.write(fSystemId); - writer.write("\""); - } + writer.write(JdkXmlUtils.getDTDExternalDecl(fPublicId, fSystemId)); writer.write('>'); } }
diff --git a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java index 1e13c72..100186c 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ */ package jdk.xml.internal; -import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; @@ -394,19 +393,40 @@ } /** - * Returns the character to be used to quote the input content. Between - * single and double quotes, this method returns the one that is not found - * in the input. Returns double quote by default. + * Returns the external declaration for a DTD construct. * - * @param s the input string - * @return returns the quote not found in the input + * @param publicId the public identifier + * @param systemId the system identifier + * @return a DTD external declaration */ - public static char getQuoteChar(String s) { - if (s != null && s.indexOf('"') > -1) { - return '\''; - } else { - return '"'; + public static String getDTDExternalDecl(String publicId, String systemId) { + StringBuilder sb = new StringBuilder(); + if (null != publicId) { + sb.append(" PUBLIC "); + sb.append(quoteString(publicId)); } + + if (null != systemId) { + if (null == publicId) { + sb.append(" SYSTEM "); + } else { + sb.append(" "); + } + + sb.append(quoteString(systemId)); + } + return sb.toString(); + } + + /** + * Returns the input string quoted with double quotes or single ones if + * there is a double quote in the string. + * @param s the input string, can not be null + * @return the quoted string + */ + private static String quoteString(String s) { + char c = (s.indexOf('"') > -1) ? '\'' : '"'; + return c + s + c; } private static XMLReader getXMLReaderWSAXFactory(boolean overrideDefaultParser) {
diff --git a/src/java.xml/share/classes/jdk/xml/internal/XMLLimitAnalyzer.java b/src/java.xml/share/classes/jdk/xml/internal/XMLLimitAnalyzer.java new file mode 100644 index 0000000..18ce1b6 --- /dev/null +++ b/src/java.xml/share/classes/jdk/xml/internal/XMLLimitAnalyzer.java
@@ -0,0 +1,249 @@ +/* + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.xml.internal; + +import java.util.Formatter; +import java.util.HashMap; +import java.util.Map; +import jdk.xml.internal.XMLSecurityManager.Limit; +import com.sun.org.apache.xalan.internal.XalanConstants; + + +/** + * A helper for analyzing entity expansion limits + * + */ +public final class XMLLimitAnalyzer { + + /** + * Map old property names with the new ones + */ + public static enum NameMap { + ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT, XalanConstants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT, XalanConstants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, XalanConstants.ELEMENT_ATTRIBUTE_LIMIT); + + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + + /** + * Max value accumulated for each property + */ + private final int[] values; + /** + * Names of the entities corresponding to their max values + */ + private final String[] names; + /** + * Total value of accumulated entities + */ + private final int[] totalValue; + + /** + * Maintain values of the top 10 elements in the process of parsing + */ + private final Map<String, Integer>[] caches; + + private String entityStart, entityEnd; + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public XMLLimitAnalyzer() { + values = new int[Limit.values().length]; + totalValue = new int[Limit.values().length]; + names = new String[Limit.values().length]; + caches = new Map[Limit.values().length]; + } + + /** + * Add the value to the current max count for the specified property + * To find the max value of all entities, set no limit + * + * @param limit the type of the property + * @param entityName the name of the entity + * @param value the value of the entity + */ + public void addValue(Limit limit, String entityName, int value) { + addValue(limit.ordinal(), entityName, value); + } + + /** + * Add the value to the current count by the index of the property + * @param index the index of the property + * @param entityName the name of the entity + * @param value the value of the entity + */ + public void addValue(int index, String entityName, int value) { + if (index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || + index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() || + index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || + index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal() + ) { + totalValue[index] += value; + return; + } + if (index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() || + index == Limit.MAX_NAME_LIMIT.ordinal()) { + values[index] = value; + totalValue[index] = value; + return; + } + + Map<String, Integer> cache; + if (caches[index] == null) { + cache = new HashMap<>(10); + caches[index] = cache; + } else { + cache = caches[index]; + } + + int accumulatedValue = value; + if (cache.containsKey(entityName)) { + accumulatedValue += cache.get(entityName); + cache.put(entityName, accumulatedValue); + } else { + cache.put(entityName, value); + } + + if (accumulatedValue > values[index]) { + values[index] = accumulatedValue; + names[index] = entityName; + } + + + if (index == Limit.GENERAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.PARAMETER_ENTITY_SIZE_LIMIT.ordinal()) { + totalValue[Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()] += value; + } + } + + /** + * Return the value of the current max count for the specified property + * + * @param limit the property + * @return the value of the property + */ + public int getValue(Limit limit) { + return getValue(limit.ordinal()); + } + + public int getValue(int index) { + if (index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal()) { + return totalValue[index]; + } + return values[index]; + } + /** + * Return the total value accumulated so far + * + * @param limit the property + * @return the accumulated value of the property + */ + public int getTotalValue(Limit limit) { + return totalValue[limit.ordinal()]; + } + + public int getTotalValue(int index) { + return totalValue[index]; + } + /** + * Return the current max value (count or length) by the index of a property + * @param index the index of a property + * @return count of a property + */ + public int getValueByIndex(int index) { + return values[index]; + } + + public void startEntity(String name) { + entityStart = name; + } + + public boolean isTracking(String name) { + if (entityStart == null) { + return false; + } + return entityStart.equals(name); + } + /** + * Stop tracking the entity + * @param limit the limit property + * @param name the name of an entity + */ + public void endEntity(Limit limit, String name) { + entityStart = ""; + Map<String, Integer> cache = caches[limit.ordinal()]; + if (cache != null) { + cache.remove(name); + } + } + + /** + * Resets the current value of the specified limit. + * @param limit The limit to be reset. + */ + public void reset(Limit limit) { + if (limit.ordinal() == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) { + totalValue[limit.ordinal()] = 0; + } else if (limit.ordinal() == Limit.GENERAL_ENTITY_SIZE_LIMIT.ordinal()) { + names[limit.ordinal()] = null; + values[limit.ordinal()] = 0; + caches[limit.ordinal()] = null; + totalValue[limit.ordinal()] = 0; + } + } + + public void debugPrint(XMLSecurityManager securityManager) { + Formatter formatter = new Formatter(); + System.out.println(formatter.format("%30s %15s %15s %15s %30s", + "Property","Limit","Total size","Size","Entity Name")); + + for (Limit limit : Limit.values()) { + formatter = new Formatter(); + System.out.println(formatter.format("%30s %15d %15d %15d %30s", + limit.name(), + securityManager.getLimit(limit), + totalValue[limit.ordinal()], + values[limit.ordinal()], + names[limit.ordinal()])); + } + } +}
diff --git a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java new file mode 100644 index 0000000..2dd1657 --- /dev/null +++ b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java
@@ -0,0 +1,604 @@ +/* + * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.xml.internal; + +import com.sun.org.apache.xerces.internal.util.SecurityManager; +import java.util.concurrent.CopyOnWriteArrayList; +import com.sun.org.apache.xalan.internal.XalanConstants; +import org.xml.sax.SAXException; + + +/** + * + * This class manages standard and implementation-specific limitations. + * + */ +public final class XMLSecurityManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + + DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"), + JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"), + APIPROPERTY("property"); + + final String literal; + State(String literal) { + this.literal = literal; + } + + String literal() { + return literal; + } + } + + /** + * Limits managed by the security manager + */ + public static enum Limit { + ENTITY_EXPANSION_LIMIT("EntityExpansionLimit", XalanConstants.JDK_ENTITY_EXPANSION_LIMIT, + XalanConstants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000, Processor.PARSER), + MAX_OCCUR_NODE_LIMIT("MaxOccurLimit", XalanConstants.JDK_MAX_OCCUR_LIMIT, + XalanConstants.SP_MAX_OCCUR_LIMIT, 0, 5000, Processor.PARSER), + ELEMENT_ATTRIBUTE_LIMIT("ElementAttributeLimit", XalanConstants.JDK_ELEMENT_ATTRIBUTE_LIMIT, + XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000, Processor.PARSER), + TOTAL_ENTITY_SIZE_LIMIT("TotalEntitySizeLimit", XalanConstants.JDK_TOTAL_ENTITY_SIZE_LIMIT, + XalanConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000, Processor.PARSER), + GENERAL_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", XalanConstants.JDK_GENERAL_ENTITY_SIZE_LIMIT, + XalanConstants.SP_GENERAL_ENTITY_SIZE_LIMIT, 0, 0, Processor.PARSER), + PARAMETER_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", XalanConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, + XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000, Processor.PARSER), + MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit", XalanConstants.JDK_MAX_ELEMENT_DEPTH, + XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0, Processor.PARSER), + MAX_NAME_LIMIT("MaxXMLNameLimit", XalanConstants.JDK_XML_NAME_LIMIT, + XalanConstants.SP_XML_NAME_LIMIT, 1000, 1000, Processor.PARSER), + ENTITY_REPLACEMENT_LIMIT("EntityReplacementLimit", XalanConstants.JDK_ENTITY_REPLACEMENT_LIMIT, + XalanConstants.SP_ENTITY_REPLACEMENT_LIMIT, 0, 3000000, Processor.PARSER), + XPATH_GROUP_LIMIT("XPathGroupLimit", XalanConstants.XPATH_GROUP_LIMIT, + XalanConstants.XPATH_GROUP_LIMIT, 10, 10, Processor.XPATH), + XPATH_OP_LIMIT("XPathExprOpLimit", XalanConstants.XPATH_OP_LIMIT, + XalanConstants.XPATH_OP_LIMIT, 100, 100, Processor.XPATH), + XPATH_TOTALOP_LIMIT("XPathTotalOpLimit", XalanConstants.XPATH_TOTALOP_LIMIT, + XalanConstants.XPATH_TOTALOP_LIMIT, 10000, 10000, Processor.XPATH) + ; + + final String key; + final String apiProperty; + final String systemProperty; + final int defaultValue; + final int secureValue; + final Processor processor; + + Limit(String key, String apiProperty, String systemProperty, int value, + int secureValue, Processor processor) { + this.key = key; + this.apiProperty = apiProperty; + this.systemProperty = systemProperty; + this.defaultValue = value; + this.secureValue = secureValue; + this.processor = processor; + } + + public boolean equalsAPIPropertyName(String propertyName) { + return (propertyName == null) ? false : apiProperty.equals(propertyName); + } + + public boolean equalsSystemPropertyName(String propertyName) { + return (propertyName == null) ? false : systemProperty.equals(propertyName); + } + + public String key() { + return key; + } + + public String apiProperty() { + return apiProperty; + } + + String systemProperty() { + return systemProperty; + } + + public int defaultValue() { + return defaultValue; + } + + public boolean isSupported(Processor p) { + return processor == p; + } + + int secureValue() { + return secureValue; + } + } + + /** + * Map old property names with the new ones + */ + public static enum NameMap { + + ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT, XalanConstants.ENTITY_EXPANSION_LIMIT), + MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT, XalanConstants.MAX_OCCUR_LIMIT), + ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, XalanConstants.ELEMENT_ATTRIBUTE_LIMIT); + final String newName; + final String oldName; + + NameMap(String newName, String oldName) { + this.newName = newName; + this.oldName = oldName; + } + + String getOldName(String newName) { + if (newName.equals(this.newName)) { + return oldName; + } + return null; + } + } + + /** + * Supported processors + */ + public static enum Processor { + PARSER, + XPATH, + } + + private static final int NO_LIMIT = 0; + + /** + * Values of the properties + */ + private final int[] values; + + /** + * States of the settings for each property + */ + private State[] states; + + /** + * Flag indicating if secure processing is set + */ + boolean secureProcessing; + + /** + * States that determine if properties are set explicitly + */ + private boolean[] isSet; + + + /** + * Index of the special entityCountInfo property + */ + private final int indexEntityCountInfo = 10000; + private String printEntityCountInfo = ""; + + /** + * Default constructor. Establishes default values for known security + * vulnerabilities. + */ + public XMLSecurityManager() { + this(false); + } + + /** + * Instantiate Security Manager in accordance with the status of + * secure processing + * @param secureProcessing + */ + public XMLSecurityManager(boolean secureProcessing) { + values = new int[Limit.values().length]; + states = new State[Limit.values().length]; + isSet = new boolean[Limit.values().length]; + this.secureProcessing = secureProcessing; + for (Limit limit : Limit.values()) { + if (secureProcessing) { + values[limit.ordinal()] = limit.secureValue; + states[limit.ordinal()] = State.FSP; + } else { + values[limit.ordinal()] = limit.defaultValue(); + states[limit.ordinal()] = State.DEFAULT; + } + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Setting FEATURE_SECURE_PROCESSING explicitly + */ + public void setSecureProcessing(boolean secure) { + secureProcessing = secure; + for (Limit limit : Limit.values()) { + if (secure) { + setLimit(limit.ordinal(), State.FSP, limit.secureValue()); + } else { + setLimit(limit.ordinal(), State.FSP, limit.defaultValue()); + } + } + } + + /** + * Return the state of secure processing + * @return the state of secure processing + */ + public boolean isSecureProcessing() { + return secureProcessing; + } + + /** + * Set limit by property name and state + * @param propertyName property name + * @param state the state of the property + * @param value the value of the property + * @return true if the property is managed by the security manager; false + * if otherwise. + */ + public boolean setLimit(String propertyName, State state, Object value) { + int index = getIndex(propertyName); + if (index > -1) { + setLimit(index, state, value); + return true; + } + return false; + } + + /** + * Set the value for a specific limit. + * + * @param limit the limit + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(Limit limit, State state, int value) { + setLimit(limit.ordinal(), state, value); + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, Object value) { + if (index == indexEntityCountInfo) { + printEntityCountInfo = (String)value; + } else { + int temp = 0; + try { + temp = Integer.parseInt((String) value); + if (temp < 0) { + temp = 0; + } + } catch (NumberFormatException e) {} + setLimit(index, state, temp); } + } + + /** + * Set the value of a property by its index + * + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setLimit(int index, State state, int value) { + if (index == indexEntityCountInfo) { + //if it's explicitly set, it's treated as yes no matter the value + printEntityCountInfo = XalanConstants.JDK_YES; + } else { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + isSet[index] = true; + } + } + } + + /** + * Return the value of the specified property + * + * @param propertyName the property name + * @return the value of the property as a string. If a property is managed + * by this manager, its value shall not be null. + */ + public String getLimitAsString(String propertyName) { + int index = getIndex(propertyName); + if (index > -1) { + return getLimitValueByIndex(index); + } + + return null; + } + /** + * Return the value of the specified property + * + * @param limit the property + * @return the value of the property + */ + public int getLimit(Limit limit) { + return values[limit.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * + * @param limit the property + * @return value of a property + */ + public String getLimitValueAsString(Limit limit) { + return Integer.toString(values[limit.ordinal()]); + } + + /** + * Return the value of a property by its ordinal + * + * @param index the index of a property + * @return limit of a property as a string + */ + public String getLimitValueByIndex(int index) { + if (index == indexEntityCountInfo) { + return printEntityCountInfo; + } + + return Integer.toString(values[index]); + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public State getState(Limit limit) { + return states[limit.ordinal()]; + } + + /** + * Return the state of the limit property + * + * @param limit the limit + * @return the state of the limit property + */ + public String getStateLiteral(Limit limit) { + return states[limit.ordinal()].literal(); + } + + /** + * Get the index by property name + * + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName) { + for (Limit limit : Limit.values()) { + if (limit.equalsAPIPropertyName(propertyName)) { + //internally, ordinal is used as index + return limit.ordinal(); + } + } + //special property to return entity count info + if (propertyName.equals(XalanConstants.JDK_ENTITY_COUNT_INFO)) { + return indexEntityCountInfo; + } + return -1; + } + + /** + * Check if there's no limit defined by the Security Manager + * @param limit + * @return + */ + public boolean isNoLimit(int limit) { + return limit == NO_LIMIT; + } + /** + * Check if the size (length or count) of the specified limit property is + * over the limit + * + * @param limit the type of the limit property + * @param entityName the name of the entity + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(Limit limit, String entityName, int size, + XMLLimitAnalyzer limitAnalyzer) { + return isOverLimit(limit.ordinal(), entityName, size, limitAnalyzer); + } + + /** + * Check if the value (length or count) of the specified limit property is + * over the limit + * + * @param index the index of the limit property + * @param entityName the name of the entity + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(int index, String entityName, int size, + XMLLimitAnalyzer limitAnalyzer) { + if (values[index] == NO_LIMIT) { + return false; + } + if (size > values[index]) { + limitAnalyzer.addValue(index, entityName, size); + return true; + } + return false; + } + + /** + * Check against cumulated value + * + * @param limit the type of the limit property + * @param size the size (count or length) of the entity + * @return true if the size is over the limit, false otherwise + */ + public boolean isOverLimit(Limit limit, XMLLimitAnalyzer limitAnalyzer) { + return isOverLimit(limit.ordinal(), limitAnalyzer); + } + + public boolean isOverLimit(int index, XMLLimitAnalyzer limitAnalyzer) { + if (values[index] == NO_LIMIT) { + return false; + } + + if (index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || + index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || + index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal() || + index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() || + index == Limit.MAX_NAME_LIMIT.ordinal() + ) { + return (limitAnalyzer.getTotalValue(index) > values[index]); + } else { + return (limitAnalyzer.getValue(index) > values[index]); + } + } + + public void debugPrint(XMLLimitAnalyzer limitAnalyzer) { + if (printEntityCountInfo.equals(XalanConstants.JDK_YES)) { + limitAnalyzer.debugPrint(this); + } + } + + + /** + * Indicate if a property is set explicitly + * @param index + * @return + */ + public boolean isSet(int index) { + return isSet[index]; + } + + public boolean printEntityCountInfo() { + return printEntityCountInfo.equals(XalanConstants.JDK_YES); + } + + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + + for (Limit limit : Limit.values()) { + if (!getSystemProperty(limit, limit.systemProperty())) { + //if system property is not found, try the older form if any + for (NameMap nameMap : NameMap.values()) { + String oldName = nameMap.getOldName(limit.systemProperty()); + if (oldName != null) { + getSystemProperty(limit, oldName); + } + } + } + } + + } + + // Array list to store printed warnings for each SAX parser used + private static final CopyOnWriteArrayList<String> printedWarnings = new CopyOnWriteArrayList<>(); + + /** + * Prints out warnings if a parser does not support the specified feature/property. + * + * @param parserClassName the name of the parser class + * @param propertyName the property name + * @param exception the exception thrown by the parser + */ + public static void printWarning(String parserClassName, String propertyName, SAXException exception) { + String key = parserClassName+":"+propertyName; + if (printedWarnings.addIfAbsent(key)) { + System.err.println( "Warning: "+parserClassName+": "+exception.getMessage()); + } + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param property the type of the property + * @param sysPropertyName the name of system property + */ + private boolean getSystemProperty(Limit limit, String sysPropertyName) { + try { + String value = SecuritySupport.getSystemProperty(sysPropertyName); + if (value != null && !value.equals("")) { + values[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.SYSTEMPROPERTY; + return true; + } + + value = SecuritySupport.readJAXPProperty(sysPropertyName); + if (value != null && !value.equals("")) { + values[limit.ordinal()] = Integer.parseInt(value); + states[limit.ordinal()] = State.JAXPDOTPROPERTIES; + return true; + } + } catch (NumberFormatException e) { + //invalid setting + throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty()); + } + return false; + } + + + /** + * Convert a value set through setProperty to XMLSecurityManager. + * If the value is an instance of XMLSecurityManager, use it to override the default; + * If the value is an old SecurityManager, convert to the new XMLSecurityManager. + * + * @param value user specified security manager + * @param securityManager an instance of XMLSecurityManager + * @return an instance of the new security manager XMLSecurityManager + */ + public static XMLSecurityManager convert(Object value, XMLSecurityManager securityManager) { + if (value == null) { + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + return securityManager; + } + if (value instanceof XMLSecurityManager) { + return (XMLSecurityManager)value; + } else { + if (securityManager == null) { + securityManager = new XMLSecurityManager(true); + } + if (value instanceof SecurityManager) { + SecurityManager origSM = (SecurityManager)value; + securityManager.setLimit(Limit.MAX_OCCUR_NODE_LIMIT, State.APIPROPERTY, origSM.getMaxOccurNodeLimit()); + securityManager.setLimit(Limit.ENTITY_EXPANSION_LIMIT, State.APIPROPERTY, origSM.getEntityExpansionLimit()); + securityManager.setLimit(Limit.ELEMENT_ATTRIBUTE_LIMIT, State.APIPROPERTY, origSM.getElementAttrLimit()); + } + return securityManager; + } + } +}
diff --git a/src/java.xml/share/classes/module-info.java b/src/java.xml/share/classes/module-info.java index d4d147d..3fe717f 100644 --- a/src/java.xml/share/classes/module-info.java +++ b/src/java.xml/share/classes/module-info.java
@@ -199,7 +199,7 @@ * <th scope="col" rowspan="2">Description</th> * <th scope="col" rowspan="2">System Property [2]</th> * <th scope="col" rowspan="2">jaxp.properties [2]</th> - * <th scope="col" colspan="3" style="text-align:center">Value [3]</th> + * <th scope="col" colspan="4" style="text-align:center">Value [3]</th> * <th scope="col" rowspan="2">Security [4]</th> * <th scope="col" rowspan="2">Supported Processor [5]</th> * <th scope="col" rowspan="2">Since [6]</th> @@ -208,6 +208,7 @@ * <th scope="col">Type</th> * <th scope="col">Value</th> * <th scope="col">Default</th> + * <th scope="col">Enforced</th> * </tr> * </thead> * @@ -226,10 +227,46 @@ * <td>boolean</td> * <th id="Value" scope="row" style="font-weight:normal">true/false</th> * <th id="Default" scope="row" style="font-weight:normal">false</th> + * <td style="text-align:center">N/A</td> * <td>No</td> * <td><a href="#DOMLS">DOMLS</a></td> * <td>17</td> * </tr> + * <tr> + * <td id="extensionClassLoader">jdk.xml.xpathExprGrpLimit</td> + * <td>Limits the number of groups an XPath expression can contain. + * </td> + * <td style="text-align:center" rowspan="3">yes</td> + * <td style="text-align:center" rowspan="3">yes</td> + * <td style="text-align:center" rowspan="3">Integer</td> + * <td rowspan="3">A positive integer. A value less than or equal to 0 indicates no limit. + * If the value is not an integer, a NumberFormatException is thrown. </td> + * <td style="text-align:center">10</td> + * <td style="text-align:center">10</td> + * <td style="text-align:center" rowspan="3">Yes</td> + * <td style="text-align:center" rowspan="2"> + * <a href="#Transform">Transform</a><br> + * <a href="#XPath">XPath</a> + * </td> + * <td style="text-align:center" rowspan="3">19</td> + * </tr> + * <tr> + * <td id="extensionClassLoader">jdk.xml.xpathExprOpLimit</td> + * <td>Limits the number of operators an XPath expression can contain. + * </td> + * <td style="text-align:center">100</td> + * <td style="text-align:center">100</td> + * </tr> + * <tr> + * <td id="extensionClassLoader">jdk.xml.xpathTotalOpLimit</td> + * <td>Limits the total number of XPath operators in an XSL Stylesheet. + * </td> + * <td style="text-align:center">10000</td> + * <td style="text-align:center">10000</td> + * <td style="text-align:center"> + * <a href="#Transform">Transform</a><br> + * </td> + * </tr> * </tbody> * </table> * <p>
diff --git a/src/java.xml/share/legal/bcel.md b/src/java.xml/share/legal/bcel.md index 5e46130..aca04ab 100644 --- a/src/java.xml/share/legal/bcel.md +++ b/src/java.xml/share/legal/bcel.md
@@ -1,4 +1,4 @@ -## Apache Commons Byte Code Engineering Library (BCEL) Version 6.4.1 +## Apache Commons Byte Code Engineering Library (BCEL) Version 6.5.0 ### Apache Commons BCEL Notice <pre>
diff --git a/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java b/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java index c094622..1c0fb92 100644 --- a/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java +++ b/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ "This provider is not supported on this version of Windows"); } String arch = System.getProperty("os.arch"); - if (!arch.equals("x86") && !arch.equals("amd64")) { + if (!arch.equals("x86") && !arch.equals("amd64") && !arch.equals("aarch64")) { throw new RuntimeException( "This provider is not supported on this processor architecture"); }
diff --git a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c index a21ce9f..f08a7c0 100644 --- a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -399,6 +399,7 @@ /* * Setup data to copy to target process */ + memset(&data, 0, sizeof(data)); data._GetModuleHandle = _GetModuleHandle; data._GetProcAddress = _GetProcAddress;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java index 33b822b..d1205d4 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java
@@ -182,6 +182,7 @@ UNDERSCORE_IDENTIFIER(MIN, JDK8), PRIVATE_INTERFACE_METHODS(JDK9, Fragments.FeaturePrivateIntfMethods, DiagKind.PLURAL), LOCAL_VARIABLE_TYPE_INFERENCE(JDK10), + VAR_SYNTAX_IMPLICIT_LAMBDAS(JDK11, Fragments.FeatureVarSyntaxInImplicitLambda, DiagKind.PLURAL), IMPORT_ON_DEMAND_OBSERVABLE_PACKAGES(JDK1_2, JDK8); enum DiagKind {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 0f77ad3..b015bcb 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
@@ -1209,7 +1209,9 @@ .methodParameter(tree, i, param.vartype.pos); push(param); try { - separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); + if (!param.declaredUsingVar()) { + separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); + } } finally { pop(); } @@ -1247,7 +1249,7 @@ final TypeAnnotationPosition pos = TypeAnnotationPosition.localVariable(currentLambda, tree.pos); - if (!tree.isImplicitlyTyped()) { + if (!tree.declaredUsingVar()) { separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); } } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index b597838..957b83b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
@@ -3084,8 +3084,19 @@ /** Is the annotation applicable to the symbol? */ boolean annotationApplicable(JCAnnotation a, Symbol s) { + Optional<Set<Name>> targets = getApplicableTargets(a, s); + /* the optional could be emtpy if the annotation is unknown in that case + * we return that it is applicable and if it is erroneous that should imply + * an error at the declaration site + */ + return !targets.isPresent() || targets.isPresent() && !targets.get().isEmpty(); + } + + @SuppressWarnings("preview") + Optional<Set<Name>> getApplicableTargets(JCAnnotation a, Symbol s) { Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); Name[] targets; + Set<Name> applicableTargets = new HashSet<>(); if (arr == null) { targets = defaultTargetMetaInfo(a, s); @@ -3095,7 +3106,8 @@ for (int i=0; i<arr.values.length; ++i) { Attribute app = arr.values[i]; if (!(app instanceof Attribute.Enum)) { - return true; // recovery + // recovery + return Optional.empty(); } Attribute.Enum e = (Attribute.Enum) app; targets[i] = e.value.name; @@ -3104,51 +3116,51 @@ for (Name target : targets) { if (target == names.TYPE) { if (s.kind == TYP) - return true; + applicableTargets.add(names.TYPE); } else if (target == names.FIELD) { if (s.kind == VAR && s.owner.kind != MTH) - return true; + applicableTargets.add(names.FIELD); } else if (target == names.METHOD) { if (s.kind == MTH && !s.isConstructor()) - return true; + applicableTargets.add(names.METHOD); } else if (target == names.PARAMETER) { if (s.kind == VAR && s.owner.kind == MTH && (s.flags() & PARAMETER) != 0) { - return true; + applicableTargets.add(names.PARAMETER); } } else if (target == names.CONSTRUCTOR) { if (s.kind == MTH && s.isConstructor()) - return true; + applicableTargets.add(names.CONSTRUCTOR); } else if (target == names.LOCAL_VARIABLE) { if (s.kind == VAR && s.owner.kind == MTH && (s.flags() & PARAMETER) == 0) { - return true; + applicableTargets.add(names.LOCAL_VARIABLE); } } else if (target == names.ANNOTATION_TYPE) { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) { - return true; + applicableTargets.add(names.ANNOTATION_TYPE); } } else if (target == names.PACKAGE) { if (s.kind == PCK) - return true; + applicableTargets.add(names.PACKAGE); } else if (target == names.TYPE_USE) { if (s.kind == VAR && s.owner.kind == MTH && s.type.hasTag(NONE)) { - //cannot type annotate implictly typed locals - return false; + //cannot type annotate implicitly typed locals + continue; } else if (s.kind == TYP || s.kind == VAR || (s.kind == MTH && !s.isConstructor() && !s.type.getReturnType().hasTag(VOID)) || (s.kind == MTH && s.isConstructor())) { - return true; + applicableTargets.add(names.TYPE_USE); } } else if (target == names.TYPE_PARAMETER) { if (s.kind == TYP && s.type.hasTag(TYPEVAR)) - return true; + applicableTargets.add(names.TYPE_PARAMETER); } else - return true; // Unknown ElementType. This should be an error at declaration site, - // assume applicable. + return Optional.empty(); // Unknown ElementType. This should be an error at declaration site, + // assume applicable. } - return false; + return Optional.of(applicableTargets); }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 03b67a1..c75f854 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
@@ -150,7 +150,7 @@ JCExpression clazz = copy(t.clazz, p); List<JCExpression> args = copy(t.args, p); JCClassDecl def = null; - return make.at(t.pos).SpeculativeNewClass(encl, typeargs, clazz, args, def, t.def != null); + return make.at(t.pos).SpeculativeNewClass(encl, typeargs, clazz, args, def, t.def != null || t.classDeclRemoved()); } else { return super.visitNewClass(node, p); }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 79596fc..f168eb3 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java
@@ -313,7 +313,7 @@ fs = new DirectoryContainer(realPath); } else { try { - fs = new ArchiveContainer(realPath); + fs = new ArchiveContainer(path); } catch (ProviderNotFoundException | SecurityException ex) { throw new IOException(ex); }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java index f5ead78..eae721f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java
@@ -288,6 +288,11 @@ return userPath.toString(); } + @Override @DefinedBy(Api.COMPILER) + public String getShortName() { + return userPath.getFileName().toString(); + } + @Override public String inferBinaryName(Iterable<? extends Path> paths) { Path absPath = path.toAbsolutePath();
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index b808f24..8fc29ad 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -1690,7 +1690,9 @@ if (param.vartype != null && isRestrictedLocalVarTypeName(param.vartype, false) && param.vartype.hasTag(TYPEARRAY)) { - log.error(DiagnosticFlag.SYNTAX, param.pos, Errors.VarNotAllowedArray); + log.error(DiagnosticFlag.SYNTAX, param.pos, + Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source) + ? Errors.VarNotAllowedArray : Errors.VarNotAllowedHere); } lambdaClassifier.addParameter(param); if (lambdaClassifier.result() == LambdaParameterKind.ERROR) { @@ -1701,7 +1703,9 @@ log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidLambdaParameterDeclaration(lambdaClassifier.diagFragment)); } for (JCVariableDecl param: params) { - if (param.vartype != null && isRestrictedLocalVarTypeName(param.vartype, true)) { + if (param.vartype != null + && isRestrictedLocalVarTypeName(param.vartype, true)) { + checkSourceLevel(param.pos, Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS); param.startPos = TreeInfo.getStartPos(param.vartype); param.vartype = null; } @@ -1711,9 +1715,9 @@ } enum LambdaParameterKind { - EXPLICIT(0), - IMPLICIT(1), - VAR(2), + VAR(0), + EXPLICIT(1), + IMPLICIT(2), ERROR(-1); private final int index; @@ -1723,11 +1727,11 @@ } } - private final static Fragment[][] decisionTable = new Fragment[][]{ - /* EXPLICIT IMPLICIT VAR */ - /* EXPLICIT */ {null, ImplicitAndExplicitNotAllowed, VarAndExplicitNotAllowed}, - /* IMPLICIT */ {ImplicitAndExplicitNotAllowed, null, VarAndImplicitNotAllowed}, - /* VAR */ {VarAndExplicitNotAllowed, VarAndImplicitNotAllowed, null} + private final static Fragment[][] decisionTable = new Fragment[][] { + /* VAR EXPLICIT IMPLICIT */ + /* VAR */ {null, VarAndExplicitNotAllowed, VarAndImplicitNotAllowed}, + /* EXPLICIT */ {VarAndExplicitNotAllowed, null, ImplicitAndExplicitNotAllowed}, + /* IMPLICIT */ {VarAndImplicitNotAllowed, ImplicitAndExplicitNotAllowed, null}, }; class LambdaClassifier { @@ -1756,7 +1760,10 @@ } else if (kind != newKind && kind != LambdaParameterKind.ERROR) { LambdaParameterKind currentKind = kind; kind = LambdaParameterKind.ERROR; - diagFragment = decisionTable[currentKind.index][newKind.index]; + boolean varIndex = currentKind.index == LambdaParameterKind.VAR.index || + newKind.index == LambdaParameterKind.VAR.index; + diagFragment = Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source) || !varIndex ? + decisionTable[currentKind.index][newKind.index] : null; } } @@ -3047,6 +3054,7 @@ */ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, boolean reqInit, Comment dc, boolean localDecl, boolean compound) { + boolean declaredUsingVar = false; type = bracketsOpt(type); JCExpression init = null; if (token.kind == EQ) { @@ -3066,6 +3074,7 @@ //error - 'var' and arrays reportSyntaxError(pos, Errors.VarNotAllowedArray); } else { + declaredUsingVar = true; startPos = TreeInfo.getStartPos(mods); if (startPos == Position.NOPOS) startPos = TreeInfo.getStartPos(type); @@ -3075,7 +3084,7 @@ } } JCVariableDecl result = - toP(F.at(pos).VarDef(mods, name, type, init)); + toP(F.at(pos).VarDef(mods, name, type, init, declaredUsingVar)); attach(result, dc); result.startPos = startPos; return result; @@ -3155,7 +3164,8 @@ log.error(token.pos, Errors.VarargsAndOldArraySyntax); } type = bracketsOpt(type); - return toP(F.at(pos).VarDef(mods, name, type, null)); + return toP(F.at(pos).VarDef(mods, name, type, null, + type != null && type.hasTag(IDENT) && ((JCIdent)type).name == names.var)); } /** Resources = Resource { ";" Resources }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 0b9b3a8..e24a725 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -2795,6 +2795,9 @@ compiler.misc.feature.private.intf.methods=\ private interface methods +compiler.misc.feature.var.syntax.in.implicit.lambda=\ + var syntax in implicit lambdas + compiler.warn.underscore.as.identifier=\ as of release 9, ''_'' is a keyword, and may not be used as an identifier
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java index f265ed1..a204aa9 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
@@ -922,23 +922,35 @@ public VarSymbol sym; /** explicit start pos */ public int startPos = Position.NOPOS; + /** declared using `var` */ + private boolean declaredUsingVar; protected JCVariableDecl(JCModifiers mods, Name name, JCExpression vartype, JCExpression init, VarSymbol sym) { + this(mods, name, vartype, init, sym, false); + } + + protected JCVariableDecl(JCModifiers mods, + Name name, + JCExpression vartype, + JCExpression init, + VarSymbol sym, + boolean declaredUsingVar) { this.mods = mods; this.name = name; this.vartype = vartype; this.init = init; this.sym = sym; + this.declaredUsingVar = declaredUsingVar; } protected JCVariableDecl(JCModifiers mods, JCExpression nameexpr, JCExpression vartype) { - this(mods, null, vartype, null, null); + this(mods, null, vartype, null, null, false); this.nameexpr = nameexpr; if (nameexpr.hasTag(Tag.IDENT)) { this.name = ((JCIdent)nameexpr).name; @@ -952,6 +964,10 @@ return vartype == null; } + public boolean declaredUsingVar() { + return declaredUsingVar; + } + @Override public void accept(Visitor v) { v.visitVarDef(this); }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java index c2c1102..9545993 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
@@ -215,6 +215,12 @@ return tree; } + public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init, boolean declaredUsingVar) { + JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null, declaredUsingVar); + tree.pos = pos; + return tree; + } + public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) { JCVariableDecl tree = new JCVariableDecl(mods, name, vartype); tree.pos = pos;
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java index a5d3f10..3bcef1f 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java
@@ -143,7 +143,15 @@ // how often to test for token insertion, if no token is present private int insertionCheckInterval = 2000; - // flag inidicating whether to omit the call to C_Initialize() + // short ms value to indicate how often native cleaner thread is called + private int resourceCleanerShortInterval = 2_000; + // long ms value to indicate how often native cleaner thread is called + private int resourceCleanerLongInterval = 60_000; + + // should Token be destroyed after logout() + private boolean destroyTokenAfterLogout; + + // flag indicating whether to omit the call to C_Initialize() // should be used only if we are running within a process that // has already called it (e.g. Plugin inside of Mozilla/NSS) private boolean omitInitialize = false; @@ -277,6 +285,18 @@ return explicitCancel; } + boolean getDestroyTokenAfterLogout() { + return destroyTokenAfterLogout; + } + + int getResourceCleanerShortInterval() { + return resourceCleanerShortInterval; + } + + int getResourceCleanerLongInterval() { + return resourceCleanerLongInterval; + } + int getInsertionCheckInterval() { return insertionCheckInterval; } @@ -411,6 +431,18 @@ if (insertionCheckInterval < 100) { throw excLine(word + " must be at least 100 ms"); } + } else if (word.equals("cleaner.shortInterval")) { + resourceCleanerShortInterval = parseIntegerEntry(word); + if (resourceCleanerShortInterval < 1_000) { + throw excLine(word + " must be at least 1000 ms"); + } + } else if (word.equals("cleaner.longInterval")) { + resourceCleanerLongInterval = parseIntegerEntry(word); + if (resourceCleanerLongInterval < 1_000) { + throw excLine(word + " must be at least 1000 ms"); + } + } else if (word.equals("destroyTokenAfterLogout")) { + destroyTokenAfterLogout = parseBooleanEntry(word); } else if (word.equals("showInfo")) { showInfo = parseBooleanEntry(word); } else if (word.equals("keyStoreCompatibilityMode")) {
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/KeyCache.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/KeyCache.java index 1687649..7bfe427 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/KeyCache.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/KeyCache.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,4 +100,8 @@ map.put(key, p11Key); } + synchronized void clear() { + strongCache.clear(); + cacheReference = null; + } }
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java index 7913d75..fa8fb3f 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java
@@ -42,28 +42,38 @@ /** * P11 AEAD Cipher implementation class. This class currently supports - * AES with GCM mode. + * AES cipher in GCM mode and CHACHA20-POLY1305 cipher. * * Note that AEAD modes do not use padding, so this class does not have - * its own padding impl. In addition, NSS CKM_AES_GCM only supports single-part - * encryption/decryption, thus the current impl uses PKCS#11 C_Encrypt/C_Decrypt - * calls and buffers data until doFinal is called. - * - * Note that PKCS#11 standard currently only supports GCM and CCM AEAD modes. - * There are no provisions for other AEAD modes yet. + * its own padding impl. In addition, some vendors such as NSS may not support + * multi-part encryption/decryption for AEAD cipher algorithms, thus the + * current impl uses PKCS#11 C_Encrypt/C_Decrypt calls and buffers data until + * doFinal is called. * * @since 13 */ final class P11AEADCipher extends CipherSpi { - // mode constant for GCM mode - private static final int MODE_GCM = 10; + // supported AEAD algorithms/transformations + private enum Transformation { + AES_GCM("AES", "GCM", "NOPADDING", 16, 16), + CHACHA20_POLY1305("CHACHA20", "NONE", "NOPADDING", 12, 16); - // default constants for GCM - private static final int GCM_DEFAULT_TAG_LEN = 16; - private static final int GCM_DEFAULT_IV_LEN = 16; + final String keyAlgo; + final String mode; + final String padding; + final int defIvLen; // in bytes + final int defTagLen; // in bytes - private static final String ALGO = "AES"; + Transformation(String keyAlgo, String mode, String padding, + int defIvLen, int defTagLen) { + this.keyAlgo = keyAlgo; + this.mode = mode; + this.padding = padding; + this.defIvLen = defIvLen; + this.defTagLen = defTagLen; + } + } // token instance private final Token token; @@ -71,10 +81,10 @@ // mechanism id private final long mechanism; - // mode, one of MODE_* above - private final int blockMode; + // type of this AEAD cipher, one of Transformation enum above + private final Transformation type; - // acceptable key size, -1 if more than 1 key sizes are accepted + // acceptable key size in bytes, -1 if more than 1 key sizes are accepted private final int fixedKeySize; // associated session, if any @@ -111,99 +121,129 @@ this.mechanism = mechanism; String[] algoParts = algorithm.split("/"); - if (algoParts.length != 3) { - throw new ProviderException("Unsupported Transformation format: " + - algorithm); - } - if (!algoParts[0].startsWith("AES")) { - throw new ProviderException("Only support AES for AEAD cipher mode"); - } - int index = algoParts[0].indexOf('_'); - if (index != -1) { - // should be well-formed since we specify what we support - fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1)) >> 3; + if (algoParts[0].startsWith("AES")) { + // for AES_GCM, need 3 parts + if (algoParts.length != 3) { + throw new AssertionError("Invalid Transformation format: " + + algorithm); + } + int index = algoParts[0].indexOf('_'); + if (index != -1) { + // should be well-formed since we specify what we support + fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1)) >> 3; + } else { + fixedKeySize = -1; + } + this.type = Transformation.AES_GCM; + engineSetMode(algoParts[1]); + try { + engineSetPadding(algoParts[2]); + } catch (NoSuchPaddingException e) { + throw new NoSuchAlgorithmException(); + } + } else if (algoParts[0].equals("ChaCha20-Poly1305")) { + fixedKeySize = 32; + this.type = Transformation.CHACHA20_POLY1305; + if (algoParts.length > 3) { + throw new AssertionError( + "Invalid Transformation format: " + algorithm); + } else { + if (algoParts.length > 1) { + engineSetMode(algoParts[1]); + } + try { + if (algoParts.length > 2) { + engineSetPadding(algoParts[2]); + } + } catch (NoSuchPaddingException e) { + throw new NoSuchAlgorithmException(); + } + } } else { - fixedKeySize = -1; - } - this.blockMode = parseMode(algoParts[1]); - if (!algoParts[2].equals("NoPadding")) { - throw new ProviderException("Only NoPadding is supported for AEAD cipher mode"); + throw new AssertionError("Unsupported transformation " + algorithm); } } + @Override protected void engineSetMode(String mode) throws NoSuchAlgorithmException { - // Disallow change of mode for now since currently it's explicitly - // defined in transformation strings - throw new NoSuchAlgorithmException("Unsupported mode " + mode); - } - - private int parseMode(String mode) throws NoSuchAlgorithmException { - mode = mode.toUpperCase(Locale.ENGLISH); - int result; - if (mode.equals("GCM")) { - result = MODE_GCM; - } else { + if (!mode.toUpperCase(Locale.ENGLISH).equals(type.mode)) { throw new NoSuchAlgorithmException("Unsupported mode " + mode); } - return result; } // see JCE spec + @Override protected void engineSetPadding(String padding) throws NoSuchPaddingException { - // Disallow change of padding for now since currently it's explicitly - // defined in transformation strings - throw new NoSuchPaddingException("Unsupported padding " + padding); + if (!padding.toUpperCase(Locale.ENGLISH).equals(type.padding)) { + throw new NoSuchPaddingException("Unsupported padding " + padding); + } } // see JCE spec + @Override protected int engineGetBlockSize() { - return 16; // constant; only AES is supported + switch (type) { + case AES_GCM: return 16; + case CHACHA20_POLY1305: return 0; + default: throw new AssertionError("Unsupported type " + type); + } } // see JCE spec + @Override protected int engineGetOutputSize(int inputLen) { return doFinalLength(inputLen); } // see JCE spec + @Override protected byte[] engineGetIV() { return (iv == null) ? null : iv.clone(); } // see JCE spec protected AlgorithmParameters engineGetParameters() { - if (encrypt && iv == null && tagLen == -1) { - switch (blockMode) { - case MODE_GCM: - iv = new byte[GCM_DEFAULT_IV_LEN]; - tagLen = GCM_DEFAULT_TAG_LEN; - break; - default: - throw new ProviderException("Unsupported mode"); - } - random.nextBytes(iv); - } - try { - AlgorithmParameterSpec spec; - String apAlgo; - switch (blockMode) { - case MODE_GCM: - apAlgo = "GCM"; + String apAlgo; + AlgorithmParameterSpec spec = null; + switch (type) { + case AES_GCM: + apAlgo = "GCM"; + if (encrypt && iv == null && tagLen == -1) { + iv = new byte[type.defIvLen]; + tagLen = type.defTagLen; + random.nextBytes(iv); + } + if (iv != null) { spec = new GCMParameterSpec(tagLen << 3, iv); - break; - default: - throw new ProviderException("Unsupported mode"); - } - AlgorithmParameters params = - AlgorithmParameters.getInstance(apAlgo); - params.init(spec); - return params; - } catch (GeneralSecurityException e) { - // NoSuchAlgorithmException, NoSuchProviderException - // InvalidParameterSpecException - throw new ProviderException("Could not encode parameters", e); + } + break; + case CHACHA20_POLY1305: + if (encrypt && iv == null) { + iv = new byte[type.defIvLen]; + random.nextBytes(iv); + } + apAlgo = "ChaCha20-Poly1305"; + if (iv != null) { + spec = new IvParameterSpec(iv); + } + break; + default: + throw new AssertionError("Unsupported type " + type); } + if (spec != null) { + try { + AlgorithmParameters params = + AlgorithmParameters.getInstance(apAlgo); + params.init(spec); + return params; + } catch (GeneralSecurityException e) { + // NoSuchAlgorithmException, NoSuchProviderException + // InvalidParameterSpecException + throw new ProviderException("Could not encode parameters", e); + } + } + return null; } // see JCE spec @@ -231,20 +271,30 @@ updateCalled = false; byte[] ivValue = null; int tagLen = -1; - if (params != null) { - switch (blockMode) { - case MODE_GCM: - if (!(params instanceof GCMParameterSpec)) { - throw new InvalidAlgorithmParameterException - ("Only GCMParameterSpec is supported"); + switch (type) { + case AES_GCM: + if (params != null) { + if (!(params instanceof GCMParameterSpec)) { + throw new InvalidAlgorithmParameterException + ("Only GCMParameterSpec is supported"); + } + ivValue = ((GCMParameterSpec) params).getIV(); + tagLen = ((GCMParameterSpec) params).getTLen() >> 3; } - ivValue = ((GCMParameterSpec) params).getIV(); - tagLen = ((GCMParameterSpec) params).getTLen() >> 3; + break; + case CHACHA20_POLY1305: + if (params != null) { + if (!(params instanceof IvParameterSpec)) { + throw new InvalidAlgorithmParameterException + ("Only IvParameterSpec is supported"); + } + ivValue = ((IvParameterSpec) params).getIV(); + tagLen = type.defTagLen; + } break; default: - throw new ProviderException("Unsupported mode"); - } - } + throw new AssertionError("Unsupported type " + type); + }; implInit(opmode, key, ivValue, tagLen, sr); } @@ -260,13 +310,17 @@ try { AlgorithmParameterSpec paramSpec = null; if (params != null) { - switch (blockMode) { - case MODE_GCM: + switch (type) { + case AES_GCM: paramSpec = params.getParameterSpec(GCMParameterSpec.class); break; + case CHACHA20_POLY1305: + paramSpec = + params.getParameterSpec(IvParameterSpec.class); + break; default: - throw new ProviderException("Unsupported mode"); + throw new AssertionError("Unsupported type " + type); } } engineInit(opmode, key, paramSpec, sr); @@ -285,15 +339,16 @@ key.getEncoded().length) != fixedKeySize) { throw new InvalidKeyException("Key size is invalid"); } - P11Key newKey = P11SecretKeyFactory.convertKey(token, key, ALGO); + P11Key newKey = P11SecretKeyFactory.convertKey(token, key, + type.keyAlgo); switch (opmode) { case Cipher.ENCRYPT_MODE: encrypt = true; requireReinit = Arrays.equals(iv, lastEncIv) && (newKey == lastEncKey); if (requireReinit) { - throw new InvalidAlgorithmParameterException - ("Cannot reuse iv for GCM encryption"); + throw new InvalidAlgorithmParameterException( + "Cannot reuse the same key and iv pair"); } break; case Cipher.DECRYPT_MODE: @@ -309,16 +364,22 @@ if (sr != null) { this.random = sr; } + if (iv == null && tagLen == -1) { // generate default values - switch (blockMode) { - case MODE_GCM: - iv = new byte[GCM_DEFAULT_IV_LEN]; + switch (type) { + case AES_GCM: + iv = new byte[type.defIvLen]; this.random.nextBytes(iv); - tagLen = GCM_DEFAULT_TAG_LEN; + tagLen = type.defTagLen; + break; + case CHACHA20_POLY1305: + iv = new byte[type.defIvLen]; + this.random.nextBytes(iv); + tagLen = type.defTagLen; break; default: - throw new ProviderException("Unsupported mode"); + throw new AssertionError("Unsupported type " + type); } } this.iv = iv; @@ -382,7 +443,7 @@ } if (requireReinit) { throw new IllegalStateException - ("Must use either different key or iv for GCM encryption"); + ("Must use either different key or iv"); } token.ensureValid(); @@ -392,13 +453,17 @@ long p11KeyID = p11Key.getKeyID(); try { CK_MECHANISM mechWithParams; - switch (blockMode) { - case MODE_GCM: + switch (type) { + case AES_GCM: mechWithParams = new CK_MECHANISM(mechanism, new CK_GCM_PARAMS(tagLen << 3, iv, aad)); break; + case CHACHA20_POLY1305: + mechWithParams = new CK_MECHANISM(mechanism, + new CK_SALSA20_CHACHA20_POLY1305_PARAMS(iv, aad)); + break; default: - throw new ProviderException("Unsupported mode: " + blockMode); + throw new AssertionError("Unsupported type: " + type); } if (session == null) { session = token.getOpSession(); @@ -431,10 +496,13 @@ if (encrypt) { result += tagLen; } else { - // PKCS11Exception: CKR_BUFFER_TOO_SMALL - //result -= tagLen; + // In earlier NSS versions, AES_GCM would report + // CKR_BUFFER_TOO_SMALL error if minus tagLen + if (type == Transformation.CHACHA20_POLY1305) { + result -= tagLen; + } } - return result; + return (result > 0? result : 0); } // reset the states to the pre-initialized values @@ -492,7 +560,7 @@ } if (requireReinit) { throw new IllegalStateException - ("Must use either different key or iv for GCM encryption"); + ("Must use either different key or iv for encryption"); } if (p11Key == null) { throw new IllegalStateException("Need to initialize Cipher first"); @@ -595,6 +663,7 @@ if (outLen < requiredOutLen) { throw new ShortBufferException(); } + boolean doCancel = true; try { ensureInitialized(); @@ -712,6 +781,7 @@ outAddr, outArray, outOfs, outLen); doCancel = false; } + inBuffer.position(inBuffer.limit()); outBuffer.position(outBuffer.position() + k); return k; } catch (PKCS11Exception e) { @@ -748,8 +818,8 @@ } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID || // Solaris-specific errorCode == CKR_GENERAL_ERROR) { - throw (BadPaddingException) - (new BadPaddingException(e.toString()).initCause(e)); + throw (AEADBadTagException) + (new AEADBadTagException(e.toString()).initCause(e)); } } @@ -772,7 +842,7 @@ @Override protected int engineGetKeySize(Key key) throws InvalidKeyException { int n = P11SecretKeyFactory.convertKey - (token, key, ALGO).length(); + (token, key, type.keyAlgo).length(); return n; } }
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java index 8e2df4a..62fe416 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java
@@ -48,7 +48,6 @@ import static sun.security.pkcs11.TemplateManager.O_GENERATE; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; -import sun.security.util.Debug; import sun.security.util.DerValue; import sun.security.util.Length; import sun.security.util.ECUtil; @@ -141,8 +140,8 @@ && tokenLabel[2] == 'S'); boolean extractKeyInfo = (!DISABLE_NATIVE_KEYS_EXTRACTION && isNSS && extractable && !tokenObject); - this.keyIDHolder = new NativeKeyHolder(this, keyID, session, extractKeyInfo, - tokenObject); + this.keyIDHolder = new NativeKeyHolder(this, keyID, session, + extractKeyInfo, tokenObject); } public long getKeyID() { @@ -165,6 +164,18 @@ return (b == null) ? null : b.clone(); } + // Called by the NativeResourceCleaner at specified intervals + // See NativeResourceCleaner for more information + static boolean drainRefQueue() { + boolean found = false; + SessionKeyRef next; + while ((next = (SessionKeyRef) SessionKeyRef.refQueue.poll()) != null) { + found = true; + next.dispose(); + } + return found; + } + abstract byte[] getEncodedInternal(); public boolean equals(Object obj) { @@ -885,7 +896,7 @@ return params; } public int hashCode() { - if (token.isValid() == false) { + if (!token.isValid()) { return 0; } fetchValues(); @@ -894,7 +905,7 @@ public boolean equals(Object obj) { if (this == obj) return true; // equals() should never throw exceptions - if (token.isValid() == false) { + if (!token.isValid()) { return false; } if (!(obj instanceof DHPrivateKey)) { @@ -1132,7 +1143,6 @@ } } } - final class NativeKeyHolder { private static long nativeKeyWrapperKeyID = 0; @@ -1257,6 +1267,7 @@ this.ref = new SessionKeyRef(p11Key, keyID, wrapperKeyUsed, keySession); } + this.nativeKeyInfo = ((ki == null || ki.length == 0)? null : ki); } @@ -1330,24 +1341,9 @@ * still use these keys during finalization such as SSLSocket. */ final class SessionKeyRef extends PhantomReference<P11Key> { - private static ReferenceQueue<P11Key> refQueue = - new ReferenceQueue<P11Key>(); + static ReferenceQueue<P11Key> refQueue = new ReferenceQueue<>(); private static Set<SessionKeyRef> refSet = - Collections.synchronizedSet(new HashSet<SessionKeyRef>()); - - static ReferenceQueue<P11Key> referenceQueue() { - return refQueue; - } - - private static void drainRefQueueBounded() { - while (true) { - SessionKeyRef next = (SessionKeyRef) refQueue.poll(); - if (next == null) { - break; - } - next.dispose(); - } - } + Collections.synchronizedSet(new HashSet<>()); // handle to the native key and the session it is generated under private long keyID; @@ -1358,13 +1354,13 @@ Session session) { super(p11Key, refQueue); if (session == null) { - throw new ProviderException("key must be associated with a session"); + throw new ProviderException + ("key must be associated with a session"); } registerNativeKey(keyID, session); this.wrapperKeyUsed = wrapperKeyUsed; refSet.add(this); - drainRefQueueBounded(); } void registerNativeKey(long newKeyID, Session newSession) {
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java index 4df62de..9264146 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -194,6 +194,10 @@ keySize = 128; keyType = CKK_BLOWFISH; break; + case (int)CKM_CHACHA20_KEY_GEN: + keySize = 256; + keyType = CKK_CHACHA20; + break; default: throw new ProviderException("Unknown mechanism " + mechanism); }
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java index 68a3a06..c98960f 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java
@@ -68,6 +68,7 @@ addKeyType("DESede", CKK_DES3); addKeyType("AES", CKK_AES); addKeyType("Blowfish", CKK_BLOWFISH); + addKeyType("ChaCha20", CKK_CHACHA20); // we don't implement RC2 or IDEA, but we want to be able to generate // keys for those SSL/TLS ciphersuites. @@ -237,6 +238,10 @@ P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n, token); break; + case (int)CKK_CHACHA20: + keyLength = P11KeyGenerator.checkKeySize( + CKM_CHACHA20_KEY_GEN, n, token); + break; case (int)CKK_GENERIC_SECRET: case (int)PCKK_TLSPREMASTER: case (int)PCKK_TLSRSAPREMASTER:
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Session.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Session.java index 99d6da7..1f21ac2 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Session.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Session.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,10 +82,6 @@ return currentTime - lastAccess < MAX_IDLE_TIME; } - long idInternal() { - return id; - } - long id() { if (token.isPresent(this.id) == false) { throw new ProviderException("Token has been removed"); @@ -112,15 +108,40 @@ return createdObjects.get() != 0; } + // regular close which will not close sessions when there are objects(keys) + // still associated with them void close() { - if (hasObjects()) { + close(true); + } + + // forced close which will close sessions regardless if there are objects + // associated with them. Note that closing the sessions this way may + // lead to those associated objects(keys) un-usable. Thus should only be + // used for scenarios such as the token is about to be removed, etc. + void kill() { + close(false); + } + + private void close(boolean checkObjCtr) { + if (hasObjects() && checkObjCtr) { throw new ProviderException( - "Internal error: close session with active objects"); + "Internal error: close session with active objects"); } sessionRef.dispose(); } -} + // Called by the NativeResourceCleaner at specified intervals + // See NativeResourceCleaner for more information + static boolean drainRefQueue() { + boolean found = false; + SessionRef next; + while ((next = (SessionRef) SessionRef.refQueue.poll())!= null) { + found = true; + next.dispose(); + } + return found; + } +} /* * NOTE: Use PhantomReference here and not WeakReference * otherwise the sessions maybe closed before other objects @@ -129,27 +150,10 @@ final class SessionRef extends PhantomReference<Session> implements Comparable<SessionRef> { - private static ReferenceQueue<Session> refQueue = - new ReferenceQueue<Session>(); + static ReferenceQueue<Session> refQueue = new ReferenceQueue<>(); private static Set<SessionRef> refList = - Collections.synchronizedSortedSet(new TreeSet<SessionRef>()); - - static ReferenceQueue<Session> referenceQueue() { - return refQueue; - } - - static int totalCount() { - return refList.size(); - } - - private static void drainRefQueueBounded() { - while (true) { - SessionRef next = (SessionRef) refQueue.poll(); - if (next == null) break; - next.dispose(); - } - } + Collections.synchronizedSortedSet(new TreeSet<>()); // handle to the native session private long id; @@ -160,8 +164,6 @@ this.id = id; this.token = token; refList.add(this); - // TBD: run at some interval and not every time? - drainRefQueueBounded(); } void dispose() { @@ -170,9 +172,7 @@ if (token.isPresent(id)) { token.p11.C_CloseSession(id); } - } catch (PKCS11Exception e1) { - // ignore - } catch (ProviderException e2) { + } catch (PKCS11Exception | ProviderException e1) { // ignore } finally { this.clear();
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java index 6b2fdb1..ca8dee4 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,9 @@ package sun.security.pkcs11; import java.util.*; - import java.security.ProviderException; import sun.security.util.Debug; - import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; @@ -171,7 +169,9 @@ System.out.println("Killing session (" + location + ") active: " + activeSessions.get()); } - closeSession(session); + + session.kill(); + activeSessions.decrementAndGet(); return null; } @@ -179,7 +179,6 @@ if ((session == null) || (token.isValid() == false)) { return null; } - if (session.hasObjects()) { objSessions.release(session); } else { @@ -188,6 +187,11 @@ return null; } + void clearPools() { + objSessions.closeAll(); + opSessions.closeAll(); + } + void demoteObjSession(Session session) { if (token.isValid() == false) { return; @@ -196,6 +200,7 @@ System.out.println("Demoting session, active: " + activeSessions.get()); } + boolean present = objSessions.remove(session); if (present == false) { // session is currently in use @@ -238,6 +243,7 @@ private final SessionManager mgr; private final AbstractQueue<Session> pool; private final int SESSION_MAX = 5; + private volatile boolean closed = false; // Object session pools can contain unlimited sessions. // Operation session pools are limited and enforced by the queue. @@ -260,7 +266,7 @@ void release(Session session) { // Object session pools never return false, only Operation ones - if (!pool.offer(session)) { + if (closed || !pool.offer(session)) { mgr.closeSession(session); free(); } @@ -268,6 +274,9 @@ // Free any old operation session if this queue is full void free() { + // quick return path + if (pool.size() == 0) return; + int n = SESSION_MAX; int i = 0; Session oldestSession; @@ -291,6 +300,14 @@ } } + // empty out all sessions inside 'pool' and close them. + // however the Pool can still accept sessions + void closeAll() { + closed = true; + Session s; + while ((s = pool.poll()) != null) { + mgr.killSession(s); + } + } } - }
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index b00b738..099caac 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,10 +38,11 @@ import javax.security.auth.login.FailedLoginException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.ConfirmationCallback; import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.TextOutputCallback; +import com.sun.crypto.provider.ChaCha20Poly1305Parameters; + +import jdk.internal.misc.InnocuousThread; import sun.security.util.Debug; import sun.security.util.ResourcesMgr; import static sun.security.util.SecurityConstants.PROVIDER_VER; @@ -84,6 +85,8 @@ private TokenPoller poller; + static NativeResourceCleaner cleaner; + Token getToken() { return token; } @@ -599,6 +602,8 @@ m(CKM_AES_KEY_GEN)); d(KG, "Blowfish", P11KeyGenerator, m(CKM_BLOWFISH_KEY_GEN)); + d(KG, "ChaCha20", P11KeyGenerator, + m(CKM_CHACHA20_KEY_GEN)); // register (Secret)KeyFactories if there are any mechanisms // for a particular algorithm that we support @@ -625,6 +630,11 @@ d(AGP, "GCM", "sun.security.util.GCMParameters", m(CKM_AES_GCM)); + d(AGP, "ChaCha20-Poly1305", + "com.sun.crypto.provider.ChaCha20Poly1305Parameters", + s("1.2.840.113549.1.9.16.3.18", "OID.1.2.840.113549.1.9.16.3.18"), + m(CKM_CHACHA20_POLY1305)); + d(KA, "DH", P11KeyAgreement, s("DiffieHellman"), m(CKM_DH_PKCS_DERIVE)); d(KA, "ECDH", "sun.security.pkcs11.P11ECDHKeyAgreement", @@ -641,6 +651,8 @@ m(CKM_AES_CBC)); d(SKF, "Blowfish", P11SecretKeyFactory, m(CKM_BLOWFISH_CBC)); + d(SKF, "ChaCha20", P11SecretKeyFactory, + m(CKM_CHACHA20_POLY1305)); // XXX attributes for Ciphers (supported modes, padding) d(CIP, "ARCFOUR", P11Cipher, s("RC4"), @@ -708,6 +720,10 @@ d(CIP, "Blowfish/CBC/PKCS5Padding", P11Cipher, m(CKM_BLOWFISH_CBC)); + d(CIP, "ChaCha20-Poly1305", P11AEADCipher, + s("1.2.840.113549.1.9.16.3.18", "OID.1.2.840.113549.1.9.16.3.18"), + m(CKM_CHACHA20_POLY1305)); + d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher, s("RSA"), m(CKM_RSA_PKCS)); d(CIP, "RSA/ECB/NoPadding", P11RSACipher, @@ -833,10 +849,12 @@ private static class TokenPoller implements Runnable { private final SunPKCS11 provider; private volatile boolean enabled; + private TokenPoller(SunPKCS11 provider) { this.provider = provider; enabled = true; } + @Override public void run() { int interval = provider.config.getInsertionCheckInterval(); while (enabled) { @@ -861,17 +879,20 @@ } // create the poller thread, if not already active + @SuppressWarnings("removal") private void createPoller() { if (poller != null) { return; } - final TokenPoller poller = new TokenPoller(this); - Thread t = new Thread(null, poller, "Poller " + getName(), 0, false); - t.setContextClassLoader(null); + poller = new TokenPoller(this); + Thread t = InnocuousThread.newSystemThread( + "Poller-" + getName(), + poller, + Thread.MIN_PRIORITY); + assert t.getContextClassLoader() == null; t.setDaemon(true); - t.setPriority(Thread.MIN_PRIORITY); t.start(); - this.poller = poller; + } // destroy the poller thread, if active @@ -894,6 +915,62 @@ return (token != null) && token.isValid(); } + private class NativeResourceCleaner implements Runnable { + private long sleepMillis = config.getResourceCleanerShortInterval(); + private int count = 0; + boolean keyRefFound, sessRefFound; + + /* + * The cleaner.shortInterval and cleaner.longInterval properties + * may be defined in the pkcs11 config file and are specified in milliseconds + * Minimum value is 1000ms. Default values : + * cleaner.shortInterval : 2000ms + * cleaner.longInterval : 60000ms + * + * The cleaner thread runs at cleaner.shortInterval intervals + * while P11Key or Session references continue to be found for cleaning. + * If 100 iterations occur with no references being found, then the interval + * period moves to cleaner.longInterval value. The cleaner thread moves back + * to short interval checking if a resource is found + */ + @Override + public void run() { + while (true) { + try { + Thread.sleep(sleepMillis); + } catch (InterruptedException ie) { + break; + } + keyRefFound = P11Key.drainRefQueue(); + sessRefFound = Session.drainRefQueue(); + if (!keyRefFound && !sessRefFound) { + count++; + if (count > 100) { + // no reference freed for some time + // increase the sleep time + sleepMillis = config.getResourceCleanerLongInterval(); + } + } else { + count = 0; + sleepMillis = config.getResourceCleanerShortInterval(); + } + } + } + } + + // create the cleaner thread, if not already active + @SuppressWarnings("removal") + private void createCleaner() { + cleaner = new NativeResourceCleaner(); + Thread t = InnocuousThread.newSystemThread( + "Cleanup-SunPKCS11", + cleaner, + Thread.MIN_PRIORITY); + assert t.getContextClassLoader() == null; + t.setDaemon(true); + t.start(); + } + // destroy the token. Called if we detect that it has been removed synchronized void uninitToken(Token token) { if (this.token != token) { @@ -909,7 +986,10 @@ return null; } }); - createPoller(); + // keep polling for token insertion unless configured not to + if (removable && !config.getDestroyTokenAfterLogout()) { + createPoller(); + } } private static boolean isLegacy(CK_MECHANISM_INFO mechInfo) @@ -1056,6 +1136,9 @@ }); this.token = token; + if (cleaner == null) { + createCleaner(); + } } private static final class P11Service extends Service { @@ -1097,7 +1180,8 @@ } else if (type == CIP) { if (algorithm.startsWith("RSA")) { return new P11RSACipher(token, algorithm, mechanism); - } else if (algorithm.endsWith("GCM/NoPadding")) { + } else if (algorithm.endsWith("GCM/NoPadding") || + algorithm.startsWith("ChaCha20-Poly1305")) { return new P11AEADCipher(token, algorithm, mechanism); } else { return new P11Cipher(token, algorithm, mechanism); @@ -1150,6 +1234,8 @@ return new sun.security.util.ECParameters(); } else if (algorithm == "GCM") { return new sun.security.util.GCMParameters(); + } else if (algorithm == "ChaCha20-Poly1305") { + return new ChaCha20Poly1305Parameters(); // from SunJCE } else { throw new NoSuchAlgorithmException("Unsupported algorithm: " + algorithm); @@ -1270,12 +1356,12 @@ ("authProvider." + this.getName())); } - if (hasValidToken() == false) { + if (!hasValidToken()) { throw new LoginException("No token present"); + } // see if a login is required - if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) { if (debug != null) { debug.println("login operation not required for token - " + @@ -1387,7 +1473,6 @@ * this provider's <code>getName</code> method */ public void logout() throws LoginException { - if (!isConfigured()) { throw new IllegalStateException("Configuration is required"); } @@ -1413,10 +1498,13 @@ } try { - if (token.isLoggedInNow(null) == false) { + if (!token.isLoggedInNow(null)) { if (debug != null) { debug.println("user not logged in"); } + if (config.getDestroyTokenAfterLogout()) { + token.destroy(); + } return; } } catch (PKCS11Exception e) { @@ -1424,7 +1512,6 @@ } // perform token logout - Session session = null; try { session = token.getOpSession(); @@ -1445,6 +1532,9 @@ throw le; } finally { token.releaseSession(session); + if (config.getDestroyTokenAfterLogout()) { + token.destroy(); + } } }
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java index 39d301a..1d0c0a7 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java
@@ -291,8 +291,12 @@ } void destroy() { - valid = false; + secretCache.clear(); + privateCache.clear(); + + sessionManager.clearPools(); provider.uninitToken(this); + valid = false; } Session getObjSession() throws PKCS11Exception {
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java index 1e54646..db5474f 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -155,6 +155,11 @@ init(mechanism, params); } + public CK_MECHANISM(long mechanism, + CK_SALSA20_CHACHA20_POLY1305_PARAMS params) { + init(mechanism, params); + } + // For PSS. the parameter may be set multiple times, use the // CK_MECHANISM(long) constructor and setParameter(CK_RSA_PKCS_PSS_PARAMS) // methods instead of creating yet another constructor
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SALSA20_CHACHA20_POLY1305_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SALSA20_CHACHA20_POLY1305_PARAMS.java new file mode 100644 index 0000000..280279b --- /dev/null +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SALSA20_CHACHA20_POLY1305_PARAMS.java
@@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.pkcs11.wrapper; + +/** + * This class represents the necessary parameters required by the + * CKM_CHACHA20_POLY1305 and CKM_SALSA20_POLY1305 mechanisms as defined in + * CK_SALSA20_CHACHA20_POLY1305_PARAMS structure.<p> + * <B>PKCS#11 structure:</B> + * <PRE> + * typedef struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { + * CK_BYTE_PTR pNonce; + * CK_ULONG ulNonceLen; + * CK_BYTE_PTR pAAD; + * CK_ULONG ulAADLen; + * } CK_SALSA20_CHACHA20_POLY1305_PARAMS; + * </PRE> + * + * @since 17 + */ +public class CK_SALSA20_CHACHA20_POLY1305_PARAMS { + + private final byte[] nonce; + private final byte[] aad; + + public CK_SALSA20_CHACHA20_POLY1305_PARAMS(byte[] nonce, byte[] aad) { + this.nonce = nonce; + this.aad = aad; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append(Constants.INDENT); + sb.append("Nonce: "); + if (nonce == null) { + sb.append("null"); + } else { + sb.append("0x"); + for (byte b: nonce) { + sb.append(String.format("%02x", b)); + } + } + sb.append(Constants.NEWLINE); + sb.append(Constants.INDENT); + sb.append("AAD: "); + if (aad == null) { + sb.append("null"); + } else { + sb.append("0x"); + for (byte b: aad) { + sb.append(String.format("%02x", b)); + } + } + return sb.toString(); + } +}
diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c index 5990121..666c5eb 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -1160,6 +1160,73 @@ } /* + * converts the Java CK_SALSA20_CHACHA20_POLY1305_PARAMS object to a + * CK_SALSA20_CHACHA20_POLY1305_PARAMS pointer + * + * @param env - used to call JNI functions to get the Java classes and objects + * @param jParam - the Java CK_SALSA20_CHACHA20_POLY1305_PARAMS object to + * convert + * @param pLength - length of the allocated memory of the returned pointer + * @return pointer to the new CK_SALSA20_CHACHA20_POLY1305_PARAMS structure + */ +CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR +jSalsaChaChaPolyParamsToCKSalsaChaChaPolyParamPtr( + JNIEnv *env, jobject jParam, CK_ULONG *pLength) +{ + CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR ckParamPtr; + jclass jParamsClass; + jfieldID fieldID; + jobject jNonce, jAad; + + if (pLength != NULL) { + *pLength = 0; + } + + // retrieve java values + jParamsClass = (*env)->FindClass(env, + CLASS_SALSA20_CHACHA20_POLY1305_PARAMS); + if (jParamsClass == NULL) { return NULL; } + if (!(*env)->IsInstanceOf(env, jParam, jParamsClass)) { + return NULL; + } + fieldID = (*env)->GetFieldID(env, jParamsClass, "nonce", "[B"); + if (fieldID == NULL) { return NULL; } + jNonce = (*env)->GetObjectField(env, jParam, fieldID); + fieldID = (*env)->GetFieldID(env, jParamsClass, "aad", "[B"); + if (fieldID == NULL) { return NULL; } + jAad = (*env)->GetObjectField(env, jParam, fieldID); + // allocate memory for CK_SALSA20_CHACHA20_POLY1305_PARAMS pointer + ckParamPtr = calloc(1, sizeof(CK_SALSA20_CHACHA20_POLY1305_PARAMS)); + if (ckParamPtr == NULL) { + throwOutOfMemoryError(env, 0); + return NULL; + } + + // populate using java values + jByteArrayToCKByteArray(env, jNonce, &(ckParamPtr->pNonce), + &(ckParamPtr->ulNonceLen)); + if ((*env)->ExceptionCheck(env)) { + goto cleanup; + } + + jByteArrayToCKByteArray(env, jAad, &(ckParamPtr->pAAD), + &(ckParamPtr->ulAADLen)); + if ((*env)->ExceptionCheck(env)) { + goto cleanup; + } + + if (pLength != NULL) { + *pLength = sizeof(CK_SALSA20_CHACHA20_POLY1305_PARAMS); + } + return ckParamPtr; +cleanup: + free(ckParamPtr->pNonce); + free(ckParamPtr->pAAD); + free(ckParamPtr); + return NULL; +} + +/* * converts a Java CK_MECHANISM object into a CK_MECHANISM pointer * pointer. * @@ -1437,6 +1504,11 @@ case CKM_AES_CCM: ckpParamPtr = jCCMParamsToCKCCMParamPtr(env, jParam, ckpLength); break; + case CKM_CHACHA20_POLY1305: + ckpParamPtr = + jSalsaChaChaPolyParamsToCKSalsaChaChaPolyParamPtr(env, + jParam, ckpLength); + break; case CKM_RSA_PKCS_OAEP: ckpParamPtr = jRsaPkcsOaepParamToCKRsaPkcsOaepParamPtr(env, jParam, ckpLength); break;
diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c index cba1bf3..27006b9 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -323,6 +323,11 @@ free(((CK_CCM_PARAMS*)tmp)->pNonce); free(((CK_CCM_PARAMS*)tmp)->pAAD); break; + case CKM_CHACHA20_POLY1305: + TRACE0("[ CK_SALSA20_CHACHA20_POLY1305_PARAMS ]\n"); + free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pNonce); + free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pAAD); + break; case CKM_TLS_PRF: case CKM_NSS_TLS_PRF_GENERAL: TRACE0("[ CK_TLS_PRF_PARAMS ]\n");
diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h index 513810d..7159fc9 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -256,6 +256,8 @@ #define CLASS_AES_CTR_PARAMS "sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS" #define CLASS_GCM_PARAMS "sun/security/pkcs11/wrapper/CK_GCM_PARAMS" #define CLASS_CCM_PARAMS "sun/security/pkcs11/wrapper/CK_CCM_PARAMS" +#define CLASS_SALSA20_CHACHA20_POLY1305_PARAMS \ + "sun/security/pkcs11/wrapper/CK_SALSA20_CHACHA20_POLY1305_PARAMS" #define CLASS_RSA_PKCS_PSS_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS" #define CLASS_RSA_PKCS_OAEP_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS"
diff --git a/src/jdk.hotspot.agent/macosx/native/libsaproc/MacosxDebuggerLocal.m b/src/jdk.hotspot.agent/macosx/native/libsaproc/MacosxDebuggerLocal.m index 1188720..18b8b42 100644 --- a/src/jdk.hotspot.agent/macosx/native/libsaproc/MacosxDebuggerLocal.m +++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/MacosxDebuggerLocal.m
@@ -1,5 +1,6 @@ /* * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -42,14 +43,10 @@ #import <sys/ptrace.h> #include "libproc_impl.h" -#define UNSUPPORTED_ARCH "Unsupported architecture!" - -#if defined(x86_64) && !defined(amd64) -#define amd64 1 -#endif - -#if amd64 +#if defined(amd64) #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" +#elif defined(aarch64) +#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h" #else #error UNSUPPORTED_ARCH #endif @@ -162,20 +159,20 @@ return (struct ps_prochandle*)(intptr_t)ptr; } -#if defined(__i386__) - #define hsdb_thread_state_t x86_thread_state32_t - #define hsdb_float_state_t x86_float_state32_t - #define HSDB_THREAD_STATE x86_THREAD_STATE32 - #define HSDB_FLOAT_STATE x86_FLOAT_STATE32 - #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT - #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE32_COUNT -#elif defined(__x86_64__) +#if defined(amd64) #define hsdb_thread_state_t x86_thread_state64_t #define hsdb_float_state_t x86_float_state64_t #define HSDB_THREAD_STATE x86_THREAD_STATE64 #define HSDB_FLOAT_STATE x86_FLOAT_STATE64 #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT +#elif defined(aarch64) + #define hsdb_thread_state_t arm_thread_state64_t + #define hsdb_float_state_t arm_neon_state64_t + #define HSDB_THREAD_STATE ARM_THREAD_STATE64 + #define HSDB_FLOAT_STATE ARM_NEON_STATE64 + #define HSDB_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT + #define HSDB_FLOAT_STATE_COUNT ARM_NEON_STATE64_COUNT #else #error UNSUPPORTED_ARCH #endif @@ -493,11 +490,21 @@ lwpid_t uid = cinfos[j]; uint64_t beg = cinfos[j + 1]; uint64_t end = cinfos[j + 2]; +#if defined(amd64) if ((regs.r_rsp < end && regs.r_rsp >= beg) || (regs.r_rbp < end && regs.r_rbp >= beg)) { set_lwp_id(ph, i, uid); break; } +#elif defined(aarch64) + if ((regs.r_sp < end && regs.r_sp >= beg) || + (regs.r_fp < end && regs.r_fp >= beg)) { + set_lwp_id(ph, i, uid); + break; + } +#else +#error UNSUPPORTED_ARCH +#endif } } (*env)->ReleaseLongArrayElements(env, thrinfos, (jlong*)cinfos, 0); @@ -529,14 +536,22 @@ #undef NPRGREG #undef REG_INDEX -#if amd64 +#if defined(amd64) #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg +#elif defined(aarch64) +#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG +#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg +#else +#error UNSUPPORTED_ARCH +#endif array = (*env)->NewLongArray(env, NPRGREG); CHECK_EXCEPTION_(0); regs = (*env)->GetLongArrayElements(env, array, &isCopy); +#if defined(amd64) + regs[REG_INDEX(R15)] = gregs.r_r15; regs[REG_INDEX(R14)] = gregs.r_r14; regs[REG_INDEX(R13)] = gregs.r_r13; @@ -565,7 +580,46 @@ regs[REG_INDEX(TRAPNO)] = gregs.r_trapno; regs[REG_INDEX(RFL)] = gregs.r_rflags; -#endif /* amd64 */ +#elif defined(aarch64) + + regs[REG_INDEX(R0)] = gregs.r_r0; + regs[REG_INDEX(R1)] = gregs.r_r1; + regs[REG_INDEX(R2)] = gregs.r_r2; + regs[REG_INDEX(R3)] = gregs.r_r3; + regs[REG_INDEX(R4)] = gregs.r_r4; + regs[REG_INDEX(R5)] = gregs.r_r5; + regs[REG_INDEX(R6)] = gregs.r_r6; + regs[REG_INDEX(R7)] = gregs.r_r7; + regs[REG_INDEX(R8)] = gregs.r_r8; + regs[REG_INDEX(R9)] = gregs.r_r9; + regs[REG_INDEX(R10)] = gregs.r_r10; + regs[REG_INDEX(R11)] = gregs.r_r11; + regs[REG_INDEX(R12)] = gregs.r_r12; + regs[REG_INDEX(R13)] = gregs.r_r13; + regs[REG_INDEX(R14)] = gregs.r_r14; + regs[REG_INDEX(R15)] = gregs.r_r15; + regs[REG_INDEX(R16)] = gregs.r_r16; + regs[REG_INDEX(R17)] = gregs.r_r17; + regs[REG_INDEX(R18)] = gregs.r_r18; + regs[REG_INDEX(R19)] = gregs.r_r19; + regs[REG_INDEX(R20)] = gregs.r_r20; + regs[REG_INDEX(R21)] = gregs.r_r21; + regs[REG_INDEX(R22)] = gregs.r_r22; + regs[REG_INDEX(R23)] = gregs.r_r23; + regs[REG_INDEX(R24)] = gregs.r_r24; + regs[REG_INDEX(R25)] = gregs.r_r25; + regs[REG_INDEX(R26)] = gregs.r_r26; + regs[REG_INDEX(R27)] = gregs.r_r27; + regs[REG_INDEX(R28)] = gregs.r_r28; + regs[REG_INDEX(FP)] = gregs.r_fp; + regs[REG_INDEX(LR)] = gregs.r_lr; + regs[REG_INDEX(SP)] = gregs.r_sp; + regs[REG_INDEX(PC)] = gregs.r_pc; + +#else +#error UNSUPPORTED_ARCH +#endif + (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); return array; } @@ -655,10 +709,14 @@ return NULL; } -#if amd64 +#undef NPRGREG +#if defined(amd64) #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG -#undef REG_INDEX -#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg +#elif defined(aarch64) +#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG +#else +#error UNSUPPORTED_ARCH +#endif // 64 bit print_debug("Getting threads for a 64-bit process\n"); @@ -666,6 +724,8 @@ CHECK_EXCEPTION_(0); primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); +#if defined(amd64) + primitiveArray[REG_INDEX(R15)] = state.__r15; primitiveArray[REG_INDEX(R14)] = state.__r14; primitiveArray[REG_INDEX(R13)] = state.__r13; @@ -694,14 +754,50 @@ primitiveArray[REG_INDEX(DS)] = 0; primitiveArray[REG_INDEX(FSBASE)] = 0; primitiveArray[REG_INDEX(GSBASE)] = 0; - print_debug("set registers\n"); - (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); +#elif defined(aarch64) + + primitiveArray[REG_INDEX(R0)] = state.__x[0]; + primitiveArray[REG_INDEX(R1)] = state.__x[1]; + primitiveArray[REG_INDEX(R2)] = state.__x[2]; + primitiveArray[REG_INDEX(R3)] = state.__x[3]; + primitiveArray[REG_INDEX(R4)] = state.__x[4]; + primitiveArray[REG_INDEX(R5)] = state.__x[5]; + primitiveArray[REG_INDEX(R6)] = state.__x[6]; + primitiveArray[REG_INDEX(R7)] = state.__x[7]; + primitiveArray[REG_INDEX(R8)] = state.__x[8]; + primitiveArray[REG_INDEX(R9)] = state.__x[9]; + primitiveArray[REG_INDEX(R10)] = state.__x[10]; + primitiveArray[REG_INDEX(R11)] = state.__x[11]; + primitiveArray[REG_INDEX(R12)] = state.__x[12]; + primitiveArray[REG_INDEX(R13)] = state.__x[13]; + primitiveArray[REG_INDEX(R14)] = state.__x[14]; + primitiveArray[REG_INDEX(R15)] = state.__x[15]; + primitiveArray[REG_INDEX(R16)] = state.__x[16]; + primitiveArray[REG_INDEX(R17)] = state.__x[17]; + primitiveArray[REG_INDEX(R18)] = state.__x[18]; + primitiveArray[REG_INDEX(R19)] = state.__x[19]; + primitiveArray[REG_INDEX(R20)] = state.__x[20]; + primitiveArray[REG_INDEX(R21)] = state.__x[21]; + primitiveArray[REG_INDEX(R22)] = state.__x[22]; + primitiveArray[REG_INDEX(R23)] = state.__x[23]; + primitiveArray[REG_INDEX(R24)] = state.__x[24]; + primitiveArray[REG_INDEX(R25)] = state.__x[25]; + primitiveArray[REG_INDEX(R26)] = state.__x[26]; + primitiveArray[REG_INDEX(R27)] = state.__x[27]; + primitiveArray[REG_INDEX(R28)] = state.__x[28]; + primitiveArray[REG_INDEX(FP)] = state.__fp; + primitiveArray[REG_INDEX(LR)] = state.__lr; + primitiveArray[REG_INDEX(SP)] = state.__sp; + primitiveArray[REG_INDEX(PC)] = state.__pc; #else #error UNSUPPORTED_ARCH -#endif /* amd64 */ +#endif + print_debug("set registers\n"); + + (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); return registerArray; }
diff --git a/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.c b/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.c index a7e4b0b..9c902c6 100644 --- a/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.c +++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,7 +213,7 @@ } lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) { - lib_info* newlib; + lib_info* newlib; print_debug("add_lib_info_fd %s\n", libname); if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) { @@ -258,11 +258,11 @@ } #endif // __APPLE__ - newlib->symtab = build_symtab(newlib->fd); + newlib->symtab = build_symtab(newlib->fd, &newlib->memsz); if (newlib->symtab == NULL) { print_debug("symbol table build failed for %s\n", newlib->name); } else { - print_debug("built symbol table for %s\n", newlib->name); + print_debug("built symbol table for 0x%lx memsz=0x%lx %s\n", newlib, newlib->memsz, newlib->name); } // even if symbol table building fails, we add the lib_info. @@ -305,8 +305,12 @@ const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) { const char* res = NULL; lib_info* lib = ph->libs; + print_debug("symbol_for_pc: addr 0x%lx\n", addr); while (lib) { - if (lib->symtab && addr >= lib->base) { + print_debug("symbol_for_pc: checking lib 0x%lx 0x%lx %s\n", lib->base, lib->memsz, lib->name); + if (lib->symtab && addr >= lib->base && addr < lib->base + lib->memsz) { + print_debug("symbol_for_pc: address=0x%lx offset=0x%lx found inside lib base=0x%lx memsz=0x%lx %s\n", + addr, addr - lib->base, lib->base, lib->memsz, lib->name); res = nearest_symbol(lib->symtab, addr - lib->base, poffset); if (res) return res; }
diff --git a/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.h b/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.h index b5cec4d..96fcf68 100644 --- a/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.h +++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/libproc_impl.h
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -30,17 +31,29 @@ #include "libproc.h" #include "symtab.h" +#define UNSUPPORTED_ARCH "Unsupported architecture!" + +#if defined(__x86_64__) && !defined(amd64) +#define amd64 1 +#endif + +#if defined(__arm64__) && !defined(aarch64) +#define aarch64 1 +#endif + #ifdef __APPLE__ #include <inttypes.h> // for PRIx64, 32, ... #include <pthread.h> #include <mach-o/loader.h> #include <mach-o/nlist.h> #include <mach-o/fat.h> +#include <mach-o/stab.h> #ifndef register_t #define register_t uint64_t #endif +#if defined(amd64) /*** registers copied from bsd/amd64 */ typedef struct reg { register_t r_r15; @@ -71,6 +84,48 @@ register_t r_ss; // not used } reg; +#elif defined(aarch64) +/*** registers copied from bsd/arm64 */ +typedef struct reg { + register_t r_r0; + register_t r_r1; + register_t r_r2; + register_t r_r3; + register_t r_r4; + register_t r_r5; + register_t r_r6; + register_t r_r7; + register_t r_r8; + register_t r_r9; + register_t r_r10; + register_t r_r11; + register_t r_r12; + register_t r_r13; + register_t r_r14; + register_t r_r15; + register_t r_r16; + register_t r_r17; + register_t r_r18; + register_t r_r19; + register_t r_r20; + register_t r_r21; + register_t r_r22; + register_t r_r23; + register_t r_r24; + register_t r_r25; + register_t r_r26; + register_t r_r27; + register_t r_r28; + register_t r_fp; + register_t r_lr; + register_t r_sp; + register_t r_pc; +} reg; + +#else +#error UNSUPPORTED_ARCH +#endif + // convenient defs typedef struct mach_header_64 mach_header_64; typedef struct load_command load_command; @@ -95,6 +150,7 @@ struct symtab* symtab; int fd; // file descriptor for lib struct lib_info* next; + size_t memsz; } lib_info; // list of threads @@ -108,8 +164,8 @@ // list of virtual memory maps typedef struct map_info { int fd; // file descriptor - off_t offset; // file offset of this mapping - uintptr_t vaddr; // starting virtual address + uint64_t offset; // file offset of this mapping + uint64_t vaddr; // starting virtual address size_t memsz; // size of the mapping struct map_info* next; } map_info; @@ -173,8 +229,7 @@ lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base); // adds a new shared object to lib list, supply open lib file descriptor as well -lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, - uintptr_t base); +lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base); sa_thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id); // a test for ELF signature without using libelf
diff --git a/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c b/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c index 682e931..9228522 100644 --- a/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c +++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -32,8 +33,14 @@ #include "cds.h" #ifdef __APPLE__ +#if defined(amd64) #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" +#elif defined(aarch64) +#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h" +#else +#error UNSUPPORTED_ARCH #endif +#endif /* __APPLE__ */ // This file has the libproc implementation to read core files. // For live processes, refer to ps_proc.c. Portions of this is adapted @@ -520,6 +527,8 @@ void print_thread(sa_thread_info *threadinfo) { print_debug("thread added: %d\n", threadinfo->lwp_id); print_debug("registers:\n"); + +#if defined(amd64) print_debug(" r_r15: 0x%" PRIx64 "\n", threadinfo->regs.r_r15); print_debug(" r_r14: 0x%" PRIx64 "\n", threadinfo->regs.r_r14); print_debug(" r_r13: 0x%" PRIx64 "\n", threadinfo->regs.r_r13); @@ -541,6 +550,45 @@ print_debug(" r_cs: 0x%" PRIx64 "\n", threadinfo->regs.r_cs); print_debug(" r_rsp: 0x%" PRIx64 "\n", threadinfo->regs.r_rsp); print_debug(" r_rflags: 0x%" PRIx64 "\n", threadinfo->regs.r_rflags); + +#elif defined(aarch64) + print_debug(" r_r0: 0x%" PRIx64 "\n", threadinfo->regs.r_r0); + print_debug(" r_r1: 0x%" PRIx64 "\n", threadinfo->regs.r_r1); + print_debug(" r_r2: 0x%" PRIx64 "\n", threadinfo->regs.r_r2); + print_debug(" r_r3: 0x%" PRIx64 "\n", threadinfo->regs.r_r3); + print_debug(" r_r4: 0x%" PRIx64 "\n", threadinfo->regs.r_r4); + print_debug(" r_r5: 0x%" PRIx64 "\n", threadinfo->regs.r_r5); + print_debug(" r_r6: 0x%" PRIx64 "\n", threadinfo->regs.r_r6); + print_debug(" r_r7: 0x%" PRIx64 "\n", threadinfo->regs.r_r7); + print_debug(" r_r8: 0x%" PRIx64 "\n", threadinfo->regs.r_r8); + print_debug(" r_r9: 0x%" PRIx64 "\n", threadinfo->regs.r_r9); + print_debug(" r_r10: 0x%" PRIx64 "\n", threadinfo->regs.r_r10); + print_debug(" r_r11: 0x%" PRIx64 "\n", threadinfo->regs.r_r11); + print_debug(" r_r12: 0x%" PRIx64 "\n", threadinfo->regs.r_r12); + print_debug(" r_r13: 0x%" PRIx64 "\n", threadinfo->regs.r_r13); + print_debug(" r_r14: 0x%" PRIx64 "\n", threadinfo->regs.r_r14); + print_debug(" r_r15: 0x%" PRIx64 "\n", threadinfo->regs.r_r15); + print_debug(" r_r16: 0x%" PRIx64 "\n", threadinfo->regs.r_r16); + print_debug(" r_r17: 0x%" PRIx64 "\n", threadinfo->regs.r_r17); + print_debug(" r_r18: 0x%" PRIx64 "\n", threadinfo->regs.r_r18); + print_debug(" r_r19: 0x%" PRIx64 "\n", threadinfo->regs.r_r19); + print_debug(" r_r20: 0x%" PRIx64 "\n", threadinfo->regs.r_r20); + print_debug(" r_r21: 0x%" PRIx64 "\n", threadinfo->regs.r_r21); + print_debug(" r_r22: 0x%" PRIx64 "\n", threadinfo->regs.r_r22); + print_debug(" r_r23: 0x%" PRIx64 "\n", threadinfo->regs.r_r23); + print_debug(" r_r24: 0x%" PRIx64 "\n", threadinfo->regs.r_r24); + print_debug(" r_r25: 0x%" PRIx64 "\n", threadinfo->regs.r_r25); + print_debug(" r_r26: 0x%" PRIx64 "\n", threadinfo->regs.r_r26); + print_debug(" r_r27: 0x%" PRIx64 "\n", threadinfo->regs.r_r27); + print_debug(" r_r28: 0x%" PRIx64 "\n", threadinfo->regs.r_r28); + print_debug(" r_fp: 0x%" PRIx64 "\n", threadinfo->regs.r_fp); + print_debug(" r_lr: 0x%" PRIx64 "\n", threadinfo->regs.r_lr); + print_debug(" r_sp: 0x%" PRIx64 "\n", threadinfo->regs.r_sp); + print_debug(" r_pc: 0x%" PRIx64 "\n", threadinfo->regs.r_pc); + +#else +#error UNSUPPORTED_ARCH +#endif } // read all segments64 commands from core file @@ -567,6 +615,7 @@ goto err; } offset += lcmd.cmdsize; // next command position + //print_debug("LC: 0x%x\n", lcmd.cmd); if (lcmd.cmd == LC_SEGMENT_64) { lseek(fd, -sizeof(load_command), SEEK_CUR); if (read(fd, (void *)&segcmd, sizeof(segment_command_64)) != sizeof(segment_command_64)) { @@ -577,8 +626,9 @@ print_debug("Failed to add map_info at i = %d\n", i); goto err; } - print_debug("segment added: %" PRIu64 " 0x%" PRIx64 " %d\n", - segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize); + print_debug("LC_SEGMENT_64 added: nsects=%d fileoff=0x%llx vmaddr=0x%llx vmsize=0x%llx filesize=0x%llx %s\n", + segcmd.nsects, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize, + segcmd.filesize, &segcmd.segname[0]); } else if (lcmd.cmd == LC_THREAD || lcmd.cmd == LC_UNIXTHREAD) { typedef struct thread_fc { uint32_t flavor; @@ -592,6 +642,7 @@ goto err; } size += sizeof(thread_fc); +#if defined(amd64) if (fc.flavor == x86_THREAD_STATE) { x86_thread_state_t thrstate; if (read(fd, (void *)&thrstate, sizeof(x86_thread_state_t)) != sizeof(x86_thread_state_t)) { @@ -651,6 +702,90 @@ } size += sizeof(x86_exception_state_t); } + +#elif defined(aarch64) + if (fc.flavor == ARM_THREAD_STATE64) { + arm_thread_state64_t thrstate; + if (read(fd, (void *)&thrstate, sizeof(arm_thread_state64_t)) != sizeof(arm_thread_state64_t)) { + printf("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(arm_thread_state64_t); + // create thread info list, update lwp_id later + sa_thread_info* newthr = add_thread_info(ph, (pthread_t) -1, (lwpid_t) num_threads++); + if (newthr == NULL) { + printf("create thread_info failed\n"); + goto err; + } + + // note __DARWIN_UNIX03 depengs on other definitions +#if __DARWIN_UNIX03 +#define get_register_v(regst, regname) \ + regst.__##regname +#else +#define get_register_v(regst, regname) \ + regst.##regname +#endif // __DARWIN_UNIX03 + newthr->regs.r_r0 = get_register_v(thrstate, x[0]); + newthr->regs.r_r1 = get_register_v(thrstate, x[1]); + newthr->regs.r_r2 = get_register_v(thrstate, x[2]); + newthr->regs.r_r3 = get_register_v(thrstate, x[3]); + newthr->regs.r_r4 = get_register_v(thrstate, x[4]); + newthr->regs.r_r5 = get_register_v(thrstate, x[5]); + newthr->regs.r_r6 = get_register_v(thrstate, x[6]); + newthr->regs.r_r7 = get_register_v(thrstate, x[7]); + newthr->regs.r_r8 = get_register_v(thrstate, x[8]); + newthr->regs.r_r9 = get_register_v(thrstate, x[9]); + newthr->regs.r_r10 = get_register_v(thrstate, x[10]); + newthr->regs.r_r11 = get_register_v(thrstate, x[11]); + newthr->regs.r_r12 = get_register_v(thrstate, x[12]); + newthr->regs.r_r13 = get_register_v(thrstate, x[13]); + newthr->regs.r_r14 = get_register_v(thrstate, x[14]); + newthr->regs.r_r15 = get_register_v(thrstate, x[15]); + newthr->regs.r_r16 = get_register_v(thrstate, x[16]); + newthr->regs.r_r17 = get_register_v(thrstate, x[17]); + newthr->regs.r_r18 = get_register_v(thrstate, x[18]); + newthr->regs.r_r19 = get_register_v(thrstate, x[19]); + newthr->regs.r_r20 = get_register_v(thrstate, x[20]); + newthr->regs.r_r21 = get_register_v(thrstate, x[21]); + newthr->regs.r_r22 = get_register_v(thrstate, x[22]); + newthr->regs.r_r23 = get_register_v(thrstate, x[23]); + newthr->regs.r_r24 = get_register_v(thrstate, x[24]); + newthr->regs.r_r25 = get_register_v(thrstate, x[25]); + newthr->regs.r_r26 = get_register_v(thrstate, x[26]); + newthr->regs.r_r27 = get_register_v(thrstate, x[27]); + newthr->regs.r_r28 = get_register_v(thrstate, x[28]); + newthr->regs.r_fp = get_register_v(thrstate, fp); + newthr->regs.r_lr = get_register_v(thrstate, lr); + newthr->regs.r_sp = get_register_v(thrstate, sp); + newthr->regs.r_pc = get_register_v(thrstate, pc); + print_thread(newthr); + } else if (fc.flavor == ARM_NEON_STATE64) { + arm_neon_state64_t flstate; + if (read(fd, (void *)&flstate, sizeof(arm_neon_state64_t)) != sizeof(arm_neon_state64_t)) { + printf("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(arm_neon_state64_t); + } else if (fc.flavor == ARM_EXCEPTION_STATE64) { + arm_exception_state64_t excpstate; + if (read(fd, (void *)&excpstate, sizeof(arm_exception_state64_t)) != sizeof(arm_exception_state64_t)) { + printf("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(arm_exception_state64_t); + } else if (fc.flavor == ARM_DEBUG_STATE64) { + arm_debug_state64_t dbgstate; + if (read(fd, (void *)&dbgstate, sizeof(arm_debug_state64_t)) != sizeof(arm_debug_state64_t)) { + printf("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(arm_debug_state64_t); + } + +#else +#error UNSUPPORTED_ARCH +#endif } } } @@ -765,7 +900,7 @@ // only search core file! continue; } - print_debug("map_info %d: vmaddr = 0x%016" PRIx64 " fileoff = %" PRIu64 " vmsize = %" PRIu64 "\n", + print_debug("map_info %d: vmaddr = 0x%016llx fileoff = 0x%llx vmsize = 0x%lx\n", j, iter->vaddr, iter->offset, iter->memsz); lseek(fd, fpos, SEEK_SET); // we assume .dylib loaded at segment address --- which is true for JVM libraries @@ -789,7 +924,7 @@ continue; } lseek(fd, -sizeof(uint32_t), SEEK_CUR); - // this is the file begining to core file. + // This is the begining of the mach-o file in the segment. if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) { goto err; } @@ -822,18 +957,26 @@ if (name[j] == '\0') break; j++; } - print_debug("%s\n", name); + print_debug("%d %s\n", lcmd.cmd, name); // changed name from @rpath/xxxx.dylib to real path if (strrchr(name, '@')) { get_real_path(ph, name); print_debug("get_real_path returned: %s\n", name); + } else { + break; // Ignore non-relative paths, which are system libs. See JDK-8249779. } add_lib_info(ph, name, iter->vaddr); break; } } // done with the file, advanced to next page to search more files +#if 0 + // This line is disabled due to JDK-8249779. Instead we break out of the loop + // and don't attempt to find any more mach-o files in this segment. fpos = (ltell(fd) + pagesize - 1) / pagesize * pagesize; +#else + break; +#endif } } return true;
diff --git a/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.c b/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.c index 1edc849..52fd791 100644 --- a/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.c +++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.c
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include <unistd.h> #include <search.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> #include <db.h> @@ -57,12 +58,14 @@ void build_search_table(symtab_t *symtab) { int i; + print_debug("build_search_table\n"); for (i = 0; i < symtab->num_symbols; i++) { DBT key, value; key.data = symtab->symbols[i].name; key.size = strlen(key.data) + 1; value.data = &(symtab->symbols[i]); value.size = sizeof(symtab_symbol); + //print_debug("build_search_table: %d 0x%x %s\n", i, symtab->symbols[i].offset, symtab->symbols[i].name); (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0); // check result @@ -90,12 +93,14 @@ } // read symbol table from given fd. -struct symtab* build_symtab(int fd) { +struct symtab* build_symtab(int fd, size_t *p_max_offset) { symtab_t* symtab = NULL; - int i; + int i, j; mach_header_64 header; off_t image_start; + size_t max_offset = 0; + print_debug("build_symtab\n"); if (!get_arch_off(fd, CPU_TYPE_X86_64, &image_start)) { print_debug("failed in get fat header\n"); return NULL; @@ -151,6 +156,7 @@ if (symtab->hash_table == NULL) goto quit; + // allocate the symtab symtab->num_symbols = symtabcmd.nsyms; symtab->symbols = (symtab_symbol *)malloc(sizeof(symtab_symbol) * symtab->num_symbols); symtab->strs = (char *)malloc(sizeof(char) * symtabcmd.strsize); @@ -158,17 +164,8 @@ print_debug("out of memory: allocating symtab.symbol or symtab.strs\n"); goto quit; } - lseek(fd, image_start + symtabcmd.symoff, SEEK_SET); - for (i = 0; i < symtab->num_symbols; i++) { - if (read(fd, (void *)&lentry, sizeof(nlist_64)) != sizeof(nlist_64)) { - print_debug("read nlist_64 failed at %i\n", i); - goto quit; - } - symtab->symbols[i].offset = lentry.n_value; - symtab->symbols[i].size = lentry.n_un.n_strx; // index - } - // string table + // read in the string table lseek(fd, image_start + symtabcmd.stroff, SEEK_SET); int size = read(fd, (void *)(symtab->strs), symtabcmd.strsize * sizeof(char)); if (size != symtabcmd.strsize * sizeof(char)) { @@ -176,25 +173,57 @@ goto quit; } - for (i = 0; i < symtab->num_symbols; i++) { - symtab->symbols[i].name = symtab->strs + symtab->symbols[i].size; - if (i > 0) { - // fix size - symtab->symbols[i - 1].size = symtab->symbols[i].size - symtab->symbols[i - 1].size; - print_debug("%s size = %d\n", symtab->symbols[i - 1].name, symtab->symbols[i - 1].size); - + // read in each nlist_64 from the symbol table and use to fill in symtab->symbols + lseek(fd, image_start + symtabcmd.symoff, SEEK_SET); + i = 0; + for (j = 0; j < symtab->num_symbols; j++) { + if (read(fd, (void *)&lentry, sizeof(nlist_64)) != sizeof(nlist_64)) { + print_debug("read nlist_64 failed at %j\n", j); + goto quit; } - if (i == symtab->num_symbols - 1) { - // last index - symtab->symbols[i].size = - symtabcmd.strsize - symtab->symbols[i].size; - print_debug("%s size = %d\n", symtab->symbols[i].name, symtab->symbols[i].size); + uintptr_t offset = lentry.n_value; // offset of the symbol code/data in the file + uintptr_t stridx = lentry.n_un.n_strx; // offset of symbol string in the symtabcmd.symoff section + + if (stridx == 0 || offset == 0) { + continue; // Skip this entry. It's not a reference to code or data } + if (lentry.n_type == N_OSO) { + // This is an object file name/path. These entries have something other than + // an offset in lentry.n_value, so we need to ignore them. + continue; + } + symtab->symbols[i].offset = offset; + symtab->symbols[i].name = symtab->strs + stridx; + symtab->symbols[i].size = strlen(symtab->symbols[i].name); + + if (symtab->symbols[i].size == 0) { + continue; // Skip this entry. It points to an empty string. + } + + // Track the maximum offset we've seen. This is used to determine the address range + // that the library covers. + if (offset > max_offset) { + max_offset = (offset + 4096) & ~0xfff; // Round up to next page boundary + } + print_debug("symbol read: %d %d n_type=0x%x n_sect=0x%x n_desc=0x%x n_strx=0x%lx offset=0x%lx %s\n", + j, i, lentry.n_type, lentry.n_sect, lentry.n_desc, stridx, offset, symtab->symbols[i].name); + i++; + } + + // Update symtab->num_symbols to be the actual number of symbols we added. Since the symbols + // array was allocated larger, reallocate it to the proper size. + print_debug("build_symtab: included %d of %d entries.\n", i, symtab->num_symbols); + symtab->num_symbols = i; + symtab->symbols = (symtab_symbol *)realloc(symtab->symbols, sizeof(symtab_symbol) * symtab->num_symbols); + if (symtab->symbols == NULL) { + print_debug("out of memory: reallocating symtab.symbol\n"); + goto quit; } // build a hashtable for fast query build_search_table(symtab); + *p_max_offset = max_offset; return symtab; quit: if (symtab) destroy_symtab(symtab); @@ -389,14 +418,37 @@ const char* nearest_symbol(struct symtab* symtab, uintptr_t offset, uintptr_t* poffset) { int n = 0; + char* result = NULL; + ptrdiff_t lowest_offset_from_sym = -1; if (!symtab) return NULL; + // Search the symbol table for the symbol that is closest to the specified offset, but is not under. + // + // Note we can't just use the first symbol that is >= the offset because the symbols may not be + // sorted by offset. + // + // Note this is a rather slow search that is O(n/2), and libjvm has as many as 250k symbols. + // Probably would be good to sort the array and do a binary search, or use a hash table like + // we do for name -> address lookups. However, this functionality is not used often and + // generally just involves one lookup, such as with the clhsdb "findpc" command. for (; n < symtab->num_symbols; n++) { symtab_symbol* sym = &(symtab->symbols[n]); - if (sym->name != NULL && - offset >= sym->offset && offset < sym->offset + sym->size) { - if (poffset) *poffset = (offset - sym->offset); - return sym->name; + if (sym->size != 0 && offset >= sym->offset) { + ptrdiff_t offset_from_sym = offset - sym->offset; + if (offset_from_sym >= 0) { // ignore symbols that come after "offset" + if (lowest_offset_from_sym == -1 || offset_from_sym < lowest_offset_from_sym) { + lowest_offset_from_sym = offset_from_sym; + result = sym->name; + //print_debug("nearest_symbol: found %d %s 0x%x 0x%x 0x%x\n", + // n, sym->name, offset, sym->offset, lowest_offset_from_sym); + } + } } } - return NULL; + print_debug("nearest_symbol: found symbol %d file_offset=0x%lx sym_offset=0x%lx %s\n", + n, offset, lowest_offset_from_sym, result); + // Save the offset from the symbol if requested. + if (result != NULL && poffset) { + *poffset = lowest_offset_from_sym; + } + return result; }
diff --git a/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.h b/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.h index f5f8645..a55fbaa 100644 --- a/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.h +++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.h
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ struct symtab; // build symbol table for a given ELF or MachO file escriptor -struct symtab* build_symtab(int fd); +struct symtab* build_symtab(int fd, size_t *p_max_offset); // destroy the symbol table void destroy_symtab(struct symtab* symtab);
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java index 33f20ea..0f5f011 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java
@@ -1,5 +1,6 @@ /* * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -555,8 +556,10 @@ machDesc = new MachineDescriptionIntelX86(); } else if (cpu.equals("amd64")) { machDesc = new MachineDescriptionAMD64(); + } else if (cpu.equals("aarch64")) { + machDesc = new MachineDescriptionAArch64(); } else { - throw new DebuggerException("Win32 supported under x86 and amd64 only"); + throw new DebuggerException("Win32 supported under x86, amd64 and aarch64 only"); } // Note we do not use a cache for the local debugger in server @@ -650,8 +653,10 @@ if (cpu.equals("amd64") || cpu.equals("x86_64")) { machDesc = new MachineDescriptionAMD64(); + } else if (cpu.equals("aarch64")) { + machDesc = new MachineDescriptionAArch64(); } else { - throw new DebuggerException("Darwin only supported on x86_64. Current arch: " + cpu); + throw new DebuggerException("Darwin only supported on x86_64/aarch64. Current arch: " + cpu); } BsdDebuggerLocal dbg = new BsdDebuggerLocal(machDesc, !isServer);
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ci/ciEnv.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ci/ciEnv.java index ca4b2f5..0e7a45c 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ci/ciEnv.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ci/ciEnv.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,14 +50,12 @@ factoryField = type.getAddressField("_factory"); compilerDataField = type.getAddressField("_compiler_data"); taskField = type.getAddressField("_task"); - systemDictionaryModificationCounterField = new CIntField(type.getCIntegerField("_system_dictionary_modification_counter"), 0); } private static AddressField dependenciesField; private static AddressField factoryField; private static AddressField compilerDataField; private static AddressField taskField; - private static CIntField systemDictionaryModificationCounterField; public ciEnv(Address addr) { super(addr);
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java index ca0b982..00c09c1 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -199,11 +199,14 @@ // changed before derived pointer offset has been collected) OopMapValue omv; { - for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE); !oms.isDone(); oms.next()) { + for (OopMapStream oms = new OopMapStream(map); !oms.isDone(); oms.next()) { + omv = oms.getCurrent(); + if (omv.getType() != OopMapValue.OopTypes.DERIVED_OOP_VALUE) { + continue; + } if (VM.getVM().isClientCompiler()) { Assert.that(false, "should not reach here"); } - omv = oms.getCurrent(); Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap); if (loc != null) { Address baseLoc = fr.oopMapRegToLocation(omv.getContentReg(), regMap); @@ -214,12 +217,8 @@ } // We want narow oop and oop oop_types - OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] { - OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE - }; - { - for (OopMapStream oms = new OopMapStream(map, values); !oms.isDone(); oms.next()) { + for (OopMapStream oms = new OopMapStream(map); !oms.isDone(); oms.next()) { omv = oms.getCurrent(); Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap); if (loc != null) { @@ -276,8 +275,11 @@ } OopMapValue omv = null; - for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); !oms.isDone(); oms.next()) { + for (OopMapStream oms = new OopMapStream(map); !oms.isDone(); oms.next()) { omv = oms.getCurrent(); + if (omv.getType() != OopMapValue.OopTypes.CALLEE_SAVED_VALUE) { + continue; + } if (Assert.ASSERTS_ENABLED) { Assert.that(nofCallee < 2 * REG_COUNT, "overflow"); }
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapStream.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapStream.java index 3dc1556..6b0c236 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapStream.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapStream.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,24 +29,13 @@ public class OopMapStream { private CompressedReadStream stream; private ImmutableOopMap oopMap; - private int mask; private int size; private int position; private OopMapValue omv; private boolean omvValid; public OopMapStream(ImmutableOopMap oopMap) { - this(oopMap, (OopMapValue.OopTypes[]) null); - } - - public OopMapStream(ImmutableOopMap oopMap, OopMapValue.OopTypes type) { - this(oopMap, (OopMapValue.OopTypes[]) null); - mask = type.getValue(); - } - - public OopMapStream(ImmutableOopMap oopMap, OopMapValue.OopTypes[] types) { stream = new CompressedReadStream(oopMap.getData()); - mask = computeMask(types); size = (int) oopMap.getCount(); position = 0; omv = new OopMapValue(); @@ -72,23 +61,11 @@ // Internals only below this point // - private int computeMask(OopMapValue.OopTypes[] types) { - mask = 0; - if (types != null) { - for (int i = 0; i < types.length; i++) { - mask |= types[i].getValue(); - } - } - return mask; - } - private void findNext() { - while (position++ < size) { + if (position++ < size) { omv.readFrom(stream); - if ((omv.getType().getValue() & mask) > 0) { - omvValid = true; - return; - } + omvValid = true; + return; } omvValid = false; }
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java index addcf05..ed0be8e 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java
@@ -1,5 +1,6 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, 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 @@ -30,8 +31,10 @@ import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.debugger.x86.*; import sun.jvm.hotspot.debugger.amd64.*; +import sun.jvm.hotspot.debugger.aarch64.*; import sun.jvm.hotspot.debugger.bsd.x86.*; import sun.jvm.hotspot.debugger.bsd.amd64.*; +import sun.jvm.hotspot.debugger.bsd.aarch64.*; import sun.jvm.hotspot.utilities.*; class BsdCDebugger implements CDebugger { @@ -97,6 +100,13 @@ Address pc = context.getRegisterAsAddress(AMD64ThreadContext.RIP); if (pc == null) return null; return new BsdAMD64CFrame(dbg, rbp, pc); + } else if (cpu.equals("aarch64")) { + AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext(); + Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP); + if (fp == null) return null; + Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC); + if (pc == null) return null; + return new BsdAARCH64CFrame(dbg, fp, pc); } else { throw new DebuggerException(cpu + " is not yet supported"); }
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java index 0624fa9..48126ec 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package sun.jvm.hotspot.debugger.bsd; import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.bsd.aarch64.*; import sun.jvm.hotspot.debugger.bsd.amd64.*; import sun.jvm.hotspot.debugger.bsd.x86.*; @@ -35,6 +36,8 @@ return new BsdX86ThreadContext(dbg); } else if (cpu.equals("amd64") || cpu.equals("x86_64")) { return new BsdAMD64ThreadContext(dbg); + } else if (cpu.equals("aarch64")) { + return new BsdAARCH64ThreadContext(dbg); } else { throw new RuntimeException("cpu " + cpu + " is not yet supported"); }
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java new file mode 100644 index 0000000..845e1b5 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
@@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Red Hat Inc. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.bsd.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.debugger.bsd.*; +import sun.jvm.hotspot.debugger.cdbg.*; +import sun.jvm.hotspot.debugger.cdbg.basic.*; + +final public class BsdAARCH64CFrame extends BasicCFrame { + public BsdAARCH64CFrame(BsdDebugger dbg, Address fp, Address pc) { + super(dbg.getCDebugger()); + this.fp = fp; + this.pc = pc; + this.dbg = dbg; + } + + // override base class impl to avoid ELF parsing + public ClosestSymbol closestSymbolToPC() { + // try native lookup in debugger. + return dbg.lookup(dbg.getAddressValue(pc())); + } + + public Address pc() { + return pc; + } + + public Address localVariableBase() { + return fp; + } + + public CFrame sender(ThreadProxy thread) { + AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext(); + Address rsp = context.getRegisterAsAddress(AARCH64ThreadContext.SP); + + if ((fp == null) || fp.lessThan(rsp)) { + return null; + } + + // Check alignment of fp + if (dbg.getAddressValue(fp) % (2 * ADDRESS_SIZE) != 0) { + return null; + } + + Address nextFP = fp.getAddressAt(0 * ADDRESS_SIZE); + if (nextFP == null || nextFP.lessThanOrEqual(fp)) { + return null; + } + Address nextPC = fp.getAddressAt(1 * ADDRESS_SIZE); + if (nextPC == null) { + return null; + } + return new BsdAARCH64CFrame(dbg, nextFP, nextPC); + } + + // package/class internals only + private static final int ADDRESS_SIZE = 8; + private Address pc; + private Address sp; + private Address fp; + private BsdDebugger dbg; +}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java new file mode 100644 index 0000000..a8c1442 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.bsd.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.debugger.bsd.*; + +public class BsdAARCH64ThreadContext extends AARCH64ThreadContext { + private BsdDebugger debugger; + + public BsdAARCH64ThreadContext(BsdDebugger debugger) { + super(); + this.debugger = debugger; + } + + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFFileParser.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFFileParser.java index b2c5ffa..d34cc7f 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFFileParser.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFFileParser.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,13 +116,13 @@ private int version; // Elf32_Word /** Virtual address to which the system first transfers control. * If there is no entry point for the file the value is 0. */ - private int entry_point; // Elf32_Addr + private long entry_point; // Elf32_Addr /** Program header table offset in bytes. If there is no program * header table the value is 0. */ - private int ph_offset; // Elf32_Off + private long ph_offset; // Elf32_Off /** Section header table offset in bytes. If there is no section * header table the value is 0. */ - private int sh_offset; // Elf32_Off + private long sh_offset; // Elf32_Off /** Processor specific flags. */ private int flags; // Elf32_Word /** ELF header size in bytes. */ @@ -165,9 +165,9 @@ file_type = readShort(); arch = readShort(); version = readInt(); - entry_point = readInt(); - ph_offset = readInt(); - sh_offset = readInt(); + entry_point = readWord(); + ph_offset = readWord(); + sh_offset = readWord(); flags = readInt(); eh_size = readShort(); ph_entry_size = readShort(); @@ -384,23 +384,23 @@ /** Section content and semantics. */ private int type; // Elf32_Word /** Flags. */ - private int flags; // Elf32_Word + private long flags; // Elf32_Word /** If the section will be in the memory image of a process this * will be the address at which the first byte of section will be * loaded. Otherwise, this value is 0. */ - private int address; // Elf32_Addr + private long address; // Elf32_Addr /** Offset from beginning of file to first byte of the section. */ - private int section_offset; // Elf32_Off + private long section_offset; // Elf32_Off /** Size in bytes of the section. TYPE_NOBITS is a special case. */ - private int size; // Elf32_Word + private long size; // Elf32_Word /** Section header table index link. */ private int link; // Elf32_Word /** Extra information determined by the section type. */ private int info; // Elf32_Word /** Address alignment constraints for the section. */ - private int address_alignment; // Elf32_Word + private long address_alignment; // Elf32_Word /** Size of a fixed-size entry, 0 if none. */ - private int entry_size; // Elf32_Word + private long entry_size; // Elf32_Word /** Memoized symbol table. */ private MemoizedObject[] symbols; @@ -416,14 +416,14 @@ seek(offset); name_ndx = readInt(); type = readInt(); - flags = readInt(); - address = readInt(); - section_offset = readInt(); - size = readInt(); + flags = readWord(); + address = readWord(); + section_offset = readWord(); + size = readWord(); link = readInt(); info = readInt(); - address_alignment = readInt(); - entry_size = readInt(); + address_alignment = readWord(); + entry_size = readWord(); switch (type) { case ELFSectionHeader.TYPE_NULL: @@ -433,10 +433,10 @@ case ELFSectionHeader.TYPE_SYMTBL: case ELFSectionHeader.TYPE_DYNSYM: // Setup the symbol table. - int num_entries = size / entry_size; + int num_entries = (int)(size / entry_size); symbols = new MemoizedObject[num_entries]; for (int i = 0; i < num_entries; i++) { - final int symbolOffset = section_offset + + final long symbolOffset = section_offset + (i * entry_size); symbols[i] = new MemoizedObject() { public Object computeValue() { @@ -447,24 +447,26 @@ break; case ELFSectionHeader.TYPE_STRTBL: // Setup the string table. - final int strTableOffset = section_offset; - final int strTableSize = size; + final long strTableOffset = section_offset; + final long strTableSize = size; + assert32bitLong(strTableSize); // must fit in 32-bits stringTable = new MemoizedObject() { public Object computeValue() { return new ELFStringTableImpl(strTableOffset, - strTableSize); + (int)strTableSize); } }; break; case ELFSectionHeader.TYPE_RELO_EXPLICIT: break; case ELFSectionHeader.TYPE_HASH: - final int hashTableOffset = section_offset; - final int hashTableSize = size; + final long hashTableOffset = section_offset; + final long hashTableSize = size; + assert32bitLong(hashTableSize); // must fit in 32-bits hashTable = new MemoizedObject() { public Object computeValue() { return new ELFHashTableImpl(hashTableOffset, - hashTableSize); + (int)hashTableSize); } }; break; @@ -531,7 +533,7 @@ return link; } - public int getOffset() { + public long getOffset() { return section_offset; } } @@ -625,10 +627,10 @@ private int name_ndx; // Elf32_Word /** Value of the associated symbol. This may be an address or * an absolute value. */ - private int value; // Elf32_Addr + private long value; // Elf32_Addr /** Size of the symbol. 0 if the symbol has no size or the size * is unknown. */ - private int size; // Elf32_Word + private long size; // Elf32_Word /** Specifies the symbol type and beinding attributes. */ private byte info; // unsigned char /** Currently holds the value of 0 and has no meaning. */ @@ -646,12 +648,28 @@ ELFSymbolImpl(long offset, int section_type) throws ELFException { seek(offset); this.offset = offset; - name_ndx = readInt(); - value = readInt(); - size = readInt(); - info = readByte(); - other = readByte(); - section_header_ndx = readShort(); + switch (getObjectSize()) { + case CLASS_32: { + name_ndx = readInt(); + value = readInt(); + size = readInt(); + info = readByte(); + other = readByte(); + section_header_ndx = readShort(); + break; + } + case CLASS_64: { + name_ndx = readInt(); + info = readByte(); + other = readByte(); + section_header_ndx = readShort(); + value = readWord(); + size = readWord(); + break; + } + default: + throw new ELFException("Invalid Object Size."); + } this.section_type = section_type; @@ -701,7 +719,7 @@ return value; } - public int getSize() { + public long getSize() { return size; } } @@ -923,6 +941,17 @@ } } + long readWord() throws ELFException { + switch (getObjectSize()) { + case CLASS_32: + return readInt(); + case CLASS_64: + return readLong(); + default: + throw new ELFException("Invalid Object Size."); + } + } + /** Signed byte utility functions used for converting from big-endian * (MSB) to little-endian (LSB). */ short byteSwap(short arg) { @@ -1030,6 +1059,12 @@ return (long)(((long)unsignedByteSwap((short)arg)) << 16) | ((long)unsignedByteSwap((short)(arg >>> 16))); } + + void assert32bitLong(long x) { + if (x != (long)(int)x) { + throw new ELFException("64-bit value does not fit in 32-bits: " + x); + } + } } public static void main(String args[]) {
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSectionHeader.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSectionHeader.java index b055cc1..428456a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSectionHeader.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSectionHeader.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,5 +117,5 @@ /** Returns the name of the section or null if the section has no name. */ public String getName(); /** Returns the offset in bytes to the beginning of the section. */ - public int getOffset(); + public long getOffset(); }
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSymbol.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSymbol.java index 1f93b68..3410dab 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSymbol.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/posix/elf/ELFSymbol.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,5 +73,5 @@ /** Size of the symbol. 0 if the symbol has no size or the size * is unknown. */ - public int getSize(); + public long getSize(); }
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java index 4536f21..84a99ee 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
@@ -28,8 +28,10 @@ import java.net.*; import java.util.*; import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.x86.*; +import sun.jvm.hotspot.debugger.windbg.aarch64.*; import sun.jvm.hotspot.debugger.windbg.amd64.*; import sun.jvm.hotspot.debugger.windbg.x86.*; import sun.jvm.hotspot.debugger.win32.coff.*; @@ -113,6 +115,8 @@ threadFactory = new WindbgX86ThreadFactory(this); } else if (cpu.equals("amd64")) { threadFactory = new WindbgAMD64ThreadFactory(this); + } else if (cpu.equals("aarch64")) { + threadFactory = new WindbgAARCH64ThreadFactory(this); } if (useCache) {
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64Thread.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64Thread.java new file mode 100644 index 0000000..cbc34f4 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64Thread.java
@@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.windbg.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.debugger.windbg.*; + +class WindbgAARCH64Thread implements ThreadProxy { + private WindbgDebugger debugger; + private long sysId; + private boolean gotID; + private long id; + + // The address argument must be the address of the OSThread::_thread_id + WindbgAARCH64Thread(WindbgDebugger debugger, Address addr) { + this.debugger = debugger; + this.sysId = (long)addr.getCIntegerAt(0, 4, true); + gotID = false; + } + + WindbgAARCH64Thread(WindbgDebugger debugger, long sysId) { + this.debugger = debugger; + this.sysId = sysId; + gotID = false; + } + + public ThreadContext getContext() throws IllegalThreadStateException { + long[] data = debugger.getThreadIntegerRegisterSet(getThreadID()); + WindbgAARCH64ThreadContext context = new WindbgAARCH64ThreadContext(debugger); + for (int i = 0; i < data.length; i++) { + context.setRegister(i, data[i]); + } + return context; + } + + public boolean canSetContext() throws DebuggerException { + return false; + } + + public void setContext(ThreadContext thrCtx) + throws IllegalThreadStateException, DebuggerException { + throw new DebuggerException("Unimplemented"); + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof WindbgAARCH64Thread)) { + return false; + } + + return (((WindbgAARCH64Thread) obj).getThreadID() == getThreadID()); + } + + public int hashCode() { + return (int) getThreadID(); + } + + public String toString() { + return Long.toString(getThreadID()); + } + + /** Retrieves the thread ID of this thread by examining the Thread + Information Block. */ + private long getThreadID() { + if (!gotID) { + id = debugger.getThreadIdFromSysId(sysId); + } + + return id; + } +}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadContext.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadContext.java new file mode 100644 index 0000000..8da63ed --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadContext.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.windbg.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.debugger.windbg.*; + +class WindbgAARCH64ThreadContext extends AARCH64ThreadContext { + private WindbgDebugger debugger; + + public WindbgAARCH64ThreadContext(WindbgDebugger debugger) { + super(); + this.debugger = debugger; + } + + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadFactory.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadFactory.java new file mode 100644 index 0000000..6f1e929 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadFactory.java
@@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.windbg.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.windbg.*; + +public class WindbgAARCH64ThreadFactory implements WindbgThreadFactory { + private WindbgDebugger debugger; + + public WindbgAARCH64ThreadFactory(WindbgDebugger debugger) { + this.debugger = debugger; + } + + public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { + return new WindbgAARCH64Thread(debugger, threadIdentifierAddr); + } + + public ThreadProxy createThreadWrapper(long id) { + return new WindbgAARCH64Thread(debugger, id); + } +}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java index 1e47141..1900627 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,11 +28,13 @@ import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.types.*; + import sun.jvm.hotspot.runtime.solaris_sparc.SolarisSPARCJavaThreadPDAccess; import sun.jvm.hotspot.runtime.solaris_x86.SolarisX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.solaris_amd64.SolarisAMD64JavaThreadPDAccess; -import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess; +import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess; +import sun.jvm.hotspot.runtime.win32_aarch64.Win32AARCH64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess; @@ -40,6 +42,7 @@ import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess; import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess; +import sun.jvm.hotspot.runtime.bsd_aarch64.BsdAARCH64JavaThreadPDAccess; import sun.jvm.hotspot.utilities.*; public class Threads { @@ -82,6 +85,8 @@ access = new Win32X86JavaThreadPDAccess(); } else if (cpu.equals("amd64")) { access = new Win32AMD64JavaThreadPDAccess(); + } else if (cpu.equals("aarch64")) { + access = new Win32AARCH64JavaThreadPDAccess(); } } else if (os.equals("linux")) { if (cpu.equals("x86")) { @@ -114,6 +119,8 @@ } else if (os.equals("darwin")) { if (cpu.equals("amd64") || cpu.equals("x86_64")) { access = new BsdAMD64JavaThreadPDAccess(); + } else if (cpu.equals("aarch64")) { + access = new BsdAARCH64JavaThreadPDAccess(); } }
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java new file mode 100644 index 0000000..3cdd4ab --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
@@ -0,0 +1,137 @@ +/* + * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.bsd_aarch64; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.debugger.bsd.BsdDebugger; +import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.runtime.aarch64.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +public class BsdAARCH64JavaThreadPDAccess implements JavaThreadPDAccess { + private static AddressField lastJavaFPField; + private static AddressField osThreadField; + + // Field from OSThread + private static CIntegerField osThreadThreadIDField; + private static CIntegerField osThreadUniqueThreadIDField; + + // This is currently unneeded but is being kept in case we change + // the currentFrameGuess algorithm + private static final long GUESS_SCAN_RANGE = 128 * 1024; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("JavaThread"); + osThreadField = type.getAddressField("_osthread"); + + Type anchorType = db.lookupType("JavaFrameAnchor"); + lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); + + Type osThreadType = db.lookupType("OSThread"); + osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); + osThreadUniqueThreadIDField = osThreadType.getCIntegerField("_unique_thread_id"); + } + + public Address getLastJavaFP(Address addr) { + return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset())); + } + + public Address getLastJavaPC(Address addr) { + return null; + } + + public Address getBaseOfStackPointer(Address addr) { + return null; + } + + public Frame getLastFramePD(JavaThread thread, Address addr) { + Address fp = thread.getLastJavaFP(); + if (fp == null) { + return null; // no information + } + return new AARCH64Frame(thread.getLastJavaSP(), fp); + } + + public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { + return new AARCH64RegisterMap(thread, updateMap); + } + + public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { + ThreadProxy t = getThreadProxy(addr); + AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext(); + AARCH64CurrentFrameGuess guesser = new AARCH64CurrentFrameGuess(context, thread); + if (!guesser.run(GUESS_SCAN_RANGE)) { + return null; + } + if (guesser.getPC() == null) { + return new AARCH64Frame(guesser.getSP(), guesser.getFP()); + } else { + return new AARCH64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); + } + } + + public void printThreadIDOn(Address addr, PrintStream tty) { + tty.print(getThreadProxy(addr)); + } + + public void printInfoOn(Address threadAddr, PrintStream tty) { + tty.print("Thread id: "); + printThreadIDOn(threadAddr, tty); +// tty.println("\nPostJavaState: " + getPostJavaState(threadAddr)); + } + + public Address getLastSP(Address addr) { + ThreadProxy t = getThreadProxy(addr); + AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext(); + return context.getRegisterAsAddress(AARCH64ThreadContext.SP); + } + + public ThreadProxy getThreadProxy(Address addr) { + // Addr is the address of the JavaThread. + // Fetch the OSThread (for now and for simplicity, not making a + // separate "OSThread" class in this package) + Address osThreadAddr = osThreadField.getValue(addr); + // Get the address of the _thread_id from the OSThread + Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); + Address uniqueThreadIdAddr = osThreadAddr.addOffsetTo(osThreadUniqueThreadIDField.getOffset()); + + BsdDebuggerLocal debugger = (BsdDebuggerLocal) VM.getVM().getDebugger(); + return debugger.getThreadForIdentifierAddress(threadIdAddr, uniqueThreadIdAddr); + } +}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java new file mode 100644 index 0000000..55fbc03 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java
@@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.win32_aarch64; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.runtime.aarch64.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +/** This class is only public to allow using the VMObjectFactory to + instantiate these. +*/ + +public class Win32AARCH64JavaThreadPDAccess implements JavaThreadPDAccess { + private static AddressField lastJavaFPField; + private static AddressField osThreadField; + + // Field from OSThread + private static Field osThreadThreadIDField; + + // This is currently unneeded but is being kept in case we change + // the currentFrameGuess algorithm + private static final long GUESS_SCAN_RANGE = 128 * 1024; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("JavaThread"); + osThreadField = type.getAddressField("_osthread"); + + Type anchorType = db.lookupType("JavaFrameAnchor"); + lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); + + Type osThreadType = db.lookupType("OSThread"); + osThreadThreadIDField = osThreadType.getField("_thread_id"); + } + + public Address getLastJavaFP(Address addr) { + return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset())); + } + + public Address getLastJavaPC(Address addr) { + return null; + } + + public Address getBaseOfStackPointer(Address addr) { + return null; + } + + public Frame getLastFramePD(JavaThread thread, Address addr) { + Address fp = thread.getLastJavaFP(); + if (fp == null) { + return null; // no information + } + Address pc = thread.getLastJavaPC(); + if ( pc != null ) { + return new AARCH64Frame(thread.getLastJavaSP(), fp, pc); + } else { + return new AARCH64Frame(thread.getLastJavaSP(), fp); + } + } + + public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { + return new AARCH64RegisterMap(thread, updateMap); + } + + public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { + ThreadProxy t = getThreadProxy(addr); + AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext(); + AARCH64CurrentFrameGuess guesser = new AARCH64CurrentFrameGuess(context, thread); + if (!guesser.run(GUESS_SCAN_RANGE)) { + return null; + } + if (guesser.getPC() == null) { + return new AARCH64Frame(guesser.getSP(), guesser.getFP()); + } else { + return new AARCH64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); + } + } + + public void printThreadIDOn(Address addr, PrintStream tty) { + tty.print(getThreadProxy(addr)); + } + + public void printInfoOn(Address threadAddr, PrintStream tty) { + } + + public Address getLastSP(Address addr) { + ThreadProxy t = getThreadProxy(addr); + AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext(); + return context.getRegisterAsAddress(AARCH64ThreadContext.SP); + } + + public ThreadProxy getThreadProxy(Address addr) { + // Addr is the address of the JavaThread. + // Fetch the OSThread (for now and for simplicity, not making a + // separate "OSThread" class in this package) + Address osThreadAddr = osThreadField.getValue(addr); + // Get the address of the thread_id within the OSThread + Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); + + JVMDebugger debugger = VM.getVM().getDebugger(); + return debugger.getThreadForIdentifierAddress(threadIdAddr); + } +}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java index 796b6f8..1badf15 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
@@ -1183,7 +1183,8 @@ Formatter buf = new Formatter(genHTML); final class OopMapValueIterator { - final Formatter iterate(OopMapStream oms, String type, boolean printContentReg) { + final Formatter iterate(OopMapStream oms, String type, boolean printContentReg, + OopMapValue.OopTypes filter) { Formatter tmpBuf = new Formatter(genHTML); boolean found = false; tmpBuf.beginTag("tr"); @@ -1191,7 +1192,7 @@ tmpBuf.append(type); for (; ! oms.isDone(); oms.next()) { OopMapValue omv = oms.getCurrent(); - if (omv == null) { + if (omv == null || omv.getType() != filter) { continue; } found = true; @@ -1227,17 +1228,21 @@ buf.beginTable(0); OopMapValueIterator omvIterator = new OopMapValueIterator(); - OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE); - buf.append(omvIterator.iterate(oms, "Oops:", false)); + OopMapStream oms = new OopMapStream(map); + buf.append(omvIterator.iterate(oms, "Oops:", false, + OopMapValue.OopTypes.OOP_VALUE)); - oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE); - buf.append(omvIterator.iterate(oms, "NarrowOops:", false)); + oms = new OopMapStream(map); + buf.append(omvIterator.iterate(oms, "NarrowOops:", false, + OopMapValue.OopTypes.NARROWOOP_VALUE)); - oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); - buf.append(omvIterator.iterate(oms, "Callee saved:", true)); + oms = new OopMapStream(map); + buf.append(omvIterator.iterate(oms, "Callee saved:", true, + OopMapValue.OopTypes.CALLEE_SAVED_VALUE)); - oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE); - buf.append(omvIterator.iterate(oms, "Derived oops:", true)); + oms = new OopMapStream(map); + buf.append(omvIterator.iterate(oms, "Derived oops:", true, + OopMapValue.OopTypes.DERIVED_OOP_VALUE)); buf.endTag("table"); return buf.toString();
diff --git a/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp b/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp index 3eecaad..72f3d07 100644 --- a/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp +++ b/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp
@@ -36,6 +36,9 @@ #elif _M_AMD64 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG +#elif _M_ARM64 + #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h" + #define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG #else #error "SA windbg back-end is not supported for your cpu!" #endif
diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java index c875a1a..ac6fb7b 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthInputStream.java
@@ -41,6 +41,9 @@ FixedLengthInputStream (ExchangeImpl t, InputStream src, long len) { super (t, src); + if (len < 0) { + throw new IllegalArgumentException("Content-Length: " + len); + } this.remaining = len; }
diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java index 8b43164..4935214 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/FixedLengthOutputStream.java
@@ -47,6 +47,9 @@ FixedLengthOutputStream (ExchangeImpl t, OutputStream src, long len) { super (src); + if (len < 0) { + throw new IllegalArgumentException("Content-Length: " + len); + } this.t = t; this.remaining = len; }
diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java index e8d719f..03e2a9ee 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -206,7 +206,9 @@ "sun.net.httpserver.maxReqHeaders) exceeded, " + ServerConfig.getMaxReqHeaders() + "."); } - + if (k == null) { // Headers disallows null keys, use empty string + k = ""; // instead to represent invalid key + } hdrs.add (k,v); len = 0; }
diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java index 218776b..dc3a54c 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java
@@ -614,6 +614,11 @@ headerValue = headers.getFirst("Content-Length"); if (headerValue != null) { clen = Long.parseLong(headerValue); + if (clen < 0) { + reject(Code.HTTP_BAD_REQUEST, requestLine, + "Illegal Content-Length value"); + return; + } } if (clen == 0) { requestCompleted(connection); @@ -934,7 +939,7 @@ * Validates a RFC 7230 header-key. */ static boolean isValidHeaderKey(String token) { - if (token == null) return false; + if (token == null || token.isEmpty()) return false; boolean isValidChar; char[] chars = token.toCharArray(); @@ -947,6 +952,6 @@ return false; } } - return !token.isEmpty(); + return true; } }
diff --git a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java index 2af0436..98bbd25 100644 --- a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java +++ b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,6 +111,11 @@ return new URI(uriString); } + if (Character.isDigit(uriString.charAt(0))) { + // may be hostname or hostname:port since it starts with digits + uriString = "//" + uriString; + } + URI u = new URI(uriString); if (u.isAbsolute()) {
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java index 98a18cb..51f449f 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java
@@ -137,4 +137,9 @@ public int compareTo(Candidate o) { return value.compareTo(o.value); } + + @Override + public String toString() { + return "Candidate{" + value + "}"; + } }
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java new file mode 100644 index 0000000..3cfd73f --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java
@@ -0,0 +1,48 @@ +/* + * Copyright (c) 2002-2020, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.reader; + +import java.util.List; +import java.util.Map; + +public interface CompletionMatcher { + + /** + * Compiles completion matcher functions + * + * @param options LineReader options + * @param prefix invoked by complete-prefix or expand-or-complete-prefix widget + * @param line The parsed line within which completion has been requested + * @param caseInsensitive if completion is case insensitive or not + * @param errors number of errors accepted in matching + * @param originalGroupName value of JLineReader variable original-group-name + */ + void compile(Map<LineReader.Option, Boolean> options, boolean prefix, CompletingParsedLine line + , boolean caseInsensitive, int errors, String originalGroupName); + + /** + * + * @param candidates list of candidates + * @return a map of candidates that completion matcher matches + */ + List<Candidate> matches(List<Candidate> candidates); + + /** + * + * @return a candidate that have exact match, null if no exact match found + */ + Candidate exactMatch(); + + /** + * + * @return a common prefix of matched candidates + */ + String getCommonPrefix(); + +}
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ConfigurationPath.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ConfigurationPath.java deleted file mode 100644 index a8663e8..0000000 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ConfigurationPath.java +++ /dev/null
@@ -1,75 +0,0 @@ -/* - * Copyright (c) 2002-2019, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.reader; - -import java.io.IOException; -import java.nio.file.Path; - -public class ConfigurationPath { - private Path appConfig; - private Path userConfig; - - /** - * Configuration class constructor. - * @param appConfig Application configuration directory - * @param userConfig User private configuration directory - */ - public ConfigurationPath(Path appConfig, Path userConfig) { - this.appConfig = appConfig; - this.userConfig = userConfig; - } - - /** - * Search configuration file first from userConfig and then appConfig directory. Returns null if file is not found. - * @param name Configuration file name. - * @return Configuration file. - * - */ - public Path getConfig(String name) { - Path out = null; - if (userConfig != null && userConfig.resolve(name).toFile().exists()) { - out = userConfig.resolve(name); - } else if (appConfig != null && appConfig.resolve(name).toFile().exists()) { - out = appConfig.resolve(name); - } - return out; - } - - /** - * Search configuration file from userConfig directory. Returns null if file is not found. - * @param name Configuration file name. - * @return Configuration file. - * @throws IOException When we do not have read access to the file or directory. - * - */ - public Path getUserConfig(String name) throws IOException { - return getUserConfig(name, false); - } - - /** - * Search configuration file from userConfig directory. Returns null if file is not found. - * @param name Configuration file name - * @param create When true configuration file is created if not found. - * @return Configuration file. - * @throws IOException When we do not have read/write access to the file or directory. - */ - public Path getUserConfig(String name, boolean create) throws IOException { - Path out = null; - if (userConfig != null) { - if (!userConfig.resolve(name).toFile().exists() && create) { - userConfig.resolve(name).toFile().createNewFile(); - } - if (userConfig.resolve(name).toFile().exists()) { - out = userConfig.resolve(name); - } - } - return out; - } - -}
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java index 9f39b9e..9f70420 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2020, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -15,6 +15,7 @@ public class EndOfFileException extends RuntimeException { private static final long serialVersionUID = 528485360925144689L; + private String partialLine; public EndOfFileException() { } @@ -34,4 +35,13 @@ public EndOfFileException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } + + public EndOfFileException partialLine(String partialLine) { + this.partialLine = partialLine; + return this; + } + + public String getPartialLine() { + return partialLine; + } }
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java index 4effefb..07b7266 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -294,7 +294,13 @@ String COMMENT_BEGIN = "comment-begin"; String BELL_STYLE = "bell-style"; String PREFER_VISIBLE_BELL = "prefer-visible-bell"; + /** tab completion: if candidates are more than list-max a question will be asked before displaying them */ String LIST_MAX = "list-max"; + /** + * tab completion: if candidates are less than menu-list-max + * they are displayed in a list below the field to be completed + */ + String MENU_LIST_MAX = "menu-list-max"; String DISABLE_HISTORY = "disable-history"; String DISABLE_COMPLETION = "disable-completion"; String EDITING_MODE = "editing-mode"; @@ -303,6 +309,7 @@ String WORDCHARS = "WORDCHARS"; String REMOVE_SUFFIX_CHARS = "REMOVE_SUFFIX_CHARS"; String SEARCH_TERMINATORS = "search-terminators"; + /** Number of matching errors that are accepted by the completion matcher */ String ERRORS = "errors"; /** Property for the "others" group name */ String OTHERS_GROUP_NAME = "OTHERS_GROUP_NAME"; @@ -310,12 +317,19 @@ String ORIGINAL_GROUP_NAME = "ORIGINAL_GROUP_NAME"; /** Completion style for displaying groups name */ String COMPLETION_STYLE_GROUP = "COMPLETION_STYLE_GROUP"; + String COMPLETION_STYLE_LIST_GROUP = "COMPLETION_STYLE_LIST_GROUP"; /** Completion style for displaying the current selected item */ String COMPLETION_STYLE_SELECTION = "COMPLETION_STYLE_SELECTION"; + String COMPLETION_STYLE_LIST_SELECTION = "COMPLETION_STYLE_LIST_SELECTION"; /** Completion style for displaying the candidate description */ String COMPLETION_STYLE_DESCRIPTION = "COMPLETION_STYLE_DESCRIPTION"; + String COMPLETION_STYLE_LIST_DESCRIPTION = "COMPLETION_STYLE_LIST_DESCRIPTION"; /** Completion style for displaying the matching part of candidates */ String COMPLETION_STYLE_STARTING = "COMPLETION_STYLE_STARTING"; + String COMPLETION_STYLE_LIST_STARTING = "COMPLETION_STYLE_LIST_STARTING"; + /** Completion style for displaying the list */ + String COMPLETION_STYLE_BACKGROUND = "COMPLETION_STYLE_BACKGROUND"; + String COMPLETION_STYLE_LIST_BACKGROUND = "COMPLETION_STYLE_LIST_BACKGROUND"; /** * Set the template for prompts for secondary (continuation) lines. * This is a prompt template as described in the class header. @@ -370,10 +384,20 @@ */ String FEATURES_MAX_BUFFER_SIZE = "features-max-buffer-size"; + /** + * Min buffer size for tab auto-suggestions. + * For shorter buffer sizes auto-suggestions are not resolved. + */ + String SUGGESTIONS_MIN_BUFFER_SIZE = "suggestions-min-buffer-size"; + Map<String, KeyMap<Binding>> defaultKeyMaps(); enum Option { COMPLETE_IN_WORD, + /** use camel case completion matcher */ + COMPLETE_MATCHER_CAMELCASE, + /** use type completion matcher */ + COMPLETE_MATCHER_TYPO(true), DISABLE_EVENT_EXPANSION, HISTORY_VERIFY, HISTORY_IGNORE_SPACE(true), @@ -386,9 +410,13 @@ AUTO_GROUP(true), AUTO_MENU(true), AUTO_LIST(true), + /** list candidates below the field to be completed */ + AUTO_MENU_LIST, RECOGNIZE_EXACT, /** display group name before each group (else display all group names first) */ GROUP(true), + /** when double tab to select candidate keep candidates grouped (else loose grouping) */ + GROUP_PERSIST, /** if completion is case insensitive or not */ CASE_INSENSITIVE, LIST_AMBIGUOUS, @@ -414,7 +442,8 @@ DELAY_LINE_WRAP, AUTO_PARAM_SLASH(true), AUTO_REMOVE_SLASH(true), - USE_FORWARD_SLASH(false), + /** FileNameCompleter: Use '/' character as a file directory separator */ + USE_FORWARD_SLASH, /** When hitting the <code><tab></code> key at the beginning of the line, insert a tabulation * instead of completing. This is mainly useful when {@link #BRACKETED_PASTE} is * disabled, so that copy/paste of indented text does not trigger completion. @@ -450,6 +479,11 @@ this.def = def; } + public final boolean isSet(Map<Option, Boolean> options) { + Boolean b = options.get(this); + return b != null ? b : this.isDef(); + } + public boolean isDef() { return def; } @@ -489,8 +523,9 @@ * Equivalent to <code>readLine(null, null, null)</code>. * * @return the line read - * @throws UserInterruptException If the call was interrupted by the user. - * @throws EndOfFileException If the end of the input stream was reached. + * @throws UserInterruptException if readLine was interrupted (using Ctrl-C for example) + * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) + * @throws java.io.IOError in case of other i/o errors */ String readLine() throws UserInterruptException, EndOfFileException; @@ -502,8 +537,9 @@ * * @param mask The mask character, <code>null</code> or <code>0</code>. * @return A line that is read from the terminal, can never be null. - * @throws UserInterruptException If the call was interrupted by the user. - * @throws EndOfFileException If the end of the input stream was reached. + * @throws UserInterruptException if readLine was interrupted (using Ctrl-C for example) + * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) + * @throws java.io.IOError in case of other i/o errors */ String readLine(Character mask) throws UserInterruptException, EndOfFileException; @@ -515,8 +551,9 @@ * * @param prompt The prompt to issue to the terminal, may be null. * @return A line that is read from the terminal, can never be null. - * @throws UserInterruptException If the call was interrupted by the user. - * @throws EndOfFileException If the end of the input stream was reached. + * @throws UserInterruptException if readLine was interrupted (using Ctrl-C for example) + * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) + * @throws java.io.IOError in case of other i/o errors */ String readLine(String prompt) throws UserInterruptException, EndOfFileException; @@ -529,8 +566,9 @@ * @param prompt The prompt to issue to the terminal, may be null. * @param mask The mask character, <code>null</code> or <code>0</code>. * @return A line that is read from the terminal, can never be null. - * @throws UserInterruptException If the call was interrupted by the user. - * @throws EndOfFileException If the end of the input stream was reached. + * @throws UserInterruptException if readLine was interrupted (using Ctrl-C for example) + * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) + * @throws java.io.IOError in case of other i/o errors */ String readLine(String prompt, Character mask) throws UserInterruptException, EndOfFileException; @@ -546,8 +584,9 @@ * @param mask The character mask, may be null. * @param buffer The default value presented to the user to edit, may be null. * @return A line that is read from the terminal, can never be null. - * @throws UserInterruptException If the call was interrupted by the user. - * @throws EndOfFileException If the end of the input stream was reached. + * @throws UserInterruptException if readLine was interrupted (using Ctrl-C for example) + * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) + * @throws java.io.IOError in case of other i/o errors */ String readLine(String prompt, Character mask, String buffer) throws UserInterruptException, EndOfFileException; @@ -568,8 +607,6 @@ * @throws UserInterruptException if readLine was interrupted (using Ctrl-C for example) * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) * @throws java.io.IOError in case of other i/o errors - * @throws UserInterruptException If the call was interrupted by the user. - * @throws EndOfFileException If the end of the input stream was reached. */ String readLine(String prompt, String rightPrompt, Character mask, String buffer) throws UserInterruptException, EndOfFileException; @@ -590,8 +627,6 @@ * @throws UserInterruptException if readLine was interrupted (using Ctrl-C for example) * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) * @throws java.io.IOError in case of other i/o errors - * @throws UserInterruptException If the call was interrupted by the user. - * @throws EndOfFileException If the end of the input stream was reached. */ String readLine(String prompt, String rightPrompt, MaskingCallback maskingCallback, String buffer) throws UserInterruptException, EndOfFileException;
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java index 20a3f64..422561a 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2020, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -36,6 +36,7 @@ Highlighter highlighter; Parser parser; Expander expander; + CompletionMatcher completionMatcher; private LineReaderBuilder() { } @@ -103,6 +104,11 @@ return this; } + public LineReaderBuilder completionMatcher(CompletionMatcher completionMatcher) { + this.completionMatcher = completionMatcher; + return this; + } + public LineReader build() { Terminal terminal = this.terminal; if (terminal == null) { @@ -133,6 +139,9 @@ if (expander != null) { reader.setExpander(expander); } + if (completionMatcher != null) { + reader.setCompletionMatcher(completionMatcher); + } for (Map.Entry<LineReader.Option, Boolean> e : options.entrySet()) { reader.option(e.getKey(), e.getValue()); }
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java index 1f6a4c6..2e2ad8c 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java
@@ -35,16 +35,12 @@ default String getCommand(final String line) { String out = ""; - Pattern patternCommand = Pattern.compile("^\\s*" + REGEX_VARIABLE + "=(" + REGEX_COMMAND + ")(\\s+.*|$)"); + Pattern patternCommand = Pattern.compile("^\\s*" + REGEX_VARIABLE + "=(" + REGEX_COMMAND + ")(\\s+|$)"); Matcher matcher = patternCommand.matcher(line); if (matcher.find()) { out = matcher.group(1); } else { out = line.trim().split("\\s+")[0]; - int idx = out.indexOf("="); - if (idx > -1) { - out = out.substring(idx + 1); - } if (!out.matches(REGEX_COMMAND)) { out = ""; }
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/PrintAboveWriter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/PrintAboveWriter.java new file mode 100644 index 0000000..63c9dec --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/PrintAboveWriter.java
@@ -0,0 +1,42 @@ +/* + * Copyright (c) 2002-2021, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.reader; + +import java.io.StringWriter; +import java.io.Writer; + +/** + * Redirects a {@link Writer} to a {@link LineReader}'s {@link LineReader#printAbove(String)} method, + * which draws output above the current prompt / input line. + * + * <p>Example:</p> + * <pre> + * LineReader reader = LineReaderBuilder.builder().terminal(terminal).parser(parser).build(); + * PrintAboveWriter printAbove = new PrintAboveWriter(reader); + * printAbove.write(new char[] { 'h', 'i', '!', '\n'}); + * </pre> + * + */ +public class PrintAboveWriter extends StringWriter { + private final LineReader reader; + + public PrintAboveWriter(LineReader reader) { + this.reader = reader; + } + + @Override + public void flush() { + StringBuffer buffer = getBuffer(); + int lastNewline = buffer.lastIndexOf("\n"); + if (lastNewline >= 0) { + reader.printAbove(buffer.substring(0, lastNewline + 1)); + buffer.delete(0, lastNewline + 1); + } + } +}
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ScriptEngine.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ScriptEngine.java deleted file mode 100644 index ab4f24e..0000000 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ScriptEngine.java +++ /dev/null
@@ -1,153 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.reader; - -import java.io.File; -import java.nio.file.Path; -import java.util.*; - -/** - * Manage scriptEngine variables, statements and script execution. - * - * @author <a href="mailto:matti.rintanikkola@gmail.com">Matti Rinta-Nikkola</a> - */ -public interface ScriptEngine { - - /** - * - * @return scriptEngine name - */ - String getEngineName(); - - /** - * - * @return script file name extensions - */ - Collection<String> getExtensions(); - - /** - * Tests if console variable exists - * @param name - * @return true if variable exists - */ - boolean hasVariable(String name); - - /** - * Creates variable - * @param name of the variable - * @param value of the variable - */ - void put(String name, Object value); - - /** - * Gets variable value - * @param name of the variable - * @return value of the variable - */ - Object get(String name); - - /** - * Gets all variables with values - * @return map of the variables - */ - default Map<String,Object> find() { - return find(null); - } - - /** - * Gets all the variables that match the name. Name can contain * wild cards. - * @param name of the variable - * @return map of the variables - */ - Map<String,Object> find(String name); - - /** - * Deletes variables. Variable name cab contain * wild cards. - * @param vars - */ - void del(String... vars); - - /** - * Converts object to JSON string. - * @param object object to convert to JSON - * @return formatted JSON string - */ - String toJson(Object object); - - /** - * Converts object to string. - * @param object object to convert to string - * @return object string value - */ - String toString(Object object); - - /** - * Substitute variable reference with its value. - * @param variable - * @return Substituted variable - * @throws Exception - */ - default Object expandParameter(String variable) { - return expandParameter(variable, ""); - } - - /** - * Substitute variable reference with its value. - * @param variable - * @param format serialization format - * @return Substituted variable - * @throws Exception - */ - Object expandParameter(String variable, String format); - - /** - * Persists object value to file. - * @param file - * @param object - */ - default void persist(Path file, Object object) { - persist(file, object, "JSON"); - } - - /** - * Persists object value to file. - * @param file - * @param object - * @param format - */ - void persist(Path file, Object object, String format); - - /** - * Executes scriptEngine statement - * @param statement - * @return result - * @throws Exception - */ - Object execute(String statement) throws Exception; - - /** - * Executes scriptEngine script - * @param script - * @return result - * @throws Exception - */ - default Object execute(File script) throws Exception { - return execute(script, null); - } - - /** - * Executes scriptEngine script - * @param script - * @param args - * @return - * @throws Exception - */ - Object execute(File script, Object[] args) throws Exception; - -}
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java new file mode 100644 index 0000000..0d4ead5 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java
@@ -0,0 +1,210 @@ +/* + * Copyright (c) 2002-2021, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.reader.impl; + +import jdk.internal.org.jline.reader.Candidate; +import jdk.internal.org.jline.reader.CompletingParsedLine; +import jdk.internal.org.jline.reader.CompletionMatcher; +import jdk.internal.org.jline.reader.LineReader; +import jdk.internal.org.jline.utils.AttributedString; + +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class CompletionMatcherImpl implements CompletionMatcher { + protected Predicate<String> exact; + protected List<Function<Map<String, List<Candidate>>, Map<String, List<Candidate>>>> matchers; + private Map<String, List<Candidate>> matching; + private boolean caseInsensitive; + + public CompletionMatcherImpl() { + } + + protected void reset(boolean caseInsensitive) { + this.caseInsensitive = caseInsensitive; + exact = s -> false; + matchers = new ArrayList<>(); + matching = null; + } + + @Override + public void compile(Map<LineReader.Option, Boolean> options, boolean prefix, CompletingParsedLine line + , boolean caseInsensitive, int errors, String originalGroupName) { + reset(caseInsensitive); + defaultMatchers(options, prefix, line, caseInsensitive, errors, originalGroupName); + } + + @Override + public List<Candidate> matches(List<Candidate> candidates) { + matching = Collections.emptyMap(); + Map<String, List<Candidate>> sortedCandidates = sort(candidates); + for (Function<Map<String, List<Candidate>>, + Map<String, List<Candidate>>> matcher : matchers) { + matching = matcher.apply(sortedCandidates); + if (!matching.isEmpty()) { + break; + } + } + return !matching.isEmpty() ? matching.entrySet().stream().flatMap(e -> e.getValue().stream()).collect(Collectors.toList()) + : new ArrayList<>(); + } + + @Override + public Candidate exactMatch() { + if (matching == null) { + throw new IllegalStateException(); + } + return matching.values().stream().flatMap(Collection::stream) + .filter(Candidate::complete) + .filter(c -> exact.test(c.value())) + .findFirst().orElse(null); + } + + @Override + public String getCommonPrefix() { + if (matching == null) { + throw new IllegalStateException(); + } + String commonPrefix = null; + for (String key : matching.keySet()) { + commonPrefix = commonPrefix == null ? key : getCommonStart(commonPrefix, key, caseInsensitive); + } + return commonPrefix; + } + + /** + * Default JLine matchers + */ + protected void defaultMatchers(Map<LineReader.Option, Boolean> options, boolean prefix, CompletingParsedLine line + , boolean caseInsensitive, int errors, String originalGroupName) { + // Find matchers + // TODO: glob completion + String wd = line.word(); + String wdi = caseInsensitive ? wd.toLowerCase() : wd; + String wp = wdi.substring(0, line.wordCursor()); + if (prefix) { + matchers = new ArrayList<>(Arrays.asList( + simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).startsWith(wp)), + simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wp)) + )); + if (LineReader.Option.COMPLETE_MATCHER_TYPO.isSet(options)) { + matchers.add(typoMatcher(wp, errors, caseInsensitive, originalGroupName)); + } + exact = s -> caseInsensitive ? s.equalsIgnoreCase(wp) : s.equals(wp); + } else if (!LineReader.Option.EMPTY_WORD_OPTIONS.isSet(options) && wd.length() == 0) { + matchers = new ArrayList<>(Collections.singletonList(simpleMatcher(s -> !s.startsWith("-")))); + exact = s -> caseInsensitive ? s.equalsIgnoreCase(wd) : s.equals(wd); + } else { + if (LineReader.Option.COMPLETE_IN_WORD.isSet(options)) { + String ws = wdi.substring(line.wordCursor()); + Pattern p1 = Pattern.compile(Pattern.quote(wp) + ".*" + Pattern.quote(ws) + ".*"); + Pattern p2 = Pattern.compile(".*" + Pattern.quote(wp) + ".*" + Pattern.quote(ws) + ".*"); + matchers = new ArrayList<>(Arrays.asList( + simpleMatcher(s -> p1.matcher(caseInsensitive ? s.toLowerCase() : s).matches()), + simpleMatcher(s -> p2.matcher(caseInsensitive ? s.toLowerCase() : s).matches()) + )); + } else { + matchers = new ArrayList<>(Arrays.asList( + simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).startsWith(wdi)), + simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wdi)) + )); + } + if (LineReader.Option.COMPLETE_MATCHER_CAMELCASE.isSet(options)) { + matchers.add(simpleMatcher(s -> camelMatch(wd, 0, s, 0))); + } + if (LineReader.Option.COMPLETE_MATCHER_TYPO.isSet(options)) { + matchers.add(typoMatcher(wdi, errors, caseInsensitive, originalGroupName)); + } + exact = s -> caseInsensitive ? s.equalsIgnoreCase(wd) : s.equals(wd); + } + } + + protected Function<Map<String, List<Candidate>>, + Map<String, List<Candidate>>> simpleMatcher(Predicate<String> predicate) { + return m -> m.entrySet().stream() + .filter(e -> predicate.test(e.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + protected Function<Map<String, List<Candidate>>, + Map<String, List<Candidate>>> typoMatcher(String word, int errors, boolean caseInsensitive, String originalGroupName) { + return m -> { + Map<String, List<Candidate>> map = m.entrySet().stream() + .filter(e -> ReaderUtils.distance(word, caseInsensitive ? e.getKey().toLowerCase() : e.getKey()) < errors) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + if (map.size() > 1) { + map.computeIfAbsent(word, w -> new ArrayList<>()) + .add(new Candidate(word, word, originalGroupName, null, null, null, false)); + } + return map; + }; + } + + protected boolean camelMatch(String word, int i, String candidate, int j) { + if (word.length() <= i) { + return true; + } else if (candidate.length() <= j) { + return false; + } else { + char c = word.charAt(i); + if (c == candidate.charAt(j)) { + return camelMatch(word, i + 1, candidate, j + 1); + } else { + for (int j1 = j; j1 < candidate.length(); j1++) { + if (Character.isUpperCase(candidate.charAt(j1))) { + if (Character.toUpperCase(c) == candidate.charAt(j1)) { + if (camelMatch(word, i + 1, candidate, j1 + 1)) { + return true; + } + } + } + } + return false; + } + } + } + + private Map<String, List<Candidate>> sort(List<Candidate> candidates) { + // Build a list of sorted candidates + Map<String, List<Candidate>> sortedCandidates = new HashMap<>(); + for (Candidate candidate : candidates) { + sortedCandidates + .computeIfAbsent(AttributedString.fromAnsi(candidate.value()).toString(), s -> new ArrayList<>()) + .add(candidate); + } + return sortedCandidates; + } + + private String getCommonStart(String str1, String str2, boolean caseInsensitive) { + int[] s1 = str1.codePoints().toArray(); + int[] s2 = str2.codePoints().toArray(); + int len = 0; + while (len < Math.min(s1.length, s2.length)) { + int ch1 = s1[len]; + int ch2 = s2[len]; + if (ch1 != ch2 && caseInsensitive) { + ch1 = Character.toUpperCase(ch1); + ch2 = Character.toUpperCase(ch2); + if (ch1 != ch2) { + ch1 = Character.toLowerCase(ch1); + ch2 = Character.toLowerCase(ch2); + } + } + if (ch1 != ch2) { + break; + } + len++; + } + return new String(s1, 0, len); + } + +} \ No newline at end of file
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java index 6dfff63..ac286ad 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -19,8 +19,8 @@ import jdk.internal.org.jline.utils.WCWidth; public class DefaultHighlighter implements Highlighter { - private Pattern errorPattern; - private int errorIndex = -1; + protected Pattern errorPattern; + protected int errorIndex = -1; @Override public void setErrorPattern(Pattern errorPattern) {
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java index a7334cc..4fb616f 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java
@@ -24,7 +24,7 @@ ROUND, // () CURLY, // {} SQUARE, // [] - ANGLE; // <> + ANGLE // <> } private char[] quoteChars = {'\'', '"'}; @@ -39,8 +39,8 @@ private char[] closingBrackets = null; - private String regexVariable = "[a-zA-Z_]{1,}[a-zA-Z0-9_-]*((.|\\['|\\[\\\"|\\[)[a-zA-Z0-9_-]*(|'\\]|\\\"\\]|\\])){0,1}"; - private String regexCommand = "[:]{0,1}[a-zA-Z]{1,}[a-zA-Z0-9_-]*"; + private String regexVariable = "[a-zA-Z_]+[a-zA-Z0-9_-]*((\\.|\\['|\\[\"|\\[)[a-zA-Z0-9_-]*(|']|\"]|]))?"; + private String regexCommand = "[:]?[a-zA-Z]+[a-zA-Z0-9_-]*"; private int commandGroup = 4; // @@ -175,23 +175,25 @@ @Override public boolean validVariableName(String name) { - return name != null && name.matches(regexVariable); + return name != null && regexVariable != null && name.matches(regexVariable); } @Override public String getCommand(final String line) { String out = ""; - Pattern patternCommand = Pattern.compile("^\\s*" + regexVariable + "=(" + regexCommand + ")(\\s+.*|$)"); - Matcher matcher = patternCommand.matcher(line); - if (matcher.find()) { - out = matcher.group(commandGroup); - } else { - out = line.trim().split("\\s+")[0]; - int idx = out.indexOf("="); - if (idx > -1) { - out = out.substring(idx + 1); + boolean checkCommandOnly = regexVariable == null; + if (!checkCommandOnly) { + Pattern patternCommand = Pattern.compile("^\\s*" + regexVariable + "=(" + regexCommand + ")(\\s+|$)"); + Matcher matcher = patternCommand.matcher(line); + if (matcher.find()) { + out = matcher.group(commandGroup); + } else { + checkCommandOnly = true; } + } + if (checkCommandOnly) { + out = line.trim().split("\\s+")[0]; if (!out.matches(regexCommand)) { out = ""; } @@ -202,10 +204,12 @@ @Override public String getVariable(final String line) { String out = null; - Pattern patternCommand = Pattern.compile("^\\s*(" + regexVariable + ")\\s*=[^=~].*"); - Matcher matcher = patternCommand.matcher(line); - if (matcher.find()) { - out = matcher.group(1); + if (regexVariable != null) { + Pattern patternCommand = Pattern.compile("^\\s*(" + regexVariable + ")\\s*=[^=~].*"); + Matcher matcher = patternCommand.matcher(line); + if (matcher.find()) { + out = matcher.group(1); + } } return out; } @@ -289,7 +293,7 @@ rawWordLength = rawWordCursor; } - if (context != ParseContext.COMPLETE) { + if (context != ParseContext.COMPLETE && context != ParseContext.SPLIT_LINE) { if (eofOnEscapedNewLine && isEscapeChar(line, line.length() - 1)) { throw new EOFError(-1, -1, "Escaped new line", "newline"); } @@ -609,25 +613,28 @@ } } if (escapeChars != null) { - // Completion is protected by an opening quote: - // Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does. - // Also, close the quote at the end - if (openingQuote != null) { - needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote); - } - // Completion is protected by middle quotes: - // Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does. - else if (middleQuotes) { - needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)); - } - // No quote protection, need to escape everything: delimiter chars (spaces), quote chars - // and escapes themselves - else { - needToBeEscaped = i -> isDelimiterChar(sb, i) || isRawEscapeChar(sb.charAt(i)) || isRawQuoteChar(sb.charAt(i)); - } - for (int i = 0; i < sb.length(); i++) { - if (needToBeEscaped.test(i)) { - sb.insert(i++, escapeChars[0]); + if (escapeChars.length > 0) { + // Completion is protected by an opening quote: + // Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does. + // Also, close the quote at the end + if (openingQuote != null) { + needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote); + } + // Completion is protected by middle quotes: + // Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does. + else if (middleQuotes) { + needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)); + } + // No quote protection, need to escape everything: delimiter chars (spaces), quote chars + // and escapes themselves + else { + needToBeEscaped = i -> isDelimiterChar(sb, i) || isRawEscapeChar(sb.charAt(i)) + || isRawQuoteChar(sb.charAt(i)); + } + for (int i = 0; i < sb.length(); i++) { + if (needToBeEscaped.test(i)) { + sb.insert(i++, escapeChars[0]); + } } } } else if (openingQuote == null && !middleQuotes) {
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java index e5e8efc..b32dde1 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java
@@ -20,7 +20,6 @@ import java.lang.reflect.Constructor; import java.time.Instant; import java.util.*; -import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantLock; import java.util.function.*; @@ -46,9 +45,9 @@ import jdk.internal.org.jline.utils.Curses; import jdk.internal.org.jline.utils.Display; import jdk.internal.org.jline.utils.InfoCmp.Capability; -import jdk.internal.org.jline.utils.Levenshtein; import jdk.internal.org.jline.utils.Log; import jdk.internal.org.jline.utils.Status; +import jdk.internal.org.jline.utils.StyleResolver; import jdk.internal.org.jline.utils.WCWidth; import static jdk.internal.org.jline.keymap.KeyMap.alt; @@ -80,18 +79,26 @@ public static final String DEFAULT_SEARCH_TERMINATORS = "\033\012"; public static final String DEFAULT_BELL_STYLE = ""; public static final int DEFAULT_LIST_MAX = 100; + public static final int DEFAULT_MENU_LIST_MAX = Integer.MAX_VALUE; public static final int DEFAULT_ERRORS = 2; public static final long DEFAULT_BLINK_MATCHING_PAREN = 500L; public static final long DEFAULT_AMBIGUOUS_BINDING = 1000L; public static final String DEFAULT_SECONDARY_PROMPT_PATTERN = "%M> "; public static final String DEFAULT_OTHERS_GROUP_NAME = "others"; public static final String DEFAULT_ORIGINAL_GROUP_NAME = "original"; - public static final String DEFAULT_COMPLETION_STYLE_STARTING = "36"; // cyan - public static final String DEFAULT_COMPLETION_STYLE_DESCRIPTION = "90"; // dark gray - public static final String DEFAULT_COMPLETION_STYLE_GROUP = "35;1"; // magenta - public static final String DEFAULT_COMPLETION_STYLE_SELECTION = "7"; // inverted + public static final String DEFAULT_COMPLETION_STYLE_STARTING = "fg:cyan"; + public static final String DEFAULT_COMPLETION_STYLE_DESCRIPTION = "fg:bright-black"; + public static final String DEFAULT_COMPLETION_STYLE_GROUP = "fg:bright-magenta,bold"; + public static final String DEFAULT_COMPLETION_STYLE_SELECTION = "inverse"; + public static final String DEFAULT_COMPLETION_STYLE_BACKGROUND = "bg:default"; + public static final String DEFAULT_COMPLETION_STYLE_LIST_STARTING = DEFAULT_COMPLETION_STYLE_STARTING; + public static final String DEFAULT_COMPLETION_STYLE_LIST_DESCRIPTION = DEFAULT_COMPLETION_STYLE_DESCRIPTION; + public static final String DEFAULT_COMPLETION_STYLE_LIST_GROUP = "fg:black,bold"; + public static final String DEFAULT_COMPLETION_STYLE_LIST_SELECTION = DEFAULT_COMPLETION_STYLE_SELECTION; + public static final String DEFAULT_COMPLETION_STYLE_LIST_BACKGROUND = "bg:bright-magenta"; public static final int DEFAULT_INDENTATION = 0; public static final int DEFAULT_FEATURES_MAX_BUFFER_SIZE = 1000; + public static final int DEFAULT_SUGGESTIONS_MIN_BUFFER_SIZE = 1; private static final int MIN_ROWS = 3; @@ -162,6 +169,7 @@ protected Highlighter highlighter = new DefaultHighlighter(); protected Parser parser = new DefaultParser(); protected Expander expander = new DefaultExpander(); + protected CompletionMatcher completionMatcher = new CompletionMatcherImpl(); // // State variables @@ -270,6 +278,8 @@ */ protected List<String> commandsBuffer = new ArrayList<>(); + int candidateStartPosition = 0; + public LineReaderImpl(Terminal terminal) throws IOException { this(terminal, null, null); } @@ -419,6 +429,10 @@ this.expander = expander; } + public void setCompletionMatcher(CompletionMatcher completionMatcher) { + this.completionMatcher = completionMatcher; + } + // // Line Reading // @@ -636,7 +650,7 @@ } Binding o = readBinding(getKeys(), local); if (o == null) { - throw new EndOfFileException(); + throw new EndOfFileException().partialLine(buf.length() > 0 ? buf.toString() : null); } Log.trace("Binding: ", o); if (buf.length() == 0 && getLastBinding().charAt(0) == originalAttributes.getControlChar(ControlChar.VEOF)) { @@ -741,11 +755,7 @@ size.copy(terminal.getBufferSize()); display = new Display(terminal, false); - if (size.getRows() == 0 || size.getColumns() == 0) { - display.resize(1, Integer.MAX_VALUE); - } else { - display.resize(size.getRows(), size.getColumns()); - } + display.resize(size.getRows(), size.getColumns()); if (isSet(Option.DELAY_LINE_WRAP)) display.setDelayLineWrap(true); } @@ -1049,8 +1059,7 @@ @Override public boolean isSet(Option option) { - Boolean b = options.get(option); - return b != null ? b : option.isDef(); + return option.isSet(options); } @Override @@ -1070,10 +1079,13 @@ @Override public void editAndAddInBuffer(File file) throws Exception { + if (isSet(Option.BRACKETED_PASTE)) { + terminal.writer().write(BRACKETED_PASTE_OFF); + } Constructor<?> ctor = Class.forName("org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); Editor editor = (Editor) ctor.newInstance(terminal, new File(file.getParent())); editor.setRestricted(true); - editor.open(Arrays.asList(file.getName())); + editor.open(Collections.singletonList(file.getName())); editor.run(); BufferedReader br = new BufferedReader(new FileReader(file)); String line; @@ -1344,7 +1356,7 @@ protected boolean viForwardWord() { if (count < 0) { - return callNeg(this::backwardWord); + return callNeg(this::viBackwardWord); } while (count-- > 0) { if (isViAlphaNum(buf.currChar())) { @@ -1395,21 +1407,7 @@ } protected boolean emacsForwardWord() { - if (count < 0) { - return callNeg(this::emacsBackwardWord); - } - while (count-- > 0) { - while (buf.cursor() < buf.length() && !isWord(buf.currChar())) { - buf.move(1); - } - if (isInViChangeOperation() && count == 0) { - return true; - } - while (buf.cursor() < buf.length() && isWord(buf.currChar())) { - buf.move(1); - } - } - return true; + return forwardWord(); } protected boolean viForwardBlankWordEnd() { @@ -1481,7 +1479,7 @@ protected boolean viBackwardWord() { if (count < 0) { - return callNeg(this::backwardWord); + return callNeg(this::viForwardWord); } while (count-- > 0) { int nl = 0; @@ -1584,24 +1582,7 @@ } protected boolean emacsBackwardWord() { - if (count < 0) { - return callNeg(this::emacsForwardWord); - } - while (count-- > 0) { - while (buf.cursor() > 0) { - buf.move(-1); - if (isWord(buf.currChar())) { - break; - } - } - while (buf.cursor() > 0) { - buf.move(-1); - if (!isWord(buf.currChar())) { - break; - } - } - } - return true; + return backwardWord(); } protected boolean backwardDeleteWord() { @@ -2557,7 +2538,7 @@ } terminal.puts(Capability.keypad_local); terminal.trackMouse(Terminal.MouseTracking.Off); - if (isSet(Option.BRACKETED_PASTE)) + if (isSet(Option.BRACKETED_PASTE) && !isTerminalDumb()) terminal.writer().write(BRACKETED_PASTE_OFF); flush(); } @@ -2720,7 +2701,7 @@ starts.add(new Pair<>(index, m.start())); } return starts; - } + } private String doGetSearchPattern() { StringBuilder sb = new StringBuilder(); @@ -3908,7 +3889,7 @@ } List<AttributedString> newLinesToDisplay = new ArrayList<>(); - int displaySize = size.getRows() - (status != null ? status.size() : 0); + int displaySize = displayRows(status); if (newLines.size() > displaySize && !isTerminalDumb()) { StringBuilder sb = new StringBuilder(">...."); // blanks are needed when displaying command completion candidate list @@ -3964,13 +3945,12 @@ } History history = getHistory(); StringBuilder sb = new StringBuilder(); - char prev = '0'; - for (char c: buffer.toCharArray()) { - if ((c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^') && prev != '\\' ) { + for (char c: buffer.replace("\\", "\\\\").toCharArray()) { + if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '*' + || c == '$' || c == '.' || c == '?' || c == '+') { sb.append('\\'); } sb.append(c); - prev = c; } Pattern pattern = Pattern.compile(sb.toString() + ".*", Pattern.DOTALL); Iterator<History.Entry> iter = history.reverseIterator(history.last()); @@ -4002,7 +3982,7 @@ AttributedStringBuilder full = new AttributedStringBuilder().tabs(TAB_WIDTH); full.append(prompt); full.append(tNewBuf); - if (doAutosuggestion) { + if (doAutosuggestion && !isTerminalDumb()) { String lastBinding = getLastBinding() != null ? getLastBinding() : ""; if (autosuggestion == SuggestionType.HISTORY) { AttributedStringBuilder sb = new AttributedStringBuilder(); @@ -4010,8 +3990,9 @@ sb.styled(AttributedStyle::faint, tailTip); full.append(sb.toAttributedString()); } else if (autosuggestion == SuggestionType.COMPLETER) { - if (buf.length() > 0 && buf.length() == buf.cursor() - && (!lastBinding.equals("\t") || buf.prevChar() == ' ' || buf.prevChar() == '=')) { + if (buf.length() >= getInt(SUGGESTIONS_MIN_BUFFER_SIZE, DEFAULT_SUGGESTIONS_MIN_BUFFER_SIZE) + && buf.length() == buf.cursor() + && (!lastBinding.equals("\t") || buf.prevChar() == ' ' || buf.prevChar() == '=')) { clearChoices(); listChoices(true); } else if (!lastBinding.equals("\t")) { @@ -4157,7 +4138,7 @@ } else sb.append(ch); } - if (padToWidth > cols) { + if (padToWidth > cols && padToWidth > 0) { int padCharCols = WCWidth.wcwidth(padChar); int padCount = (padToWidth - cols) / padCharCols; sb = padPartString; @@ -4184,6 +4165,9 @@ List<String> missings = new ArrayList<>(); if (computePrompts && secondaryPromptPattern.contains("%P")) { width = prompt.columnLength(); + if (width > size.getColumns() || prompt.contains('\n')) { + width = new TerminalLine(prompt.toString(), 0, size.getColumns()).getEndLine().length(); + } for (int line = 0; line < lines.size() - 1; line++) { AttributedString prompt; buf.append(lines.get(line)).append("\n"); @@ -4398,6 +4382,9 @@ } } catch (Exception e) { Log.info("Error while finding completion candidates", e); + if (Log.isDebugEnabled()) { + e.printStackTrace(); + } return false; } @@ -4423,79 +4410,17 @@ boolean caseInsensitive = isSet(Option.CASE_INSENSITIVE); int errors = getInt(ERRORS, DEFAULT_ERRORS); - // Build a list of sorted candidates - Map<String, List<Candidate>> sortedCandidates = new HashMap<>(); - for (Candidate cand : candidates) { - sortedCandidates - .computeIfAbsent(AttributedString.fromAnsi(cand.value()).toString(), s -> new ArrayList<>()) - .add(cand); - } - - // Find matchers - // TODO: glob completion - List<Function<Map<String, List<Candidate>>, - Map<String, List<Candidate>>>> matchers; - Predicate<String> exact; - if (prefix) { - String wd = line.word(); - String wdi = caseInsensitive ? wd.toLowerCase() : wd; - String wp = wdi.substring(0, line.wordCursor()); - matchers = Arrays.asList( - simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).startsWith(wp)), - simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wp)), - typoMatcher(wp, errors, caseInsensitive) - ); - exact = s -> caseInsensitive ? s.equalsIgnoreCase(wp) : s.equals(wp); - } else if (isSet(Option.COMPLETE_IN_WORD)) { - String wd = line.word(); - String wdi = caseInsensitive ? wd.toLowerCase() : wd; - String wp = wdi.substring(0, line.wordCursor()); - String ws = wdi.substring(line.wordCursor()); - Pattern p1 = Pattern.compile(Pattern.quote(wp) + ".*" + Pattern.quote(ws) + ".*"); - Pattern p2 = Pattern.compile(".*" + Pattern.quote(wp) + ".*" + Pattern.quote(ws) + ".*"); - matchers = Arrays.asList( - simpleMatcher(s -> p1.matcher(caseInsensitive ? s.toLowerCase() : s).matches()), - simpleMatcher(s -> p2.matcher(caseInsensitive ? s.toLowerCase() : s).matches()), - typoMatcher(wdi, errors, caseInsensitive) - ); - exact = s -> caseInsensitive ? s.equalsIgnoreCase(wd) : s.equals(wd); - } else { - String wd = line.word(); - String wdi = caseInsensitive ? wd.toLowerCase() : wd; - if (isSet(Option.EMPTY_WORD_OPTIONS) || wd.length() > 0) { - matchers = Arrays.asList( - simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).startsWith(wdi)), - simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wdi)), - typoMatcher(wdi, errors, caseInsensitive) - ); - } else { - matchers = Arrays.asList( - simpleMatcher(s -> !s.startsWith("-")) - ); - } - exact = s -> caseInsensitive ? s.equalsIgnoreCase(wd) : s.equals(wd); - } + completionMatcher.compile(options, prefix, line, caseInsensitive, errors, getOriginalGroupName()); // Find matching candidates - Map<String, List<Candidate>> matching = Collections.emptyMap(); - for (Function<Map<String, List<Candidate>>, - Map<String, List<Candidate>>> matcher : matchers) { - matching = matcher.apply(sortedCandidates); - if (!matching.isEmpty()) { - break; - } - } - + List<Candidate> possible = completionMatcher.matches(candidates); // If we have no matches, bail out - if (matching.isEmpty()) { + if (possible.isEmpty()) { return false; } size.copy(terminal.getSize()); try { // If we only need to display the list, do it now if (lst == CompletionType.List) { - List<Candidate> possible = matching.entrySet().stream() - .flatMap(e -> e.getValue().stream()) - .collect(Collectors.toList()); doList(possible, line.word(), false, line::escape, forSuggestion); return !possible.isEmpty(); } @@ -4503,16 +4428,12 @@ // Check if there's a single possible match Candidate completion = null; // If there's a single possible completion - if (matching.size() == 1) { - completion = matching.values().stream().flatMap(Collection::stream) - .findFirst().orElse(null); + if (possible.size() == 1) { + completion = possible.get(0); } // Or if RECOGNIZE_EXACT is set, try to find an exact match else if (isSet(Option.RECOGNIZE_EXACT)) { - completion = matching.values().stream().flatMap(Collection::stream) - .filter(Candidate::complete) - .filter(c -> exact.test(c.value())) - .findFirst().orElse(null); + completion = completionMatcher.exactMatch(); } // Complete and exit if (completion != null && !completion.value().isEmpty()) { @@ -4531,6 +4452,9 @@ } } if (completion.suffix() != null) { + if (autosuggestion == SuggestionType.COMPLETER) { + listChoices(true); + } redisplay(); Binding op = readBinding(getKeys()); if (op != null) { @@ -4549,10 +4473,6 @@ return true; } - List<Candidate> possible = matching.entrySet().stream() - .flatMap(e -> e.getValue().stream()) - .collect(Collectors.toList()); - if (useMenu) { buf.move(line.word().length() - line.wordCursor()); buf.backspace(line.word().length()); @@ -4570,10 +4490,7 @@ } // Now, we need to find the unambiguous completion // TODO: need to find common suffix - String commonPrefix = null; - for (String key : matching.keySet()) { - commonPrefix = commonPrefix == null ? key : getCommonStart(commonPrefix, key, caseInsensitive); - } + String commonPrefix = completionMatcher.getCommonPrefix(); boolean hasUnambiguous = commonPrefix.startsWith(current) && !commonPrefix.equals(current); if (hasUnambiguous) { @@ -4641,7 +4558,7 @@ protected Comparator<Candidate> getCandidateComparator(boolean caseInsensitive, String word) { String wdi = caseInsensitive ? word.toLowerCase() : word; - ToIntFunction<String> wordDistance = w -> distance(wdi, caseInsensitive ? w.toLowerCase() : w); + ToIntFunction<String> wordDistance = w -> ReaderUtils.distance(wdi, caseInsensitive ? w.toLowerCase() : w); return Comparator .comparing(Candidate::value, Comparator.comparingInt(wordDistance)) .thenComparing(Comparator.naturalOrder()); @@ -4688,37 +4605,6 @@ } } - private Function<Map<String, List<Candidate>>, - Map<String, List<Candidate>>> simpleMatcher(Predicate<String> pred) { - return m -> m.entrySet().stream() - .filter(e -> pred.test(e.getKey())) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - } - - private Function<Map<String, List<Candidate>>, - Map<String, List<Candidate>>> typoMatcher(String word, int errors, boolean caseInsensitive) { - return m -> { - Map<String, List<Candidate>> map = m.entrySet().stream() - .filter(e -> distance(word, caseInsensitive ? e.getKey() : e.getKey().toLowerCase()) < errors) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - if (map.size() > 1) { - map.computeIfAbsent(word, w -> new ArrayList<>()) - .add(new Candidate(word, word, getOriginalGroupName(), null, null, null, false)); - } - return map; - }; - } - - private int distance(String word, String cand) { - if (word.length() < cand.length()) { - int d1 = Levenshtein.distance(word, cand.substring(0, Math.min(cand.length(), word.length()))); - int d2 = Levenshtein.distance(word, cand); - return Math.min(d1, d2); - } else { - return Levenshtein.distance(word, cand); - } - } - protected boolean nextBindingIsComplete() { redisplay(); KeyMap<Binding> keyMap = keyMaps.get(MENU); @@ -4731,6 +4617,19 @@ } } + private int displayRows() { + return displayRows(Status.getStatus(terminal, false)); + } + + private int displayRows(Status status) { + return size.getRows() - (status != null ? status.size() : 0); + } + + private int promptLines() { + AttributedString text = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); + return text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); + } + private class MenuSupport implements Supplier<AttributedString> { final List<Candidate> possible; final BiFunction<CharSequence, Boolean, CharSequence> escaper; @@ -4850,10 +4749,7 @@ // Compute displayed prompt PostResult pr = computePost(possible, completion(), null, completed); - AttributedString text = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); - int promptLines = text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); - Status status = Status.getStatus(terminal, false); - int displaySize = size.getRows() - (status != null ? status.size() : 0) - promptLines; + int displaySize = displayRows() - promptLines(); if (pr.lines > displaySize) { int displayed = displaySize - 1; if (pr.selectedLine >= 0) { @@ -4902,7 +4798,13 @@ original.sort(getCandidateComparator(caseInsensitive, completed)); mergeCandidates(original); computePost(original, null, possible, completed); - + // candidate grouping is not supported by MenuSupport + boolean defaultAutoGroup = isSet(Option.AUTO_GROUP); + boolean defaultGroup = isSet(Option.GROUP); + if (!isSet(Option.GROUP_PERSIST)) { + option(Option.AUTO_GROUP, false); + option(Option.GROUP, false); + } // Build menu support MenuSupport menuSupport = new MenuSupport(original, completed, escaper); post = menuSupport; @@ -4959,17 +4861,21 @@ pushBackBinding(true); } post = null; + option(Option.AUTO_GROUP, defaultAutoGroup); + option(Option.GROUP, defaultGroup); return true; } } doAutosuggestion = false; callWidget(REDISPLAY); } + option(Option.AUTO_GROUP, defaultAutoGroup); + option(Option.GROUP, defaultGroup); return false; } protected boolean clearChoices() { - return doList(new ArrayList<Candidate>(), "", false, null, false); + return doList(new ArrayList<>(), "", false, null, false); } protected boolean doList(List<Candidate> possible @@ -5009,14 +4915,14 @@ boolean caseInsensitive = isSet(Option.CASE_INSENSITIVE); StringBuilder sb = new StringBuilder(); + candidateStartPosition = 0; while (true) { String current = completed + sb.toString(); List<Candidate> cands; if (sb.length() > 0) { - cands = possible.stream() - .filter(c -> caseInsensitive - ? c.value().toLowerCase().startsWith(current.toLowerCase()) - : c.value().startsWith(current)) + completionMatcher.compile(options, false, new CompletingWord(current), caseInsensitive, 0 + , null); + cands = completionMatcher.matches(possible).stream() .sorted(getCandidateComparator(caseInsensitive, current)) .collect(Collectors.toList()); } else { @@ -5024,6 +4930,9 @@ .sorted(getCandidateComparator(caseInsensitive, current)) .collect(Collectors.toList()); } + if (isSet(Option.AUTO_MENU_LIST) && candidateStartPosition == 0) { + candidateStartPosition = candidateStartPosition(cands); + } post = () -> { AttributedString t = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); int pl = t.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); @@ -5035,10 +4944,11 @@ redisplay(false); buf.cursor(oldCursor); println(); - List<AttributedString> ls = postResult.post.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); + List<AttributedString> ls = pr.post.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); Display d = new Display(terminal, false); d.resize(size.getRows(), size.getColumns()); d.update(ls, -1); + println(); redrawLine(); return new AttributedString(""); } @@ -5089,6 +4999,59 @@ } } + private static class CompletingWord implements CompletingParsedLine { + private final String word; + + public CompletingWord(String word) { + this.word = word; + } + + @Override + public CharSequence escape(CharSequence candidate, boolean complete) { + return null; + } + + @Override + public int rawWordCursor() { + return word.length(); + } + + @Override + public int rawWordLength() { + return word.length(); + } + + @Override + public String word() { + return word; + } + + @Override + public int wordCursor() { + return word.length(); + } + + @Override + public int wordIndex() { + return 0; + } + + @Override + public List<String> words() { + return null; + } + + @Override + public String line() { + return word; + } + + @Override + public int cursor() { + return word.length(); + } + } + protected static class PostResult { final AttributedString post; final int lines; @@ -5156,6 +5119,63 @@ private static final String DESC_SUFFIX = ")"; private static final int MARGIN_BETWEEN_DISPLAY_AND_DESC = 1; private static final int MARGIN_BETWEEN_COLUMNS = 3; + private static final int MENU_LIST_WIDTH = 25; + + private static class TerminalLine { + private String endLine; + private int startPos; + + public TerminalLine(String line, int startPos, int width) { + this.startPos = startPos; + endLine = line.substring(line.lastIndexOf('\n') + 1); + boolean first = true; + while (endLine.length() + (first ? startPos : 0) > width) { + if (first) { + endLine = endLine.substring(width - startPos); + } else { + endLine = endLine.substring(width); + } + first = false; + } + if (!first) { + this.startPos = 0; + } + } + + public int getStartPos() { + return startPos; + } + + public String getEndLine() { + return endLine; + } + } + + private int candidateStartPosition(List<Candidate> cands) { + List<String> values = cands.stream().map(c -> AttributedString.stripAnsi(c.displ())) + .filter(c -> !c.matches("\\w+") && c.length() > 1).collect(Collectors.toList()); + Set<String> notDelimiters = new HashSet<>(); + values.forEach(v -> v.substring(0, v.length() - 1).chars() + .filter(c -> !Character.isDigit(c) && !Character.isAlphabetic(c)) + .forEach(c -> notDelimiters.add(Character.toString((char)c)))); + int width = size.getColumns(); + int promptLength = prompt != null ? prompt.length() : 0; + if (promptLength > 0) { + TerminalLine tp = new TerminalLine(prompt.toString(), 0, width); + promptLength = tp.getEndLine().length(); + } + TerminalLine tl = new TerminalLine(buf.substring(0, buf.cursor()), promptLength, width); + int out = tl.getStartPos(); + String buffer = tl.getEndLine(); + for (int i = buffer.length(); i > 0; i--) { + if (buffer.substring(0, i).matches(".*\\W") + && !notDelimiters.contains(buffer.substring(i - 1, i))) { + out += i; + break; + } + } + return out; + } @SuppressWarnings("unchecked") protected PostResult toColumns(List<Object> items, Candidate selection, String completed, Function<String, Integer> wcwidth, int width, boolean rowsFirst) { @@ -5163,6 +5183,7 @@ // TODO: support Option.LIST_PACKED // Compute column width int maxWidth = 0; + int listSize = 0; for (Object item : items) { if (item instanceof String) { int len = wcwidth.apply((String) item); @@ -5170,6 +5191,7 @@ } else if (item instanceof List) { for (Candidate cand : (List<Candidate>) item) { + listSize++; int len = wcwidth.apply(cand.displ()); if (cand.descr() != null) { len += MARGIN_BETWEEN_DISPLAY_AND_DESC; @@ -5183,8 +5205,33 @@ } // Build columns AttributedStringBuilder sb = new AttributedStringBuilder(); - for (Object list : items) { - toColumns(list, width, maxWidth, sb, selection, completed, rowsFirst, out); + if (listSize > 0) { + if (isSet(Option.AUTO_MENU_LIST) + && listSize < Math.min(getInt(MENU_LIST_MAX, DEFAULT_MENU_LIST_MAX), displayRows() - promptLines())) { + maxWidth = Math.max(maxWidth, MENU_LIST_WIDTH); + sb.tabs(Math.max(Math.min(candidateStartPosition, width - maxWidth - 1), 1)); + width = maxWidth + 2; + if (!isSet(Option.GROUP_PERSIST)) { + List<Candidate> list = new ArrayList<>(); + for (Object o : items) { + if (o instanceof Collection) { + list.addAll((Collection<Candidate>) o); + } + } + list = list.stream() + .sorted(getCandidateComparator(isSet(Option.CASE_INSENSITIVE), "")) + .collect(Collectors.toList()); + toColumns(list, width, maxWidth, sb, selection, completed, rowsFirst, true, out); + } else { + for (Object list : items) { + toColumns(list, width, maxWidth, sb, selection, completed, rowsFirst, true, out); + } + } + } else { + for (Object list : items) { + toColumns(list, width, maxWidth, sb, selection, completed, rowsFirst, false, out); + } + } } if (sb.length() > 0 && sb.charAt(sb.length() - 1) == '\n') { sb.setLength(sb.length() - 1); @@ -5193,16 +5240,29 @@ } @SuppressWarnings("unchecked") - protected void toColumns(Object items, int width, int maxWidth, AttributedStringBuilder sb, Candidate selection, String completed, boolean rowsFirst, int[] out) { + protected void toColumns(Object items, int width, int maxWidth, AttributedStringBuilder sb, Candidate selection, String completed + , boolean rowsFirst, boolean doMenuList, int[] out) { if (maxWidth <= 0 || width <= 0) { return; } // This is a group if (items instanceof String) { - sb.style(getCompletionStyleGroup()) + if (doMenuList) { + sb.style(AttributedStyle.DEFAULT); + sb.append('\t'); + } + AttributedStringBuilder asb = new AttributedStringBuilder(); + asb.style(getCompletionStyleGroup(doMenuList)) .append((String) items) - .style(AttributedStyle.DEFAULT) - .append("\n"); + .style(AttributedStyle.DEFAULT); + if (doMenuList) { + for (int k = ((String) items).length(); k < maxWidth + 1; k++) { + asb.append(' '); + } + } + sb.style(getCompletionStyleBackground(doMenuList)); + sb.append(asb); + sb.append("\n"); out[0]++; } // This is a Candidate list @@ -5224,6 +5284,11 @@ index = (i, j) -> j * lines + i; } for (int i = 0; i < lines; i++) { + if (doMenuList) { + sb.style(AttributedStyle.DEFAULT); + sb.append('\t'); + } + AttributedStringBuilder asb = new AttributedStringBuilder(); for (int j = 0; j < columns; j++) { int idx = index.applyAsInt(i, j); if (idx < candidates.size()) { @@ -5248,56 +5313,85 @@ } if (cand == selection) { out[1] = i; - sb.style(getCompletionStyleSelection()); + asb.style(getCompletionStyleSelection(doMenuList)); if (left.toString().regionMatches( isSet(Option.CASE_INSENSITIVE), 0, completed, 0, completed.length())) { - sb.append(left.toString(), 0, completed.length()); - sb.append(left.toString(), completed.length(), left.length()); + asb.append(left.toString(), 0, completed.length()); + asb.append(left.toString(), completed.length(), left.length()); } else { - sb.append(left.toString()); + asb.append(left.toString()); } for (int k = 0; k < maxWidth - lw - rw; k++) { - sb.append(' '); + asb.append(' '); } if (right != null) { - sb.append(right); + asb.append(right); } - sb.style(AttributedStyle.DEFAULT); + asb.style(AttributedStyle.DEFAULT); } else { if (left.toString().regionMatches( isSet(Option.CASE_INSENSITIVE), 0, completed, 0, completed.length())) { - sb.style(getCompletionStyleStarting()); - sb.append(left, 0, completed.length()); - sb.style(AttributedStyle.DEFAULT); - sb.append(left, completed.length(), left.length()); + asb.style(getCompletionStyleStarting(doMenuList)); + asb.append(left, 0, completed.length()); + asb.style(AttributedStyle.DEFAULT); + asb.append(left, completed.length(), left.length()); } else { - sb.append(left); + asb.append(left); } if (right != null || hasRightItem) { for (int k = 0; k < maxWidth - lw - rw; k++) { - sb.append(' '); + asb.append(' '); } } if (right != null) { - sb.style(getCompletionStyleDescription()); - sb.append(right); - sb.style(AttributedStyle.DEFAULT); + asb.style(getCompletionStyleDescription(doMenuList)); + asb.append(right); + asb.style(AttributedStyle.DEFAULT); + } else if (doMenuList) { + for (int k = lw; k < maxWidth; k++) { + asb.append(' '); + } } } if (hasRightItem) { for (int k = 0; k < MARGIN_BETWEEN_COLUMNS; k++) { - sb.append(' '); + asb.append(' '); } } + if (doMenuList) { + asb.append(' '); + } } } + sb.style(getCompletionStyleBackground(doMenuList)); + sb.append(asb); sb.append('\n'); } out[0] += lines; } } - private AttributedStyle getCompletionStyleStarting() { + protected AttributedStyle getCompletionStyleStarting(boolean menuList) { + return menuList ? getCompletionStyleListStarting() : getCompletionStyleStarting(); + } + + protected AttributedStyle getCompletionStyleDescription(boolean menuList) { + return menuList ? getCompletionStyleListDescription() : getCompletionStyleDescription(); + } + + protected AttributedStyle getCompletionStyleGroup(boolean menuList) { + return menuList ? getCompletionStyleListGroup() : getCompletionStyleGroup(); + } + + protected AttributedStyle getCompletionStyleSelection(boolean menuList) { + return menuList ? getCompletionStyleListSelection() : getCompletionStyleSelection(); + } + + protected AttributedStyle getCompletionStyleBackground(boolean menuList) { + return menuList ? getCompletionStyleListBackground() : getCompletionStyleBackground(); + } + + protected AttributedStyle getCompletionStyleStarting() { return getCompletionStyle(COMPLETION_STYLE_STARTING, DEFAULT_COMPLETION_STYLE_STARTING); } @@ -5313,37 +5407,38 @@ return getCompletionStyle(COMPLETION_STYLE_SELECTION, DEFAULT_COMPLETION_STYLE_SELECTION); } + protected AttributedStyle getCompletionStyleBackground() { + return getCompletionStyle(COMPLETION_STYLE_BACKGROUND, DEFAULT_COMPLETION_STYLE_BACKGROUND); + } + + protected AttributedStyle getCompletionStyleListStarting() { + return getCompletionStyle(COMPLETION_STYLE_LIST_STARTING, DEFAULT_COMPLETION_STYLE_LIST_STARTING); + } + + protected AttributedStyle getCompletionStyleListDescription() { + return getCompletionStyle(COMPLETION_STYLE_LIST_DESCRIPTION, DEFAULT_COMPLETION_STYLE_LIST_DESCRIPTION); + } + + protected AttributedStyle getCompletionStyleListGroup() { + return getCompletionStyle(COMPLETION_STYLE_LIST_GROUP, DEFAULT_COMPLETION_STYLE_LIST_GROUP); + } + + protected AttributedStyle getCompletionStyleListSelection() { + return getCompletionStyle(COMPLETION_STYLE_LIST_SELECTION, DEFAULT_COMPLETION_STYLE_LIST_SELECTION); + } + + protected AttributedStyle getCompletionStyleListBackground() { + return getCompletionStyle(COMPLETION_STYLE_LIST_BACKGROUND, DEFAULT_COMPLETION_STYLE_LIST_BACKGROUND); + } + protected AttributedStyle getCompletionStyle(String name, String value) { - return buildStyle(getString(name, value)); + return new StyleResolver(s -> getString(s, null)).resolve("." + name, value); } protected AttributedStyle buildStyle(String str) { return AttributedString.fromAnsi("\u001b[" + str + "m ").styleAt(0); } - private String getCommonStart(String str1, String str2, boolean caseInsensitive) { - int[] s1 = str1.codePoints().toArray(); - int[] s2 = str2.codePoints().toArray(); - int len = 0; - while (len < Math.min(s1.length, s2.length)) { - int ch1 = s1[len]; - int ch2 = s2[len]; - if (ch1 != ch2 && caseInsensitive) { - ch1 = Character.toUpperCase(ch1); - ch2 = Character.toUpperCase(ch2); - if (ch1 != ch2) { - ch1 = Character.toLowerCase(ch1); - ch2 = Character.toLowerCase(ch2); - } - } - if (ch1 != ch2) { - break; - } - len++; - } - return new String(s1, 0, len); - } - /** * Used in "vi" mode for argumented history move, to move a specific * number of history entries forward or back.
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java index a8a419d..0ae9475 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2020, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -9,6 +9,7 @@ package jdk.internal.org.jline.reader.impl; import jdk.internal.org.jline.reader.LineReader; +import jdk.internal.org.jline.utils.Levenshtein; public class ReaderUtils { @@ -67,4 +68,14 @@ return nb; } + public static int distance(String word, String cand) { + if (word.length() < cand.length()) { + int d1 = Levenshtein.distance(word, cand.substring(0, Math.min(cand.length(), word.length()))); + int d2 = Levenshtein.distance(word, cand); + return Math.min(d1, d2); + } else { + return Levenshtein.distance(word, cand); + } + } + }
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java index b1ee32f..8baac65 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java
@@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.function.Supplier; @@ -28,10 +29,11 @@ */ public class StringsCompleter implements Completer { - protected Collection<Candidate> candidates = new ArrayList<>(); + protected Collection<Candidate> candidates; protected Supplier<Collection<String>> stringsSupplier; public StringsCompleter() { + this(Collections.<Candidate>emptyList()); } public StringsCompleter(Supplier<Collection<String>> stringsSupplier) { @@ -46,6 +48,7 @@ public StringsCompleter(Iterable<String> strings) { assert strings != null; + this.candidates = new ArrayList<>(); for (String string : strings) { candidates.add(new Candidate(AttributedString.stripAnsi(string), string, null, null, null, null, true)); } @@ -57,9 +60,10 @@ public StringsCompleter(Collection<Candidate> candidates) { assert candidates != null; - this.candidates.addAll(candidates); + this.candidates = new ArrayList<>(candidates); } + @Override public void complete(LineReader reader, final ParsedLine commandLine, final List<Candidate> candidates) { assert commandLine != null; assert candidates != null; @@ -72,4 +76,9 @@ } } + @Override + public String toString() { + String value = candidates != null ? candidates.toString() : "{" + stringsSupplier.toString() + "}"; + return "StringsCompleter" + value; + } }
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java new file mode 100644 index 0000000..691708e --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java
@@ -0,0 +1,150 @@ +/* + * Copyright (c) 2002-2020, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.reader.impl.completer; + +import java.util.*; + +import jdk.internal.org.jline.reader.Candidate; +import jdk.internal.org.jline.reader.Completer; +import jdk.internal.org.jline.reader.LineReader; +import jdk.internal.org.jline.reader.ParsedLine; +import jdk.internal.org.jline.utils.AttributedString; + +/** + * Completer which contains multiple completers and aggregates them together. + * + * @author <a href="mailto:matti.rintanikkola@gmail.com">Matti Rinta-Nikkola</a> + */ +public class SystemCompleter implements Completer { + private Map<String,List<Completer>> completers = new HashMap<>(); + private Map<String,String> aliasCommand = new HashMap<>(); + private StringsCompleter commands; + private boolean compiled = false; + + public SystemCompleter() {} + + @Override + public void complete(LineReader reader, ParsedLine commandLine, List<Candidate> candidates) { + if (!compiled) { + throw new IllegalStateException(); + } + assert commandLine != null; + assert candidates != null; + if (commandLine.words().size() > 0) { + if (commandLine.words().size() == 1) { + String buffer = commandLine.words().get(0); + int eq = buffer.indexOf('='); + if (eq < 0) { + commands.complete(reader, commandLine, candidates); + } else if (reader.getParser().validVariableName(buffer.substring(0, eq))) { + String curBuf = buffer.substring(0, eq + 1); + for (String c: completers.keySet()) { + candidates.add(new Candidate(AttributedString.stripAnsi(curBuf+c) + , c, null, null, null, null, true)); + } + } + } else { + String cmd = reader.getParser().getCommand(commandLine.words().get(0)); + if (command(cmd) != null) { + completers.get(command(cmd)).get(0).complete(reader, commandLine, candidates); + } + } + } + } + + public boolean isCompiled() { + return compiled; + } + + private String command(String cmd) { + String out = null; + if (cmd != null) { + if (completers.containsKey(cmd)) { + out = cmd; + } else if (aliasCommand.containsKey(cmd)) { + out = aliasCommand.get(cmd); + } + } + return out; + } + + public void add(String command, List<Completer> completers) { + for (Completer c : completers) { + add(command, c); + } + } + + public void add(List<String> commands, Completer completer) { + for (String c: commands) { + add(c, completer); + } + } + + public void add(String command, Completer completer) { + Objects.requireNonNull(command); + if (compiled) { + throw new IllegalStateException(); + } + if (!completers.containsKey(command)) { + completers.put(command, new ArrayList<Completer>()); + } + if (completer instanceof ArgumentCompleter) { + ((ArgumentCompleter) completer).setStrictCommand(false); + } + completers.get(command).add(completer); + } + + public void add(SystemCompleter other) { + if (other.isCompiled()) { + throw new IllegalStateException(); + } + for (Map.Entry<String, List<Completer>> entry: other.getCompleters().entrySet()) { + for (Completer c: entry.getValue()) { + add(entry.getKey(), c); + } + } + addAliases(other.getAliases()); + } + + public void addAliases(Map<String,String> aliasCommand) { + if (compiled) { + throw new IllegalStateException(); + } + this.aliasCommand.putAll(aliasCommand); + } + + private Map<String,String> getAliases() { + return aliasCommand; + } + + public void compile() { + if (compiled) { + return; + } + Map<String, List<Completer>> compiledCompleters = new HashMap<>(); + for (Map.Entry<String, List<Completer>> entry: completers.entrySet()) { + if (entry.getValue().size() == 1) { + compiledCompleters.put(entry.getKey(), entry.getValue()); + } else { + compiledCompleters.put(entry.getKey(), new ArrayList<Completer>()); + compiledCompleters.get(entry.getKey()).add(new AggregateCompleter(entry.getValue())); + } + } + completers = compiledCompleters; + Set<String> cmds = new HashSet<>(completers.keySet()); + cmds.addAll(aliasCommand.keySet()); + commands = new StringsCompleter(cmds); + compiled = true; + } + + public Map<String,List<Completer>> getCompleters() { + return completers; + } + +}
diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java index 46bbe1b..a2a0f57 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -84,7 +84,7 @@ try (BufferedReader reader = Files.newBufferedReader(path)) { internalClear(); reader.lines().forEach(line -> addHistoryLine(path, line)); - setHistoryFileData(path, new HistoryFileData(items.size(), items.size())); + setHistoryFileData(path, new HistoryFileData(items.size(), offset + items.size())); maybeResize(); } } @@ -105,7 +105,7 @@ Log.trace("Reading history from: ", path); try (BufferedReader reader = Files.newBufferedReader(path)) { reader.lines().forEach(line -> addHistoryLine(path, line, incremental)); - setHistoryFileData(path, new HistoryFileData(items.size(), items.size())); + setHistoryFileData(path, new HistoryFileData(items.size(), offset + items.size())); maybeResize(); } } @@ -136,11 +136,7 @@ private boolean isLineReaderHistory (Path path) throws IOException { Path lrp = getPath(); if (lrp == null) { - if (path != null) { - return false; - } else { - return true; - } + return path == null; } return Files.isSameFile(lrp, path); } @@ -226,7 +222,10 @@ private void internalWrite(Path path, int from) throws IOException { if (path != null) { Log.trace("Saving history to: ", path); - Files.createDirectories(path.toAbsolutePath().getParent()); + Path parent = path.toAbsolutePath().getParent(); + if (!Files.exists(parent)) { + Files.createDirectories(parent); + } // Append new items to the history file try (BufferedWriter writer = Files.newBufferedWriter(path.toAbsolutePath(), StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE)) { @@ -258,11 +257,11 @@ }); } // Remove duplicates - doTrimHistory(allItems, max); + List<Entry> trimmedItems = doTrimHistory(allItems, max); // Write history Path temp = Files.createTempFile(path.toAbsolutePath().getParent(), path.getF