# HG changeset patch # User chegar # Date 1510834555 0 # Node ID 76d033c9908f0168b01f6ca630754a0408b6a1ef # Parent 18e4312091688a87f8bf3e205707a19f98802939# Parent 13e39ca700d02944f64d4610930f0046356a2752 http-client-branch: merge diff -r 18e431209168 -r 76d033c9908f make/CompileToolsHotspot.gmk --- a/make/CompileToolsHotspot.gmk Thu Nov 16 10:29:18 2017 +0000 +++ b/make/CompileToolsHotspot.gmk Thu Nov 16 12:15:55 2017 +0000 @@ -67,6 +67,7 @@ $(SRC_DIR)/org.graalvm.compiler.phases.common/src \ $(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \ $(SRC_DIR)/org.graalvm.compiler.virtual/src \ + $(SRC_DIR)/org.graalvm.graphio/src \ $(SRC_DIR)/org.graalvm.util/src \ $(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \ $(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \ @@ -125,6 +126,7 @@ $(SRC_DIR)/org.graalvm.compiler.nodeinfo/src \ $(SRC_DIR)/org.graalvm.compiler.options/src \ $(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \ + $(SRC_DIR)/org.graalvm.graphio/src \ $(SRC_DIR)/org.graalvm.util/src \ $(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \ $(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \ diff -r 18e431209168 -r 76d033c9908f make/Help.gmk --- a/make/Help.gmk Thu Nov 16 10:29:18 2017 +0000 +++ b/make/Help.gmk Thu Nov 16 12:15:55 2017 +0000 @@ -36,15 +36,18 @@ $(info =====================) $(info ) $(info Common make targets) - $(info $(_) make [default] # Compile all modules in langtools, hotspot, jdk, jaxws,) - $(info $(_) # jaxp and corba, and create a runnable "exploded" image) - $(info $(_) make all # Compile everything, all repos, docs and images) - $(info $(_) make images # Create complete jdk and jre images (alias for product-images)) - $(info $(_) make -image # Build just the image (jdk, jre, test, docs etc)) + $(info $(_) make [default] # Compile all modules and create a runnable "exploded") + $(info $(_) # image (alias for jdk or exploded-image)) + $(info $(_) make all # Create all images: product, test, docs) + $(info $(_) # (alias for all-images)) + $(info $(_) make images # Create complete jdk and jre images) + $(info $(_) # (alias for product-images)) + $(info $(_) make -image # Build just the image for any of: ) + $(info $(_) # jdk, jre, test, docs, symbols, profiles) $(info $(_) make # Build the specified phase and everything it depends on) $(info $(_) # (gensrc, java, copy, libs, launchers, gendata, rmic)) - $(info $(_) make *-only # Applies to most targets and disables compling the) - $(info $(_) # dependencies for the target. This is faster but may) + $(info $(_) make *-only # Applies to most targets and disables building the) + $(info $(_) # dependencies for that target. This is faster but may) $(info $(_) # result in incorrect build results!) $(info $(_) make docs # Create all docs) $(info $(_) make docs-jdk-api # Create just JDK javadocs) @@ -74,7 +77,7 @@ $(info $(_) make hotspot # Build all of hotspot) $(info $(_) make hotspot- # Build just the specified jvm variant) $(info $(_) make hotspot-gensrc # Only build the gensrc part of hotspot) - $(info $(_) make hotspot-- # Build the specified phase for the specified module) + $(info $(_) make hotspot-- # Build the specified phase for the variant) $(info ) $(info Targets for specific modules) $(info $(_) make # Build and everything it depends on) diff -r 18e431209168 -r 76d033c9908f make/autoconf/spec.gmk.in diff -r 18e431209168 -r 76d033c9908f make/common/MakeBase.gmk --- a/make/common/MakeBase.gmk Thu Nov 16 10:29:18 2017 +0000 +++ b/make/common/MakeBase.gmk Thu Nov 16 12:15:55 2017 +0000 @@ -473,15 +473,32 @@ $(subst $(SPACE),?,$(strip $1)) ################################################################################ -# Make directory without forking mkdir if not needed +# Make directory without forking mkdir if not needed. +# +# If a directory with an encoded space is provided, the wildcard function +# sometimes returns false answers (typically if the dir existed when the +# makefile was parsed, but was deleted by a previous rule). In that case, always +# call mkdir regardless of what wildcard says. +# # 1: List of directories to create MakeDir = \ $(strip \ - $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, $(if $(wildcard $d), , \ - "$(call DecodeSpace, $d)")))) \ + $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, \ + $(if $(findstring ?, $d), '$(call DecodeSpace, $d)', \ + $(if $(wildcard $d), , $d) \ + ) \ + ))) \ $(if $(MakeDir_dirs_to_make), $(shell $(MKDIR) -p $(MakeDir_dirs_to_make))) \ ) +# Make directory for target file. Should handle spaces in filenames. Just +# calling $(call MakeDir $(@D)) will not work if the directory contains a space +# and the target file already exists. In that case, the target file will have +# its wildcard ? resolved and the $(@D) will evaluate each space separated dir +# part on its own. +MakeTargetDir = \ + $(call MakeDir, $(dir $(call EncodeSpace, $@))) + ################################################################################ # Assign a variable only if it is empty # Param 1 - Variable to assign @@ -499,7 +516,7 @@ # If the source and target parent directories are the same, recursive copy doesn't work # so we fall back on regular copy, which isn't preserving symlinks. define install-file - $(call MakeDir, $(@D)) + $(call MakeTargetDir) $(RM) '$(call DecodeSpace, $@)' if [ '$(call DecodeSpace, $(dir $@))' != \ '$(call DecodeSpace, $(dir $(call EncodeSpace, $<)))' ]; then \ @@ -526,21 +543,21 @@ # If copying a soft link to a directory, need to delete the target first to avoid # weird errors. define install-file - $(call MakeDir, $(@D)) + $(call MakeTargetDir) $(RM) '$(call DecodeSpace, $@)' $(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)' if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then $(XATTR) -cs '$(call DecodeSpace, $@)'; fi endef else define install-file - $(call MakeDir, $(@D)) + $(call MakeTargetDir) $(CP) -fP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)' endef endif # Variant of install file that does not preserve symlinks define install-file-nolink - $(call MakeDir, $(@D)) + $(call MakeTargetDir) $(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)' endef @@ -590,13 +607,13 @@ # careful when using this on Windows since the symlink created is only valid in # the unix emulation environment. define link-file-relative - $(call MakeDir, $(@D)) + $(call MakeTargetDir) $(RM) '$(call DecodeSpace, $@)' $(LN) -s '$(call DecodeSpace, $(call RelativePath, $<, $(@D)))' '$(call DecodeSpace, $@)' endef define link-file-absolute - $(call MakeDir, $(@D)) + $(call MakeTargetDir) $(RM) '$(call DecodeSpace, $@)' $(LN) -s '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)' endef diff -r 18e431209168 -r 76d033c9908f make/conf/jib-profiles.js diff -r 18e431209168 -r 76d033c9908f make/copy/Copy-java.base.gmk --- a/make/copy/Copy-java.base.gmk Thu Nov 16 10:29:18 2017 +0000 +++ b/make/copy/Copy-java.base.gmk Thu Nov 16 12:15:55 2017 +0000 @@ -42,7 +42,7 @@ $(call install-file) $(INCLUDE_DST_OS_DIR)/%.h: \ - $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_EXPORT_DIR)/native/include/%.h + $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include/%.h $(call install-file) ################################################################################ diff -r 18e431209168 -r 76d033c9908f make/hotspot/lib/CompileJvm.gmk --- a/make/hotspot/lib/CompileJvm.gmk Thu Nov 16 10:29:18 2017 +0000 +++ b/make/hotspot/lib/CompileJvm.gmk Thu Nov 16 12:15:55 2017 +0000 @@ -57,8 +57,8 @@ $(patsubst %,-I%,$(filter-out $(JVM_VARIANT_OUTPUTDIR)/gensrc/%, $(JVM_SRC_DIRS))) \ -I$(JVM_VARIANT_OUTPUTDIR)/gensrc \ -I$(TOPDIR)/src/hotspot/share/precompiled \ - -I$(TOPDIR)/src/hotspot/share/prims \ -I$(TOPDIR)/src/java.base/share/native/include \ + -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \ # # INCLUDE_SUFFIX_* is only meant for including the proper diff -r 18e431209168 -r 76d033c9908f make/hotspot/lib/CompileLibjsig.gmk --- a/make/hotspot/lib/CompileLibjsig.gmk Thu Nov 16 10:29:18 2017 +0000 +++ b/make/hotspot/lib/CompileLibjsig.gmk Thu Nov 16 12:15:55 2017 +0000 @@ -57,7 +57,7 @@ endif else ifeq ($(OPENJDK_TARGET_OS), solaris) - LIBJSIG_CFLAGS := -m64 -KPIC -mt -I $(TOPDIR)/src/hotspot/os/solaris + LIBJSIG_CFLAGS := -m64 -KPIC -mt -I $(TOPDIR)/src/java.base/unix/native/include LIBJSIG_LDFLAGS := -m64 -mt -xnolib LIBJSIG_LIBS := $(LIBDL) diff -r 18e431209168 -r 76d033c9908f make/mapfiles/libinstrument/mapfile-vers --- a/make/mapfiles/libinstrument/mapfile-vers Thu Nov 16 10:29:18 2017 +0000 +++ b/make/mapfiles/libinstrument/mapfile-vers Thu Nov 16 12:15:55 2017 +0000 @@ -31,6 +31,7 @@ Agent_OnAttach; Java_sun_instrument_InstrumentationImpl_isModifiableClass0; Java_sun_instrument_InstrumentationImpl_isRetransformClassesSupported0; + Java_sun_instrument_InstrumentationImpl_setHasTransformers; Java_sun_instrument_InstrumentationImpl_setHasRetransformableTransformers; Java_sun_instrument_InstrumentationImpl_retransformClasses0; Java_sun_instrument_InstrumentationImpl_getAllLoadedClasses0; diff -r 18e431209168 -r 76d033c9908f make/nashorn/build.xml --- a/make/nashorn/build.xml Thu Nov 16 10:29:18 2017 +0000 +++ b/make/nashorn/build.xml Thu Nov 16 12:15:55 2017 +0000 @@ -830,8 +830,8 @@ - - + + diff -r 18e431209168 -r 76d033c9908f make/test/JtregNativeHotspot.gmk --- a/make/test/JtregNativeHotspot.gmk Thu Nov 16 10:29:18 2017 +0000 +++ b/make/test/JtregNativeHotspot.gmk Thu Nov 16 12:15:55 2017 +0000 @@ -63,6 +63,8 @@ $(TOPDIR)/test/hotspot/jtreg/runtime/RedefineTests \ $(TOPDIR)/test/hotspot/jtreg/compiler/floatingpoint/ \ $(TOPDIR)/test/hotspot/jtreg/compiler/calls \ + $(TOPDIR)/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup \ + $(TOPDIR)/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption \ $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo \ $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetNamedModule \ $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/IsModifiableModule \ diff -r 18e431209168 -r 76d033c9908f src/hotspot/.mx.jvmci/.project --- a/src/hotspot/.mx.jvmci/.project Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ - - - mx.jvmci - - - mx - - - - org.python.pydev.PyDevBuilder - - - - - - org.python.pydev.pythonNature - - diff -r 18e431209168 -r 76d033c9908f src/hotspot/.mx.jvmci/.pydevproject --- a/src/hotspot/.mx.jvmci/.pydevproject Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ - - -Default -python 2.7 - -/mx.jvmci - - -/mx - - - diff -r 18e431209168 -r 76d033c9908f src/hotspot/.mx.jvmci/mx_jvmci.py --- a/src/hotspot/.mx.jvmci/mx_jvmci.py Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/.mx.jvmci/mx_jvmci.py Thu Nov 16 12:15:55 2017 +0000 @@ -42,11 +42,6 @@ JVMCI_VERSION = 9 -""" -Top level directory of the JDK source workspace. -""" -_jdkSourceRoot = dirname(_suite.dir) - _JVMCI_JDK_TAG = 'jvmci' _minVersion = mx.VersionSpec('1.9') @@ -145,7 +140,7 @@ return True def _makehelp(): - return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_jdkSourceRoot) + return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_get_jdk_dir()) def _runmake(args): """run the JDK make process @@ -155,12 +150,12 @@ jdkBuildDir = _get_jdk_build_dir() if not exists(jdkBuildDir): - # JDK9 must be bootstrapped with a JDK8 - compliance = mx.JavaCompliance('8') - jdk8 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value) + # JDK10 must be bootstrapped with a JDK9 + compliance = mx.JavaCompliance('9') + jdk9 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value) cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--with-native-debug-symbols=external', '--disable-precompiled-headers', '--with-jvm-features=graal', - '--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk8.home, '--with-jvm-features=graal'] - mx.run(cmd, cwd=_jdkSourceRoot) + '--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk9.home, '--with-jvm-features=graal'] + mx.run(cmd, cwd=_get_jdk_dir()) cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel] if mx.get_opts().verbose: cmd.append('LOG=debug') @@ -170,11 +165,11 @@ if not mx.get_opts().verbose: mx.log('--------------- make execution ----------------------') - mx.log('Working directory: ' + _jdkSourceRoot) + mx.log('Working directory: ' + _get_jdk_dir()) mx.log('Command line: ' + ' '.join(cmd)) mx.log('-----------------------------------------------------') - mx.run(cmd, cwd=_jdkSourceRoot) + mx.run(cmd, cwd=_get_jdk_dir()) def _runmultimake(args): """run the JDK make process for one or more configurations""" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/assembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -1489,6 +1489,17 @@ #undef INSN + // Aliases for short forms of orn +void mvn(Register Rd, Register Rm, + enum shift_kind kind = LSL, unsigned shift = 0) { + orn(Rd, zr, Rm, kind, shift); +} + +void mvnw(Register Rd, Register Rm, + enum shift_kind kind = LSL, unsigned shift = 0) { + ornw(Rd, zr, Rm, kind, shift); +} + // Add/subtract (shifted register) #define INSN(NAME, size, op) \ void NAME(Register Rd, Register Rn, Register Rm, \ diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2657,9 +2657,9 @@ __ adrp(res, ExternalAddress(StubRoutines::crc_table_addr()), offset); if (offset) __ add(res, res, offset); - __ ornw(crc, zr, crc); // ~crc + __ mvnw(crc, crc); // ~crc __ update_byte_crc32(crc, val, res); - __ ornw(res, zr, crc); // ~crc + __ mvnw(res, crc); // ~crc } void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1030,7 +1030,81 @@ } void LIRGenerator::do_update_CRC32C(Intrinsic* x) { - Unimplemented(); + assert(UseCRC32CIntrinsics, "why are we here?"); + // Make all state_for calls early since they can emit code + LIR_Opr result = rlock_result(x); + int flags = 0; + switch (x->id()) { + case vmIntrinsics::_updateBytesCRC32C: + case vmIntrinsics::_updateDirectByteBufferCRC32C: { + bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C); + int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; + + LIRItem crc(x->argument_at(0), this); + LIRItem buf(x->argument_at(1), this); + LIRItem off(x->argument_at(2), this); + LIRItem end(x->argument_at(3), this); + + buf.load_item(); + off.load_nonconstant(); + end.load_nonconstant(); + + // len = end - off + LIR_Opr len = end.result(); + LIR_Opr tmpA = new_register(T_INT); + LIR_Opr tmpB = new_register(T_INT); + __ move(end.result(), tmpA); + __ move(off.result(), tmpB); + __ sub(tmpA, tmpB, tmpA); + len = tmpA; + + LIR_Opr index = off.result(); + if(off.result()->is_constant()) { + index = LIR_OprFact::illegalOpr; + offset += off.result()->as_jint(); + } + LIR_Opr base_op = buf.result(); + + if (index->is_valid()) { + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index, tmp); + index = tmp; + } + + if (offset) { + LIR_Opr tmp = new_pointer_register(); + __ add(base_op, LIR_OprFact::intConst(offset), tmp); + base_op = tmp; + offset = 0; + } + + LIR_Address* a = new LIR_Address(base_op, + index, + offset, + T_BYTE); + BasicTypeList signature(3); + signature.append(T_INT); + signature.append(T_ADDRESS); + signature.append(T_INT); + CallingConvention* cc = frame_map()->c_calling_convention(&signature); + const LIR_Opr result_reg = result_register_for(x->type()); + + LIR_Opr addr = new_pointer_register(); + __ leal(LIR_OprFact::address(a), addr); + + crc.load_item_force(cc->at(0)); + __ move(addr, cc->at(1)); + __ move(len, cc->at(2)); + + __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), getThreadTemp(), result_reg, cc->args()); + __ move(result_reg, result); + + break; + } + default: { + ShouldNotReachHere(); + } + } } void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/frame_aarch64.cpp --- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -431,11 +431,11 @@ // This is the sp before any possible extension (adapter/locals). intptr_t* unextended_sp = interpreter_frame_sender_sp(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (map->update_map()) { update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI return frame(sender_sp, unextended_sp, link(), sender_pc()); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/jni_aarch64.h --- a/src/hotspot/cpu/aarch64/jni_aarch64.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1997, 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 _JAVASOFT_JNI_MD_H_ -#define _JAVASOFT_JNI_MD_H_ - -#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE) - - -// Note: please do not change these without also changing jni_md.h in the JDK -// repository -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) - #define JNIEXPORT __attribute__((visibility("default"))) - #define JNIIMPORT __attribute__((visibility("default"))) -#else - #define JNIEXPORT - #define JNIIMPORT -#endif - - #define JNICALL - typedef int jint; - typedef long jlong; - -#else - #define JNIEXPORT __declspec(dllexport) - #define JNIIMPORT __declspec(dllimport) - #define JNICALL __stdcall - - typedef int jint; - typedef __int64 jlong; -#endif - -typedef signed char jbyte; - -#endif /* !_JAVASOFT_JNI_MD_H_ */ diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -26,6 +26,7 @@ #include #include "precompiled.hpp" +#include "jvm.h" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "interpreter/interpreter.hpp" @@ -38,7 +39,6 @@ #include "opto/compile.hpp" #include "opto/intrinsicnode.hpp" #include "opto/node.hpp" -#include "prims/jvm.h" #include "runtime/biasedLocking.hpp" #include "runtime/icache.hpp" #include "runtime/interfaceSupport.hpp" @@ -2929,6 +2929,105 @@ eor(crc, crc, tmp); } +void MacroAssembler::kernel_crc32_using_crc32(Register crc, Register buf, + Register len, Register tmp0, Register tmp1, Register tmp2, + Register tmp3) { + Label CRC_by64_loop, CRC_by4_loop, CRC_by1_loop, CRC_less64, CRC_by64_pre, CRC_by32_loop, CRC_less32, L_exit; + assert_different_registers(crc, buf, len, tmp0, tmp1, tmp2, tmp3); + + mvnw(crc, crc); + + subs(len, len, 128); + br(Assembler::GE, CRC_by64_pre); + BIND(CRC_less64); + adds(len, len, 128-32); + br(Assembler::GE, CRC_by32_loop); + BIND(CRC_less32); + adds(len, len, 32-4); + br(Assembler::GE, CRC_by4_loop); + adds(len, len, 4); + br(Assembler::GT, CRC_by1_loop); + b(L_exit); + + BIND(CRC_by32_loop); + ldp(tmp0, tmp1, Address(post(buf, 16))); + subs(len, len, 32); + crc32x(crc, crc, tmp0); + ldr(tmp2, Address(post(buf, 8))); + crc32x(crc, crc, tmp1); + ldr(tmp3, Address(post(buf, 8))); + crc32x(crc, crc, tmp2); + crc32x(crc, crc, tmp3); + br(Assembler::GE, CRC_by32_loop); + cmn(len, 32); + br(Assembler::NE, CRC_less32); + b(L_exit); + + BIND(CRC_by4_loop); + ldrw(tmp0, Address(post(buf, 4))); + subs(len, len, 4); + crc32w(crc, crc, tmp0); + br(Assembler::GE, CRC_by4_loop); + adds(len, len, 4); + br(Assembler::LE, L_exit); + BIND(CRC_by1_loop); + ldrb(tmp0, Address(post(buf, 1))); + subs(len, len, 1); + crc32b(crc, crc, tmp0); + br(Assembler::GT, CRC_by1_loop); + b(L_exit); + + BIND(CRC_by64_pre); + sub(buf, buf, 8); + ldp(tmp0, tmp1, Address(buf, 8)); + crc32x(crc, crc, tmp0); + ldr(tmp2, Address(buf, 24)); + crc32x(crc, crc, tmp1); + ldr(tmp3, Address(buf, 32)); + crc32x(crc, crc, tmp2); + ldr(tmp0, Address(buf, 40)); + crc32x(crc, crc, tmp3); + ldr(tmp1, Address(buf, 48)); + crc32x(crc, crc, tmp0); + ldr(tmp2, Address(buf, 56)); + crc32x(crc, crc, tmp1); + ldr(tmp3, Address(pre(buf, 64))); + + b(CRC_by64_loop); + + align(CodeEntryAlignment); + BIND(CRC_by64_loop); + subs(len, len, 64); + crc32x(crc, crc, tmp2); + ldr(tmp0, Address(buf, 8)); + crc32x(crc, crc, tmp3); + ldr(tmp1, Address(buf, 16)); + crc32x(crc, crc, tmp0); + ldr(tmp2, Address(buf, 24)); + crc32x(crc, crc, tmp1); + ldr(tmp3, Address(buf, 32)); + crc32x(crc, crc, tmp2); + ldr(tmp0, Address(buf, 40)); + crc32x(crc, crc, tmp3); + ldr(tmp1, Address(buf, 48)); + crc32x(crc, crc, tmp0); + ldr(tmp2, Address(buf, 56)); + crc32x(crc, crc, tmp1); + ldr(tmp3, Address(pre(buf, 64))); + br(Assembler::GE, CRC_by64_loop); + + // post-loop + crc32x(crc, crc, tmp2); + crc32x(crc, crc, tmp3); + + sub(len, len, 64); + add(buf, buf, 8); + cmn(len, 128); + br(Assembler::NE, CRC_less64); + BIND(L_exit); + mvnw(crc, crc); +} + /** * @param crc register containing existing CRC (32-bit) * @param buf register pointing to input byte buffer (byte*) @@ -2942,58 +3041,13 @@ Label L_by16, L_by16_loop, L_by4, L_by4_loop, L_by1, L_by1_loop, L_exit; unsigned long offset; - ornw(crc, zr, crc); - if (UseCRC32) { - Label CRC_by64_loop, CRC_by4_loop, CRC_by1_loop; - - subs(len, len, 64); - br(Assembler::GE, CRC_by64_loop); - adds(len, len, 64-4); - br(Assembler::GE, CRC_by4_loop); - adds(len, len, 4); - br(Assembler::GT, CRC_by1_loop); - b(L_exit); - - BIND(CRC_by4_loop); - ldrw(tmp, Address(post(buf, 4))); - subs(len, len, 4); - crc32w(crc, crc, tmp); - br(Assembler::GE, CRC_by4_loop); - adds(len, len, 4); - br(Assembler::LE, L_exit); - BIND(CRC_by1_loop); - ldrb(tmp, Address(post(buf, 1))); - subs(len, len, 1); - crc32b(crc, crc, tmp); - br(Assembler::GT, CRC_by1_loop); - b(L_exit); - - align(CodeEntryAlignment); - BIND(CRC_by64_loop); - subs(len, len, 64); - ldp(tmp, tmp3, Address(post(buf, 16))); - crc32x(crc, crc, tmp); - crc32x(crc, crc, tmp3); - ldp(tmp, tmp3, Address(post(buf, 16))); - crc32x(crc, crc, tmp); - crc32x(crc, crc, tmp3); - ldp(tmp, tmp3, Address(post(buf, 16))); - crc32x(crc, crc, tmp); - crc32x(crc, crc, tmp3); - ldp(tmp, tmp3, Address(post(buf, 16))); - crc32x(crc, crc, tmp); - crc32x(crc, crc, tmp3); - br(Assembler::GE, CRC_by64_loop); - adds(len, len, 64-4); - br(Assembler::GE, CRC_by4_loop); - adds(len, len, 4); - br(Assembler::GT, CRC_by1_loop); - BIND(L_exit); - ornw(crc, zr, crc); + kernel_crc32_using_crc32(crc, buf, len, table0, table1, table2, table3); return; } + mvnw(crc, crc); + adrp(table0, ExternalAddress(StubRoutines::crc_table_addr()), offset); if (offset) add(table0, table0, offset); add(table1, table0, 1*256*sizeof(juint)); @@ -3171,7 +3225,7 @@ adds(len, len, 4); br(Assembler::GT, L_by1_loop); BIND(L_exit); - ornw(crc, zr, crc); + mvnw(crc, crc); } /** diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -1261,6 +1261,9 @@ Register yz_idx1, Register yz_idx2, Register tmp, Register tmp3, Register tmp4, Register tmp7, Register product_hi); + void kernel_crc32_using_crc32(Register crc, Register buf, + Register len, Register tmp0, Register tmp1, Register tmp2, + Register tmp3); public: void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z, Register zlen, Register tmp1, Register tmp2, Register tmp3, diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -41,7 +41,7 @@ #ifdef COMPILER1 #include "c1/c1_Runtime1.hpp" #endif -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI #include "adfiles/ad_aarch64.hpp" #include "opto/runtime.hpp" #endif @@ -114,7 +114,7 @@ }; OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) { -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (save_vectors) { // Save upper half of vector registers int vect_words = 32 * 8 / wordSize; @@ -2688,7 +2688,7 @@ return 0; } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI //------------------------------generate_uncommon_trap_blob-------------------- void SharedRuntime::generate_uncommon_trap_blob() { // Allocate space for the code @@ -2894,7 +2894,7 @@ } #endif } -#endif // COMPILER2 +#endif // COMPILER2_OR_JVMCI //------------------------------generate_handler_blob------ @@ -3070,8 +3070,7 @@ return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true); } - -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame // //------------------------------generate_exception_blob--------------------------- @@ -3200,4 +3199,4 @@ // Set exception blob _exception_blob = ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1); } -#endif // COMPILER2 +#endif // COMPILER2_OR_JVMCI diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -4937,6 +4937,10 @@ StubRoutines::_crc_table_adr = (address)StubRoutines::aarch64::_crc_table; StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); } + + if (UseCRC32CIntrinsics) { + StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(); + } } void generate_all() { @@ -5014,10 +5018,6 @@ StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB"); } - if (UseCRC32CIntrinsics) { - StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(); - } - // generate Adler32 intrinsics code if (UseAdler32Intrinsics) { StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -472,7 +472,7 @@ #if INCLUDE_JVMCI // Check if we need to take lock at entry of synchronized method. This can // only occur on method entry so emit it only for vtos with step 0. - if (UseJVMCICompiler && state == vtos && step == 0) { + if (EnableJVMCI && state == vtos && step == 0) { Label L; __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); __ cbz(rscratch1, L); @@ -483,7 +483,7 @@ __ bind(L); } else { #ifdef ASSERT - if (UseJVMCICompiler) { + if (EnableJVMCI) { Label L; __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); __ cbz(rscratch1, L); @@ -984,9 +984,9 @@ __ adrp(tbl, ExternalAddress(StubRoutines::crc_table_addr()), offset); __ add(tbl, tbl, offset); - __ ornw(crc, zr, crc); // ~crc + __ mvnw(crc, crc); // ~crc __ update_byte_crc32(crc, val, tbl); - __ ornw(crc, zr, crc); // ~crc + __ mvnw(crc, crc); // ~crc // result in c_rarg0 @@ -1061,8 +1061,44 @@ return NULL; } -// Not supported +/** + * Method entry for intrinsic-candidate (non-native) methods: + * int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end) + * int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long buf, int off, int end) + * Unlike CRC32, CRC32C does not have any methods marked as native + * CRC32C also uses an "end" variable instead of the length variable CRC32 uses + */ address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { + if (UseCRC32Intrinsics) { + address entry = __ pc(); + + // Prepare jump to stub using parameters from the stack + const Register crc = c_rarg0; // initial crc + const Register buf = c_rarg1; // source java byte array address + const Register len = c_rarg2; // len argument to the kernel + + const Register end = len; // index of last element to process + const Register off = crc; // offset + + __ ldrw(end, Address(esp)); // int end + __ ldrw(off, Address(esp, wordSize)); // int offset + __ sub(len, end, off); + __ ldr(buf, Address(esp, 2*wordSize)); // byte[] buf | long buf + __ add(buf, buf, off); // + offset + if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { + __ ldrw(crc, Address(esp, 4*wordSize)); // long crc + } else { + __ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size + __ ldrw(crc, Address(esp, 3*wordSize)); // long crc + } + + __ andr(sp, r13, -16); // Restore the caller's SP + + // Jump to the stub. + __ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C())); + + return entry; + } return NULL; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/arm/compiledIC_arm.cpp --- a/src/hotspot/cpu/arm/compiledIC_arm.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -33,7 +33,7 @@ #include "runtime/safepoint.hpp" // ---------------------------------------------------------------------------- -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI #define __ _masm. // emit call stub, compiled java to interpreter address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) { @@ -89,7 +89,7 @@ int CompiledStaticCall::reloc_to_interp_stub() { return 10; // 4 in emit_to_interp_stub + 1 in Java_Static_Call } -#endif // COMPILER2 || JVMCI +#endif // COMPILER2_OR_JVMCI // size of C2 call stub, compiled java to interpretor int CompiledStaticCall::to_interp_stub_size() { diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/arm/interp_masm_arm.cpp --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "gc/shared/barrierSet.inline.hpp" #include "gc/shared/cardTableModRefBS.inline.hpp" #include "gc/shared/collectedHeap.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/arm/jni_arm.h --- a/src/hotspot/cpu/arm/jni_arm.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2008, 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 _JAVASOFT_JNI_MD_H_ -#define _JAVASOFT_JNI_MD_H_ - -// Note: please do not change these without also changing jni_md.h in the JDK -// repository -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) - #define JNIEXPORT __attribute__((externally_visible,visibility("default"))) - #define JNIIMPORT __attribute__((externally_visible,visibility("default"))) -#else - #define JNIEXPORT - #define JNIIMPORT -#endif - -#define JNICALL - -typedef int jint; -#if defined(_LP64) - typedef long jlong; -#else - typedef long long jlong; -#endif -typedef signed char jbyte; - -#endif /* !_JAVASOFT_JNI_MD_H_ */ diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/arm/methodHandles_arm.cpp --- a/src/hotspot/cpu/arm/methodHandles_arm.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/arm/methodHandles_arm.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -27,12 +27,12 @@ // Last synchronization: changeset f8c9417e3571 #include "precompiled.hpp" +#include "jvm.h" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #define __ _masm-> diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/arm/vm_version_arm_32.cpp --- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/java.hpp" #include "runtime/os.inline.hpp" #include "runtime/stubCodeGenerator.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/arm/vm_version_arm_64.cpp --- a/src/hotspot/cpu/arm/vm_version_arm_64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/arm/vm_version_arm_64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/java.hpp" #include "runtime/os.inline.hpp" #include "runtime/stubCodeGenerator.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/ppc/assembler_ppc.inline.hpp --- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -941,7 +941,7 @@ inline void Assembler::vpmsumw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b)); } // Vector Permute and Xor (introduced with Power 8) -inline void Assembler::vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); } +inline void Assembler::vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VPERMXOR_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); } // Transactional Memory instructions (introduced with Power 8) inline void Assembler::tbegin_() { emit_int32( TBEGIN_OPCODE | rc(1)); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/ppc/globals_ppc.hpp --- a/src/hotspot/cpu/ppc/globals_ppc.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/ppc/globals_ppc.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -69,7 +69,7 @@ define_pd_global(bool, RewriteBytecodes, true); define_pd_global(bool, RewriteFrequentPairs, true); -define_pd_global(bool, UseMembar, false); +define_pd_global(bool, UseMembar, true); define_pd_global(bool, PreserveFramePointer, false); diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/ppc/jni_ppc.h --- a/src/hotspot/cpu/ppc/jni_ppc.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2013 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. 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 CPU_PPC_VM_JNI_PPC_H -#define CPU_PPC_VM_JNI_PPC_H - -// Note: please do not change these without also changing jni_md.h in the JDK -// repository -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) - #define JNIEXPORT __attribute__((visibility("default"))) - #define JNIIMPORT __attribute__((visibility("default"))) -#else - #define JNIEXPORT - #define JNIIMPORT -#endif - -#define JNICALL - -typedef int jint; - -#if defined(_LP64) - typedef long jlong; -#else - typedef long long jlong; -#endif - -typedef signed char jbyte; - -#endif // CPU_PPC_VM_JNI_PPC_H diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/ppc/methodHandles_ppc.cpp --- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,12 +24,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #define __ _masm-> diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1469,8 +1469,31 @@ } // Save or restore single word registers. for (int i = 0; i < total_in_args; i++) { - // PPC64: pass ints as longs: must only deal with floats here. - if (in_regs[i].first()->is_FloatRegister()) { + if (in_regs[i].first()->is_Register()) { + int offset = slot * VMRegImpl::stack_slot_size; + // Value lives in an input register. Save it on stack. + switch (in_sig_bt[i]) { + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: + if (map != NULL) { + __ stw(in_regs[i].first()->as_Register(), offset, R1_SP); + } else { + __ lwa(in_regs[i].first()->as_Register(), offset, R1_SP); + } + slot++; + assert(slot <= stack_slots, "overflow (after INT or smaller stack slot)"); + break; + case T_ARRAY: + case T_LONG: + // handled above + break; + case T_OBJECT: + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_FloatRegister()) { if (in_sig_bt[i] == T_FLOAT) { int offset = slot * VMRegImpl::stack_slot_size; slot++; diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/ppc/vm_version_ppc.cpp --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,11 +24,11 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/disassembler.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" @@ -109,7 +109,8 @@ if (PowerArchitecturePPC64 >= 8) { if (FLAG_IS_DEFAULT(SuperwordUseVSX)) { - FLAG_SET_ERGO(bool, SuperwordUseVSX, true); + // TODO: Switch on when it works stable. Currently, MachSpillCopyNode::implementation code is missing. + //FLAG_SET_ERGO(bool, SuperwordUseVSX, true); } } else { if (SuperwordUseVSX) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp --- a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -277,7 +277,7 @@ length.set_instruction(x->length()); length.load_item(); } - if (needs_store_check) { + if (needs_store_check || x->check_boolean()) { value.load_item(); } else { value.load_for_store(x->elt_type()); @@ -327,11 +327,14 @@ // Needs GC write barriers. pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */, true /* do_load */, false /* patch */, NULL); - __ move(value.result(), array_addr, null_check_info); - // Seems to be a precise. + } + + LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info); + __ move(result, array_addr, null_check_info); + + if (obj_store) { + // Precise card mark post_barrier(LIR_OprFact::address(array_addr), value.result()); - } else { - __ move(value.result(), array_addr, null_check_info); } } diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/globals_s390.hpp --- a/src/hotspot/cpu/s390/globals_s390.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/globals_s390.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -71,7 +71,7 @@ define_pd_global(bool, RewriteBytecodes, true); define_pd_global(bool, RewriteFrequentPairs, true); -define_pd_global(bool, UseMembar, false); +define_pd_global(bool, UseMembar, true); define_pd_global(bool, PreserveFramePointer, false); diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/interp_masm_s390.cpp --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -843,6 +843,38 @@ verify_oop(Z_tos, state); } +void InterpreterMacroAssembler::narrow(Register result, Register ret_type) { + get_method(ret_type); + z_lg(ret_type, Address(ret_type, in_bytes(Method::const_offset()))); + z_lb(ret_type, Address(ret_type, in_bytes(ConstMethod::result_type_offset()))); + + Label notBool, notByte, notChar, done; + + // common case first + compareU32_and_branch(ret_type, T_INT, bcondEqual, done); + + compareU32_and_branch(ret_type, T_BOOLEAN, bcondNotEqual, notBool); + z_nilf(result, 0x1); + z_bru(done); + + bind(notBool); + compareU32_and_branch(ret_type, T_BYTE, bcondNotEqual, notByte); + z_lbr(result, result); + z_bru(done); + + bind(notByte); + compareU32_and_branch(ret_type, T_CHAR, bcondNotEqual, notChar); + z_nilf(result, 0xffff); + z_bru(done); + + bind(notChar); + // compareU32_and_branch(ret_type, T_SHORT, bcondNotEqual, notShort); + z_lhr(result, result); + + // Nothing to do for T_INT + bind(done); +} + // remove activation // // Unlock the receiver if this is a synchronized method. diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/interp_masm_s390.hpp --- a/src/hotspot/cpu/s390/interp_masm_s390.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/interp_masm_s390.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -86,6 +86,8 @@ void dispatch_next_noverify_oop(TosState state, int step = 0); void dispatch_via(TosState state, address* table); + void narrow(Register result, Register ret_type); + // Jump to an invoked target. void prepare_to_jump_from_interpreted(Register method); void jump_from_interpreted(Register method, Register temp); diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/jni_s390.h --- a/src/hotspot/cpu/s390/jni_s390.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 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 _JAVASOFT_JNI_MD_H_ -#define _JAVASOFT_JNI_MD_H_ - -#if defined(__GNUC__) && (__GNUC__ >= 4) - #define JNIEXPORT __attribute__((visibility("default"))) - #define JNIIMPORT __attribute__((visibility("default"))) -#else - #define JNIEXPORT - #define JNIIMPORT -#endif - -#define JNICALL - -typedef int jint; - -typedef long int jlong; - -typedef signed char jbyte; - -#endif // _JAVASOFT_JNI_MD_H_ diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/methodHandles_s390.cpp --- a/src/hotspot/cpu/s390/methodHandles_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,12 +24,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #ifdef PRODUCT diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/sharedRuntime_s390.cpp --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1309,15 +1309,42 @@ } } else { __ z_lg(reg, offset, Z_SP); - slot += VMRegImpl::slots_per_word; - assert(slot <= stack_slots, "overflow (after LONG/ARRAY stack slot)"); } + slot += VMRegImpl::slots_per_word; + assert(slot <= stack_slots, "overflow (after LONG/ARRAY stack slot)"); } } // Save or restore single word registers. for (int i = 0; i < total_in_args; i++) { - if (in_regs[i].first()->is_FloatRegister()) { + if (in_regs[i].first()->is_Register()) { + int offset = slot * VMRegImpl::stack_slot_size; + // Value lives in an input register. Save it on stack. + switch (in_sig_bt[i]) { + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: { + const Register reg = in_regs[i].first()->as_Register(); + Address stackaddr(Z_SP, offset); + if (map != NULL) { + __ z_st(reg, stackaddr); + } else { + __ z_lgf(reg, stackaddr); + } + slot++; + assert(slot <= stack_slots, "overflow (after INT or smaller stack slot)"); + break; + } + case T_ARRAY: + case T_LONG: + // handled above + break; + case T_OBJECT: + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_FloatRegister()) { if (in_sig_bt[i] == T_FLOAT) { int offset = slot * VMRegImpl::stack_slot_size; slot++; @@ -1908,7 +1935,7 @@ case T_ARRAY: if (is_critical_native) { int body_arg = cix; - cix -= 2; // Point to length arg. + cix -= 1; // Point to length arg. unpack_array_argument(masm, in_regs[jix], in_elem_bt[jix], out_regs[body_arg], out_regs[cix], stack_slots); break; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2377,6 +2377,12 @@ __ store_const(Address(RjvmtiState, JvmtiThreadState::earlyret_state_offset()), JvmtiThreadState::earlyret_inactive, 4, 4, Z_R0_scratch); + if (state == itos) { + // Narrow result if state is itos but result type is smaller. + // Need to narrow in the return bytecode rather than in generate_return_entry + // since compiled code callers expect the result to already be narrowed. + __ narrow(Z_tos, Z_tmp_1); /* fall through */ + } __ remove_activation(state, Z_tmp_1, // retaddr false, // throw_monitor_exception diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/templateTable_s390.cpp --- a/src/hotspot/cpu/s390/templateTable_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1174,8 +1174,20 @@ __ pop_i(Z_ARG3); __ pop_ptr(Z_tmp_2); // Z_tos : value - // Z_ARG3 : index + // Z_ARG3 : index // Z_tmp_2 : array + + // Need to check whether array is boolean or byte + // since both types share the bastore bytecode. + __ load_klass(Z_tmp_1, Z_tmp_2); + __ z_llgf(Z_tmp_1, Address(Z_tmp_1, Klass::layout_helper_offset())); + __ z_tmll(Z_tmp_1, Klass::layout_helper_boolean_diffbit()); + Label L_skip; + __ z_bfalse(L_skip); + // if it is a T_BOOLEAN array, mask the stored value to 0/1 + __ z_nilf(Z_tos, 0x1); + __ bind(L_skip); + // No index shift necessary - pass 0. index_check(Z_tmp_2, Z_ARG3, 0); // Prefer index in Z_ARG3. __ z_stc(Z_tos, @@ -2321,6 +2333,13 @@ __ bind(skip_register_finalizer); } + if (state == itos) { + // Narrow result if state is itos but result type is smaller. + // Need to narrow in the return bytecode rather than in generate_return_entry + // since compiled code callers expect the result to already be narrowed. + __ narrow(Z_tos, Z_tmp_1); /* fall through */ + } + __ remove_activation(state, Z_R14); __ z_br(Z_R14); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/s390/vm_version_s390.cpp --- a/src/hotspot/cpu/s390/vm_version_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,11 +24,11 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/assembler.inline.hpp" #include "compiler/disassembler.hpp" #include "code/compiledIC.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/java.hpp" #include "runtime/stubCodeGenerator.hpp" #include "vm_version_s390.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/sparc/globals_sparc.hpp --- a/src/hotspot/cpu/sparc/globals_sparc.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/sparc/globals_sparc.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -74,7 +74,7 @@ define_pd_global(bool, RewriteBytecodes, true); define_pd_global(bool, RewriteFrequentPairs, true); -define_pd_global(bool, UseMembar, false); +define_pd_global(bool, UseMembar, true); define_pd_global(bool, PreserveFramePointer, false); diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/sparc/jni_sparc.h --- a/src/hotspot/cpu/sparc/jni_sparc.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 1997, 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. - */ - -// Note: please do not change these without also changing jni_md.h in the JDK -// repository -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) - #define JNIEXPORT __attribute__((visibility("default"))) - #define JNIIMPORT __attribute__((visibility("default"))) -#else - #define JNIEXPORT - #define JNIIMPORT -#endif -#define JNICALL - -typedef int jint; - -typedef long jlong; - -typedef signed char jbyte; diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/sparc/macroAssembler_sparc.cpp --- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.inline.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/cardTableModRefBS.hpp" @@ -31,7 +32,6 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/klass.inline.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/interfaceSupport.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/sparc/methodHandles_sparc.cpp --- a/src/hotspot/cpu/sparc/methodHandles_sparc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/sparc/methodHandles_sparc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,13 +23,13 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interp_masm.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #define __ _masm-> diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp --- a/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -319,7 +319,7 @@ #if INCLUDE_JVMCI // Check if we need to take lock at entry of synchronized method. This can // only occur on method entry so emit it only for vtos with step 0. - if (UseJVMCICompiler && state == vtos && step == 0) { + if (EnableJVMCI && state == vtos && step == 0) { Label L; Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset()); __ ldbool(pending_monitor_enter_addr, Gtemp); // Load if pending monitor enter @@ -331,7 +331,7 @@ __ bind(L); } else { #ifdef ASSERT - if (UseJVMCICompiler) { + if (EnableJVMCI) { Label L; Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset()); __ ldbool(pending_monitor_enter_addr, Gtemp); // Load if pending monitor enter diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/sparc/vm_version_sparc.cpp --- a/src/hotspot/cpu/sparc/vm_version_sparc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/sparc/vm_version_sparc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,11 +23,11 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.inline.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/frame_x86.cpp --- a/src/hotspot/cpu/x86/frame_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/frame_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -436,11 +436,11 @@ // This is the sp before any possible extension (adapter/locals). intptr_t* unextended_sp = interpreter_frame_sender_sp(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (map->update_map()) { update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI return frame(sender_sp, unextended_sp, link(), sender_pc()); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/globals_x86.hpp --- a/src/hotspot/cpu/x86/globals_x86.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/globals_x86.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -46,11 +46,11 @@ // the the vep is aligned at CodeEntryAlignment whereas c2 only aligns // the uep and the vep doesn't get real alignment but just slops on by // only assured that the entry instruction meets the 5 byte size requirement. -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI define_pd_global(intx, CodeEntryAlignment, 32); #else define_pd_global(intx, CodeEntryAlignment, 16); -#endif // COMPILER2 +#endif // COMPILER2_OR_JVMCI define_pd_global(intx, OptoLoopAlignment, 16); define_pd_global(intx, InlineFrequencyCount, 100); define_pd_global(intx, InlineSmallCode, 1000); @@ -84,11 +84,7 @@ define_pd_global(bool, RewriteBytecodes, true); define_pd_global(bool, RewriteFrequentPairs, true); -#ifdef _ALLBSD_SOURCE define_pd_global(bool, UseMembar, true); -#else -define_pd_global(bool, UseMembar, false); -#endif // GC Ergo Flags define_pd_global(size_t, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/jni_x86.h --- a/src/hotspot/cpu/x86/jni_x86.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 1997, 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 _JAVASOFT_JNI_MD_H_ -#define _JAVASOFT_JNI_MD_H_ - -#if defined(_WIN32) - #define JNIEXPORT __declspec(dllexport) - #define JNIIMPORT __declspec(dllimport) - #define JNICALL __stdcall - - typedef int jint; - typedef __int64 jlong; -#else - -// Note: please do not change these without also changing jni_md.h in the JDK -// repository -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) - #define JNIEXPORT __attribute__((visibility("default"))) - #define JNIIMPORT __attribute__((visibility("default"))) -#else - #define JNIEXPORT - #define JNIIMPORT -#endif - - #define JNICALL - typedef int jint; -#if defined(_LP64) - typedef long jlong; -#else - typedef long long jlong; -#endif - -#endif - -typedef signed char jbyte; - -#endif /* !_JAVASOFT_JNI_MD_H_ */ diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/macroAssembler_x86.cpp --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "compiler/disassembler.hpp" @@ -32,7 +33,6 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/klass.inline.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/interfaceSupport.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/methodHandles_x86.cpp --- a/src/hotspot/cpu/x86/methodHandles_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,13 +23,13 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #define __ _masm-> diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -151,7 +151,7 @@ if (UseAVX < 3) { num_xmm_regs = num_xmm_regs/2; } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (save_vectors) { assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX"); assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported"); @@ -260,7 +260,7 @@ } } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (save_vectors) { off = ymm0_off; int delta = ymm1_off - off; @@ -270,7 +270,7 @@ off += delta; } } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI // %%% These should all be a waste but we'll keep things as they were for now if (true) { @@ -323,7 +323,7 @@ __ addptr(rsp, frame::arg_reg_save_area_bytes); } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (restore_vectors) { assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX"); assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported"); @@ -2183,7 +2183,7 @@ // critical natives they are offset down. GrowableArray arg_order(2 * total_in_args); VMRegPair tmp_vmreg; - tmp_vmreg.set1(rbx->as_VMReg()); + tmp_vmreg.set2(rbx->as_VMReg()); if (!is_critical_native) { for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/stubGenerator_x86_32.cpp --- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -3433,6 +3433,8 @@ } address generate_libmExp() { + StubCodeMark mark(this, "StubRoutines", "libmExp"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3458,6 +3460,8 @@ } address generate_libmLog() { + StubCodeMark mark(this, "StubRoutines", "libmLog"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3483,6 +3487,8 @@ } address generate_libmLog10() { + StubCodeMark mark(this, "StubRoutines", "libmLog10"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3508,6 +3514,8 @@ } address generate_libmPow() { + StubCodeMark mark(this, "StubRoutines", "libmPow"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3533,6 +3541,8 @@ } address generate_libm_reduce_pi04l() { + StubCodeMark mark(this, "StubRoutines", "libm_reduce_pi04l"); + address start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -3543,6 +3553,8 @@ } address generate_libm_sin_cos_huge() { + StubCodeMark mark(this, "StubRoutines", "libm_sin_cos_huge"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3556,6 +3568,8 @@ } address generate_libmSin() { + StubCodeMark mark(this, "StubRoutines", "libmSin"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3579,6 +3593,8 @@ } address generate_libmCos() { + StubCodeMark mark(this, "StubRoutines", "libmCos"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3604,6 +3620,8 @@ } address generate_libm_tan_cot_huge() { + StubCodeMark mark(this, "StubRoutines", "libm_tan_cot_huge"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -3617,6 +3635,8 @@ } address generate_libmTan() { + StubCodeMark mark(this, "StubRoutines", "libmTan"); + address start = __ pc(); const XMMRegister x0 = xmm0; diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/stubGenerator_x86_64.cpp --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -4619,6 +4619,8 @@ } address generate_libmExp() { + StubCodeMark mark(this, "StubRoutines", "libmExp"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -4646,6 +4648,8 @@ } address generate_libmLog() { + StubCodeMark mark(this, "StubRoutines", "libmLog"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -4674,6 +4678,8 @@ } address generate_libmLog10() { + StubCodeMark mark(this, "StubRoutines", "libmLog10"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -4701,6 +4707,8 @@ } address generate_libmPow() { + StubCodeMark mark(this, "StubRoutines", "libmPow"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -4731,6 +4739,8 @@ } address generate_libmSin() { + StubCodeMark mark(this, "StubRoutines", "libmSin"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -4770,6 +4780,8 @@ } address generate_libmCos() { + StubCodeMark mark(this, "StubRoutines", "libmCos"); + address start = __ pc(); const XMMRegister x0 = xmm0; @@ -4809,6 +4821,8 @@ } address generate_libmTan() { + StubCodeMark mark(this, "StubRoutines", "libmTan"); + address start = __ pc(); const XMMRegister x0 = xmm0; diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -257,7 +257,7 @@ #if INCLUDE_JVMCI // Check if we need to take lock at entry of synchronized method. This can // only occur on method entry so emit it only for vtos with step 0. - if ((UseJVMCICompiler || UseAOT) && state == vtos && step == 0) { + if ((EnableJVMCI || UseAOT) && state == vtos && step == 0) { Label L; __ cmpb(Address(thread, JavaThread::pending_monitorenter_offset()), 0); __ jcc(Assembler::zero, L); @@ -270,7 +270,7 @@ __ bind(L); } else { #ifdef ASSERT - if (UseJVMCICompiler) { + if (EnableJVMCI) { Label L; __ cmpb(Address(r15_thread, JavaThread::pending_monitorenter_offset()), 0); __ jccb(Assembler::zero, L); diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/x86/vm_version_x86.cpp --- a/src/hotspot/cpu/x86/vm_version_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" @@ -944,7 +944,7 @@ } } #endif -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (MaxVectorSize > 0) { if (!is_power_of_2(MaxVectorSize)) { warning("MaxVectorSize must be a power of 2"); @@ -996,7 +996,7 @@ } #endif // COMPILER2 && ASSERT } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI #ifdef COMPILER2 #ifdef _LP64 diff -r 18e431209168 -r 76d033c9908f src/hotspot/cpu/zero/jni_zero.h --- a/src/hotspot/cpu/zero/jni_zero.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2009 Red Hat, Inc. - * 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. - */ - - - -// Note: please do not change these without also changing jni_md.h in the JDK -// repository -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) - #define JNIEXPORT __attribute__((visibility("default"))) - #define JNIIMPORT __attribute__((visibility("default"))) -#else - #define JNIEXPORT - #define JNIIMPORT -#endif -#define JNICALL - -typedef int jint; -typedef signed char jbyte; - -#ifdef _LP64 -typedef long jlong; -#else -typedef long long jlong; -#endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/aix/jvm_aix.cpp --- a/src/hotspot/os/aix/jvm_aix.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/aix/jvm_aix.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,7 +24,7 @@ */ #include "precompiled.hpp" -#include "prims/jvm.h" +#include "jvm.h" #include "runtime/interfaceSupport.hpp" #include "runtime/osThread.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/aix/jvm_aix.h --- a/src/hotspot/os/aix/jvm_aix.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2013 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 OS_AIX_VM_JVM_AIX_H -#define OS_AIX_VM_JVM_AIX_H - -// HotSpot integration note: -// -// This is derived from the JDK classic file: -// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22) -// All local includes have been commented out. - -#ifndef JVM_MD_H -#define JVM_MD_H - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -#include /* For DIR */ - -// Must redefine NULL because the macro gets redefined to int 0 -// by dirent.h. This redefinition is included later then the standard definition in -// globalDefinitions_.hpp and leads to assertions in the VM initialization. -// We definitely need NULL to have the same lengh as an address pointer. -#ifdef _LP64 -#undef NULL -#define NULL 0L -#else -#ifndef NULL -#define NULL 0 -#endif -#endif - -#include /* For MAXPATHLEN */ -#include /* For socklen_t */ -#include /* For F_OK, R_OK, W_OK */ - -#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} - -#define JNI_LIB_PREFIX "lib" -#define JNI_LIB_SUFFIX ".so" - -#define JVM_MAXPATHLEN MAXPATHLEN - -#define JVM_R_OK R_OK -#define JVM_W_OK W_OK -#define JVM_X_OK X_OK -#define JVM_F_OK F_OK - -/* - * File I/O - */ - -#include -#include -#include -#include - -/* O Flags */ - -#define JVM_O_RDONLY O_RDONLY -#define JVM_O_WRONLY O_WRONLY -#define JVM_O_RDWR O_RDWR -#define JVM_O_O_APPEND O_APPEND -#define JVM_O_EXCL O_EXCL -#define JVM_O_CREAT O_CREAT - -/* Signal definitions */ - -#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ -#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ -#define SHUTDOWN2_SIGNAL SIGINT -#define SHUTDOWN3_SIGNAL SIGTERM - -#endif /* JVM_MD_H */ - -#endif // OS_AIX_VM_JVM_AIX_H diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/aix/os_aix.cpp --- a/src/hotspot/os/aix/os_aix.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/aix/os_aix.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -28,6 +28,7 @@ #pragma alloca // no precompiled headers +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -35,7 +36,6 @@ #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_aix.h" #include "logging/log.hpp" #include "libo4.hpp" #include "libperfstat_aix.hpp" @@ -49,7 +49,6 @@ #include "os_share_aix.hpp" #include "porting_aix.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" @@ -3249,7 +3248,7 @@ } // ReduceSignalUsage allows the user to override these handlers - // see comments at the very top and jvm_solaris.h + // see comments at the very top and jvm_md.h if (!ReduceSignalUsage) { DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/bsd/decoder_machO.cpp --- a/src/hotspot/os/bsd/decoder_machO.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/bsd/decoder_machO.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -25,7 +25,7 @@ #include "precompiled.hpp" #ifdef __APPLE__ -#include "prims/jvm.h" +#include "jvm.h" #include "decoder_machO.hpp" #include diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/bsd/jvm_bsd.cpp --- a/src/hotspot/os/bsd/jvm_bsd.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/bsd/jvm_bsd.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "prims/jvm.h" +#include "jvm.h" #include "runtime/interfaceSupport.hpp" #include "runtime/osThread.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/bsd/jvm_bsd.h --- a/src/hotspot/os/bsd/jvm_bsd.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -/* - * Copyright (c) 1999, 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. - * - * 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_BSD_VM_JVM_BSD_H -#define OS_BSD_VM_JVM_BSD_H - -/* -// HotSpot integration note: -// -// This is derived from the JDK classic file: -// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22) -// All local includes have been commented out. -*/ - -#ifndef JVM_MD_H -#define JVM_MD_H - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -#include /* For DIR */ -#include /* For MAXPATHLEN */ -#include /* For socklen_t */ -#include /* For F_OK, R_OK, W_OK */ - -#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} - -#define JNI_LIB_PREFIX "lib" -#ifdef __APPLE__ -#define JNI_LIB_SUFFIX ".dylib" -#else -#define JNI_LIB_SUFFIX ".so" -#endif - -// Hack: MAXPATHLEN is 4095 on some Bsd and 4096 on others. This may -// cause problems if JVM and the rest of JDK are built on different -// Bsd releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1, -// so buffers declared in VM are always >= 4096. -#define JVM_MAXPATHLEN MAXPATHLEN + 1 - -#define JVM_R_OK R_OK -#define JVM_W_OK W_OK -#define JVM_X_OK X_OK -#define JVM_F_OK F_OK - -/* - * File I/O - */ - -#include -#include -#include -#include - -/* O Flags */ - -#define JVM_O_RDONLY O_RDONLY -#define JVM_O_WRONLY O_WRONLY -#define JVM_O_RDWR O_RDWR -#define JVM_O_O_APPEND O_APPEND -#define JVM_O_EXCL O_EXCL -#define JVM_O_CREAT O_CREAT - -/* Signal definitions */ - -#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ -#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ -#define SHUTDOWN2_SIGNAL SIGINT -#define SHUTDOWN3_SIGNAL SIGTERM - -#ifndef SIGRTMIN -#ifdef __OpenBSD__ -#define SIGRTMIN 1 -#else -#define SIGRTMIN 33 -#endif -#endif -#ifndef SIGRTMAX -#ifdef __OpenBSD__ -#define SIGRTMAX 31 -#else -#define SIGRTMAX 63 -#endif -#endif -#endif /* JVM_MD_H */ - -#endif // OS_BSD_VM_JVM_BSD_H diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/bsd/os_bsd.cpp --- a/src/hotspot/os/bsd/os_bsd.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/bsd/os_bsd.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -31,7 +32,6 @@ #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_bsd.h" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" @@ -39,7 +39,6 @@ #include "os_bsd.inline.hpp" #include "os_share_bsd.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" @@ -3240,7 +3239,7 @@ // ReduceSignalUsage allows the user to override these handlers - // see comments at the very top and jvm_solaris.h + // see comments at the very top and jvm_md.h if (!ReduceSignalUsage) { DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/linux/decoder_linux.cpp --- a/src/hotspot/os/linux/decoder_linux.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/linux/decoder_linux.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,7 +22,7 @@ * */ -#include "prims/jvm.h" +#include "jvm.h" #include "utilities/decoder_elf.hpp" #include diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/linux/jvm_linux.cpp --- a/src/hotspot/os/linux/jvm_linux.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/linux/jvm_linux.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "prims/jvm.h" +#include "jvm.h" #include "runtime/interfaceSupport.hpp" #include "runtime/osThread.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/linux/jvm_linux.h --- a/src/hotspot/os/linux/jvm_linux.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 1999, 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. - * - * 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_LINUX_VM_JVM_LINUX_H -#define OS_LINUX_VM_JVM_LINUX_H - -/* -// HotSpot integration note: -// -// This is derived from the JDK classic file: -// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22) -// All local includes have been commented out. -*/ - -#ifndef JVM_MD_H -#define JVM_MD_H - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -#include /* For DIR */ -#include /* For MAXPATHLEN */ -#include /* For socklen_t */ -#include /* For F_OK, R_OK, W_OK */ - -#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} - -#define JNI_LIB_PREFIX "lib" -#define JNI_LIB_SUFFIX ".so" - -// Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may -// cause problems if JVM and the rest of JDK are built on different -// Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1, -// so buffers declared in VM are always >= 4096. -#define JVM_MAXPATHLEN MAXPATHLEN + 1 - -#define JVM_R_OK R_OK -#define JVM_W_OK W_OK -#define JVM_X_OK X_OK -#define JVM_F_OK F_OK - -/* - * File I/O - */ - -#include -#include -#include -#include - -/* O Flags */ - -#define JVM_O_RDONLY O_RDONLY -#define JVM_O_WRONLY O_WRONLY -#define JVM_O_RDWR O_RDWR -#define JVM_O_O_APPEND O_APPEND -#define JVM_O_EXCL O_EXCL -#define JVM_O_CREAT O_CREAT - -/* Signal definitions */ - -#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ -#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ -#define SHUTDOWN2_SIGNAL SIGINT -#define SHUTDOWN3_SIGNAL SIGTERM - -#endif /* JVM_MD_H */ - -#endif // OS_LINUX_VM_JVM_LINUX_H diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/linux/os_linux.cpp --- a/src/hotspot/os/linux/os_linux.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/linux/os_linux.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -31,7 +32,6 @@ #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" @@ -39,7 +39,6 @@ #include "os_linux.inline.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" @@ -4664,7 +4663,7 @@ #endif // ReduceSignalUsage allows the user to override these handlers - // see comments at the very top and jvm_solaris.h + // see comments at the very top and jvm_md.h if (!ReduceSignalUsage) { DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/posix/os_posix.cpp --- a/src/hotspot/os/posix/os_posix.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/posix/os_posix.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,8 +22,8 @@ * */ +#include "jvm.h" #include "utilities/globalDefinitions.hpp" -#include "prims/jvm.h" #include "runtime/frame.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/os.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/solaris/jvm_solaris.cpp --- a/src/hotspot/os/solaris/jvm_solaris.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/solaris/jvm_solaris.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "prims/jvm.h" +#include "jvm.h" #include "runtime/interfaceSupport.hpp" #include "runtime/osThread.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/solaris/jvm_solaris.h --- a/src/hotspot/os/solaris/jvm_solaris.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 1998, 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. - * - * 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_SOLARIS_VM_JVM_SOLARIS_H -#define OS_SOLARIS_VM_JVM_SOLARIS_H - -/* -// HotSpot integration note: -// -// This is derived from the JDK classic file: -// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22) -// All local includes have been commented out. -*/ - -#ifndef JVM_MD_H -#define JVM_MD_H - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -#include /* For DIR */ -#include /* For MAXPATHLEN */ -#include /* For socklen_t */ -#include /* For F_OK, R_OK, W_OK */ -#include /* for intptr_t types (64 Bit cleanliness) */ - -#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} - -#define JNI_LIB_PREFIX "lib" -#define JNI_LIB_SUFFIX ".so" - -#define JVM_MAXPATHLEN MAXPATHLEN - -#define JVM_R_OK R_OK -#define JVM_W_OK W_OK -#define JVM_X_OK X_OK -#define JVM_F_OK F_OK - -/* - * File I/O - */ - -#include -#include -#include -#include - -/* O Flags */ - -#define JVM_O_RDONLY O_RDONLY -#define JVM_O_WRONLY O_WRONLY -#define JVM_O_RDWR O_RDWR -#define JVM_O_O_APPEND O_APPEND -#define JVM_O_EXCL O_EXCL -#define JVM_O_CREAT O_CREAT - -/* Signal definitions */ - -#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ -#define ASYNC_SIGNAL SIGJVM2 /* Event-based suspend/resume support */ -#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ -#define SHUTDOWN2_SIGNAL SIGINT -#define SHUTDOWN3_SIGNAL SIGTERM - -/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */ -#define JSIG_VERSION_1_4_1 0x30140100 - -#endif /* JVM_MD_H */ - -#endif // OS_SOLARIS_VM_JVM_SOLARIS_H diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/solaris/os_solaris.cpp --- a/src/hotspot/os/solaris/os_solaris.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/solaris/os_solaris.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -31,7 +32,6 @@ #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_solaris.h" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" @@ -39,7 +39,6 @@ #include "os_share_solaris.hpp" #include "os_solaris.inline.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/windows/jvm_windows.cpp --- a/src/hotspot/os/windows/jvm_windows.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/windows/jvm_windows.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "prims/jvm.h" +#include "jvm.h" #include "runtime/interfaceSupport.hpp" #include "runtime/osThread.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/windows/jvm_windows.h --- a/src/hotspot/os/windows/jvm_windows.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_WINDOWS_VM_JVM_WINDOWS_H -#define OS_WINDOWS_VM_JVM_WINDOWS_H - -#ifndef _JAVASOFT_JVM_MD_H_ -#define _JAVASOFT_JVM_MD_H_ - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -// JDK7 requires VS2010 -#if _MSC_VER >= 1600 -// JDK7 minimum platform requirement: Windows XP -#if _WIN32_WINNT < 0x0501 -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 -#endif -#endif - -#include - -#include -#include - -typedef int socklen_t; - -#define JNI_ONLOAD_SYMBOLS {"_JNI_OnLoad@8", "JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"_JNI_OnUnload@8", "JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"_JVM_OnLoad@12", "JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"_Agent_OnLoad@12", "Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"_Agent_OnUnload@4", "Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"_Agent_OnAttach@12", "Agent_OnAttach"} - -#define JNI_LIB_PREFIX "" -#define JNI_LIB_SUFFIX ".dll" - -struct dirent { - char d_name[MAX_PATH]; -}; - -typedef struct { - struct dirent dirent; - char *path; - HANDLE handle; - WIN32_FIND_DATA find_data; -} DIR; - -#include - -#define JVM_MAXPATHLEN _MAX_PATH - -#define JVM_R_OK 4 -#define JVM_W_OK 2 -#define JVM_X_OK 1 -#define JVM_F_OK 0 - -#ifdef __cplusplus -extern "C" { -#endif - -JNIEXPORT void * JNICALL -JVM_GetThreadInterruptEvent(); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -/* - * File I/O - */ - -#include - -/* O Flags */ - -#define JVM_O_RDONLY O_RDONLY -#define JVM_O_WRONLY O_WRONLY -#define JVM_O_RDWR O_RDWR -#define JVM_O_O_APPEND O_APPEND -#define JVM_O_EXCL O_EXCL -#define JVM_O_CREAT O_CREAT - -/* Signals */ - -#define JVM_SIGINT SIGINT -#define JVM_SIGTERM SIGTERM - -#define SHUTDOWN1_SIGNAL SIGINT /* Shutdown Hooks support. */ -#define SHUTDOWN2_SIGNAL SIGTERM - -#endif /* !_JAVASOFT_JVM_MD_H_ */ - -#endif // OS_WINDOWS_VM_JVM_WINDOWS_H diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/windows/os_windows.cpp --- a/src/hotspot/os/windows/os_windows.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/windows/os_windows.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -26,6 +26,7 @@ #define _WIN32_WINNT 0x0600 // no precompiled headers +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -34,7 +35,6 @@ #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_windows.h" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" @@ -42,7 +42,6 @@ #include "os_share_windows.hpp" #include "os_windows.inline.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" @@ -100,6 +99,7 @@ #include // For os::dll_address_to_function_name // for enumerating dll libraries #include +#include // for timer info max values which include all bits #define ALL_64_BITS CONST64(-1) @@ -3656,7 +3656,7 @@ static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; static CRITICAL_SECTION crit_sect; - static volatile jint process_exiting = 0; + static volatile DWORD process_exiting = 0; int i, j; DWORD res; HANDLE hproc, hthr; @@ -3675,7 +3675,7 @@ if (what != EPT_THREAD) { // Atomically set process_exiting before the critical section // to increase the visibility between racing threads. - Atomic::cmpxchg((jint)GetCurrentThreadId(), &process_exiting, 0); + Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0); } EnterCriticalSection(&crit_sect); @@ -3793,7 +3793,7 @@ if (!registered && OrderAccess::load_acquire(&process_exiting) != 0 && - process_exiting != (jint)GetCurrentThreadId()) { + process_exiting != GetCurrentThreadId()) { // Some other thread is about to call exit(), so we don't let // the current unregistered thread proceed to exit() or _endthreadex() while (true) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/os/windows/threadCritical_windows.cpp --- a/src/hotspot/os/windows/threadCritical_windows.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os/windows/threadCritical_windows.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -36,7 +36,7 @@ // static bool initialized = false; -static volatile jint lock_count = -1; +static volatile int lock_count = -1; static HANDLE lock_event; static DWORD lock_owner = -1; diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,6 +24,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/assembler.inline.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -32,12 +33,10 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_aix.h" #include "memory/allocation.inline.hpp" #include "nativeInst_ppc.hpp" #include "os_share_aix.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "porting_aix.hpp" #include "runtime/arguments.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -31,11 +32,9 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_bsd.h" #include "memory/allocation.inline.hpp" #include "os_share_bsd.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp --- a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -73,7 +73,7 @@ frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { -#if defined(COMPILER2) || INCLUDE_JVMCI +#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()); if (!ret_frame2.safe_for_sender(jt)) { @@ -84,7 +84,7 @@ #else // nothing else to try if the frame isn't good return false; -#endif /* COMPILER2 || INCLUDE_JVMCI */ +#endif // COMPILER2_OR_JVMCI } *fr_addr = ret_frame; return true; diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp --- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -29,6 +29,7 @@ #endif // no precompiled headers +#include "jvm.h" #include "assembler_zero.inline.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -36,12 +37,10 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_bsd.h" #include "memory/allocation.inline.hpp" #include "nativeInst_zero.hpp" #include "os_share_bsd.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,6 +24,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -33,11 +34,9 @@ #include "code/vtableStubs.hpp" #include "code/nativeInst.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "memory/allocation.inline.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" @@ -234,8 +233,17 @@ } intptr_t* _get_previous_fp() { - register intptr_t **ebp __asm__ (SPELL_REG_FP); - return (intptr_t*) *ebp; // we want what it points to. + register intptr_t **fp __asm__ (SPELL_REG_FP); + + // fp is for this frame (_get_previous_fp). We want the fp for the + // caller of os::current_frame*(), so go up two frames. However, for + // optimized builds, _get_previous_fp() will be inlined, so only go + // up 1 frame in that case. + #ifdef _NMT_NOINLINE_ + return **(intptr_t***)fp; + #else + return *fp; + #endif } diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "assembler_arm.inline.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -30,12 +31,10 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "memory/allocation.inline.hpp" #include "nativeInst_arm.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,6 +24,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/assembler.inline.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -32,12 +33,10 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "memory/allocation.inline.hpp" #include "nativeInst_ppc.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -26,6 +26,7 @@ // This file is organized as os_linux_x86.cpp. // no precompiled headers +#include "jvm.h" #include "asm/assembler.inline.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -35,12 +36,10 @@ #include "code/vtableStubs.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "memory/allocation.inline.hpp" #include "nativeInst_s390.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp --- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -31,12 +32,10 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "memory/allocation.inline.hpp" #include "nativeInst_sparc.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_sparc/vm_version_linux_sparc.cpp --- a/src/hotspot/os_cpu/linux_sparc/vm_version_linux_sparc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_sparc/vm_version_linux_sparc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -27,58 +27,326 @@ #include "runtime/os.hpp" #include "vm_version_sparc.hpp" -static bool cpuinfo_field_contains(const char* field, const char* value) { - char line[1024]; - bool rv = false; + +#define CPUINFO_LINE_SIZE 1024 + + +class CPUinfo { +public: + CPUinfo(const char* field) : _string(NULL) { + + char line[CPUINFO_LINE_SIZE]; + FILE* fp = fopen("/proc/cpuinfo", "r"); - FILE* fp = fopen("/proc/cpuinfo", "r"); - if (fp == NULL) { - return rv; - } + if (fp != NULL) { + while (fgets(line, sizeof(line), fp) != NULL) { + assert(strlen(line) < sizeof(line) - 1, + "buffer too small (%d)", CPUINFO_LINE_SIZE); + + const char* vstr = match_field(line, field); - while (fgets(line, sizeof(line), fp) != NULL) { - assert(strlen(line) < sizeof(line) - 1, "buffer line[1024] is too small."); - if (strncmp(line, field, strlen(field)) == 0) { - if (strstr(line, value) != NULL) { - rv = true; + if (vstr != NULL) { + // We have a matching line and a valid starting point to the value of + // the field, copy the string for keeps. + _string = strdup(vstr); + break; + } } - break; + fclose(fp); } } - fclose(fp); - return rv; + ~CPUinfo() { os::free((void*)_string); } + + const char* value() const { return _string; } + + bool valid() const { return _string != NULL; } + + bool match(const char* s) const { + return valid() ? strcmp(_string, s) == 0 : false; + } + +private: + const char* _string; + + const char* match_field(char line[CPUINFO_LINE_SIZE], const char* field); + const char* match_alo(const char* text, const char* exp); + const char* match_seq(const char* text, const char* seq); +}; + +/* Given a line of text read from /proc/cpuinfo, determine if the property header + * matches the field specified, according to the following regexp: ""\W+:\W+ + * + * If we have a matching expression, return a pointer to the first character after + * the matching pattern, i.e. the "value", otherwise return NULL. + */ +const char* CPUinfo::match_field(char line[CPUINFO_LINE_SIZE], const char* field) { + return match_alo(match_seq(match_alo(match_seq(line, field), "\t "), ":"), "\t "); } -static bool detect_niagara() { - return cpuinfo_field_contains("cpu", "Niagara"); +/* Match a sequence of at-least-one character in the string expression (exp) to + * the text input. + */ +const char* CPUinfo::match_alo(const char* text, const char* exp) { + if (text == NULL) return NULL; + + const char* chp; + + for (chp = &text[0]; *chp != '\0'; chp++) { + if (strchr(exp, *chp) == NULL) break; + } + + return text < chp ? chp : NULL; } -static bool detect_M_family() { - return cpuinfo_field_contains("cpu", "SPARC-M"); -} +/* Match an exact sequence of characters as specified by the string expression + * (seq) to the text input. + */ +const char* CPUinfo::match_seq(const char* text, const char* seq) { + if (text == NULL) return NULL; -static bool detect_blkinit() { - return cpuinfo_field_contains("cpucaps", "blkinit"); + while (*seq != '\0') { + if (*seq != *text++) break; else seq++; + } + + return *seq == '\0' ? text : NULL; } -int VM_Version::platform_features(int features) { - // Default to generic v9 - features = generic_v9_m; + +typedef struct { + const uint32_t hash; + bool seen; + const char* const name; + const uint64_t mask; +} FeatureEntry; + + +static uint64_t parse_features(FeatureEntry feature_tbl[], const char input[]); + + +void VM_Version::platform_features() { + + // Some of the features reported via "cpucaps", such as; 'flush', 'stbar', + // 'swap', 'muldiv', 'ultra3', 'blkinit', 'n2', 'mul32', 'div32', 'fsmuld' + // and 'v8plus', are either SPARC V8, supported by all HW or simply nonsense + // (the 'ultra3' "property"). + // + // Entries marked as 'NYI' are not yet supported via "cpucaps" but are + // expected to have the names used in the table below (these are SPARC M7 + // features or more recent). + // + // NOTE: Table sorted on lookup/hash ID. - if (detect_niagara()) { - log_info(os, cpu)("Detected Linux on Niagara"); - features = niagara1_m | T_family_m; + static FeatureEntry s_feature_tbl[] = { + { 0x006f, false, "v9", ISA_v9_msk }, // Mandatory + { 0x00a6, false, "md5", ISA_md5_msk }, + { 0x00ce, false, "adi", ISA_adi_msk }, // NYI + { 0x00d7, false, "ima", ISA_ima_msk }, + { 0x00d9, false, "aes", ISA_aes_msk }, + { 0x00db, false, "hpc", ISA_hpc_msk }, + { 0x00dc, false, "des", ISA_des_msk }, + { 0x00ed, false, "sha1", ISA_sha1_msk }, + { 0x00f2, false, "vis", ISA_vis1_msk }, + { 0x0104, false, "vis2", ISA_vis2_msk }, + { 0x0105, false, "vis3", ISA_vis3_msk }, + { 0x0114, false, "sha512", ISA_sha512_msk }, + { 0x0119, false, "sha256", ISA_sha256_msk }, + { 0x011a, false, "fmaf", ISA_fmaf_msk }, + { 0x0132, false, "popc", ISA_popc_msk }, + { 0x0140, false, "crc32c", ISA_crc32c_msk }, + { 0x0147, false, "vis3b", ISA_vis3b_msk }, // NYI + { 0x017e, false, "pause", ISA_pause_msk }, + { 0x0182, false, "mwait", ISA_mwait_msk }, // NYI + { 0x018b, false, "mpmul", ISA_mpmul_msk }, + { 0x018e, false, "sparc5", ISA_sparc5_msk }, // NYI + { 0x01a9, false, "cbcond", ISA_cbcond_msk }, + { 0x01c3, false, "vamask", ISA_vamask_msk }, // NYI + { 0x01ca, false, "kasumi", ISA_kasumi_msk }, + { 0x01e3, false, "xmpmul", ISA_xmpmul_msk }, // NYI + { 0x022c, false, "montmul", ISA_mont_msk }, + { 0x0234, false, "montsqr", ISA_mont_msk }, + { 0x0238, false, "camellia", ISA_camellia_msk }, + { 0x024a, false, "ASIBlkInit", ISA_blk_init_msk }, + { 0x0284, false, "xmontmul", ISA_xmont_msk }, // NYI + { 0x02e6, false, "pause_nsec", ISA_pause_nsec_msk }, // NYI + + { 0x0000, false, NULL, 0 } + }; + + CPUinfo caps("cpucaps"); // Read "cpucaps" from /proc/cpuinfo. + + assert(caps.valid(), "must be"); + + _features = parse_features(s_feature_tbl, caps.value()); + + assert(has_v9(), "must be"); // Basic SPARC-V9 required (V8 not supported). + + CPUinfo type("type"); + + bool is_sun4v = type.match("sun4v"); // All Oracle SPARC + Fujitsu Athena+ + bool is_sun4u = type.match("sun4u"); // All other Fujitsu + + uint64_t synthetic = 0; + + if (is_sun4v) { + // Indirect and direct branches are equally fast. + synthetic = CPU_fast_ind_br_msk; + // Fast IDIV, BIS and LD available on Niagara Plus. + if (has_vis2()) { + synthetic |= (CPU_fast_idiv_msk | CPU_fast_ld_msk); + // ...on Core C4 however, we prefer not to use BIS. + if (!has_sparc5()) { + synthetic |= CPU_fast_bis_msk; + } + } + // Niagara Core C3 supports fast RDPC and block zeroing. + if (has_ima()) { + synthetic |= (CPU_fast_rdpc_msk | CPU_blk_zeroing_msk); + } + // Niagara Core C3 and C4 have slow CMOVE. + if (!has_ima()) { + synthetic |= CPU_fast_cmove_msk; + } + } else if (is_sun4u) { + // SPARC64 only have fast IDIV and RDPC. + synthetic |= (CPU_fast_idiv_msk | CPU_fast_rdpc_msk); + } else { + log_info(os, cpu)("Unable to derive CPU features: %s", type.value()); } - if (detect_M_family()) { - log_info(os, cpu)("Detected Linux on M family"); - features = sun4v_m | generic_v9_m | M_family_m | T_family_m; + _features += synthetic; // Including CPU derived/synthetic features. +} + + +//////////////////////////////////////////////////////////////////////////////// + +static uint32_t uhash32(const char name[]); + +static void update_table(FeatureEntry feature_tbl[], uint32_t hv, + const char* ch1p, + const char* endp); + +/* Given a feature table, parse the input text holding the string value of + * 'cpucaps' as reported by '/proc/cpuinfo', in order to complete the table + * with information on each admissible feature (whether present or not). + * + * Return the composite bit-mask representing the features found. + */ +static uint64_t parse_features(FeatureEntry feature_tbl[], const char input[]) { + log_info(os, cpu)("Parse CPU features: %s\n", input); + +#ifdef ASSERT + // Verify that hash value entries in the table are unique and ordered. + + uint32_t prev = 0; + + for (uint k = 0; feature_tbl[k].name != NULL; k++) { + feature_tbl[k].seen = false; + + assert(feature_tbl[k].hash == uhash32(feature_tbl[k].name), + "feature '%s' has mismatching hash 0x%08x (expected 0x%08x).\n", + feature_tbl[k].name, + feature_tbl[k].hash, + uhash32(feature_tbl[k].name)); + + assert(prev < feature_tbl[k].hash, + "feature '%s' has invalid hash 0x%08x (previous is 0x%08x).\n", + feature_tbl[k].name, + feature_tbl[k].hash, + prev); + + prev = feature_tbl[k].hash; + } +#endif + // Identify features from the input, consisting of a string with features + // separated by commas (or whitespace), e.g. "flush,muldiv,v9,mul32,div32, + // v8plus,popc,vis". + + uint32_t hv = 0; + const char* ch1p = &input[0]; + uint i = 0; + + do { + char ch = input[i]; + + if (isalnum(ch) || ch == '_') { + hv += (ch - 32u); + } + else if (isspace(ch) || ch == ',' || ch == '\0') { // end-of-token + if (ch1p < &input[i]) { + update_table(feature_tbl, hv, ch1p, &input[i]); + } + ch1p = &input[i + 1]; hv = 0; + } else { + // Handle non-accepted input robustly. + log_info(os, cpu)("Bad token in feature string: '%c' (0x%02x).\n", ch, ch); + ch1p = &input[i + 1]; hv = 0; + } + } + while (input[i++] != '\0'); + + // Compute actual bit-mask representation. + + uint64_t mask = 0; + + for (uint k = 0; feature_tbl[k].name != NULL; k++) { + mask |= feature_tbl[k].seen ? feature_tbl[k].mask : 0; } - if (detect_blkinit()) { - features |= blk_init_instructions_m; + return mask; +} + +static uint32_t uhash32(const char name[]) { + uint32_t hv = 0; + + for (uint i = 0; name[i] != '\0'; i++) { + hv += (name[i] - 32u); } - return features; + return hv; } + +static bool verify_match(const char name[], const char* ch1p, const char* endp); + +static void update_table(FeatureEntry feature_tbl[], uint32_t hv, const char* ch1p, const char* endp) { + assert(ch1p < endp, "at least one character"); + + // Look for a hash value in the table. Since this table is a small one (and + // is expected to stay small), we use a simple linear search (iff the table + // grows large, we may consider to adopt a binary ditto, or a perfect hash). + + for (uint k = 0; feature_tbl[k].name != NULL; k++) { + uint32_t hash = feature_tbl[k].hash; + + if (hash < hv) continue; + + if (hash == hv) { + const char* name = feature_tbl[k].name; + + if (verify_match(name, ch1p, endp)) { + feature_tbl[k].seen = true; + break; + } + } + + // Either a non-matching feature (when hash == hv) or hash > hv. In either + // case we break out of the loop and terminate the search (note that the + // table is assumed to be uniquely sorted on the hash). + + break; + } +} + +static bool verify_match(const char name[], const char* ch1p, const char* endp) { + size_t len = strlen(name); + + if (len != static_cast(endp - ch1p)) { + return false; + } + + for (uint i = 0; ch1p + i < endp; i++) { + if (name[i] != ch1p[i]) return false; + } + + return true; +} diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -31,11 +32,9 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "memory/allocation.inline.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp --- a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -74,7 +74,7 @@ frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { -#if defined(COMPILER2) || INCLUDE_JVMCI +#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()); if (!ret_frame2.safe_for_sender(jt)) { @@ -85,7 +85,7 @@ #else // nothing else to try if the frame isn't good return false; -#endif /* COMPILER2 || INCLUDE_JVMCI */ +#endif // COMPILER2_OR_JVMCI } *fr_addr = ret_frame; return true; diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,6 +24,7 @@ */ // no precompiled headers +#include "jvm.h" #include "assembler_zero.inline.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -31,12 +32,10 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_linux.h" #include "memory/allocation.inline.hpp" #include "nativeInst_zero.hpp" #include "os_share_linux.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp --- a/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "macroAssembler_sparc.hpp" #include "classfile/classLoader.hpp" @@ -32,12 +33,10 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_solaris.h" #include "memory/allocation.inline.hpp" #include "nativeInst_sparc.hpp" #include "os_share_solaris.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp --- a/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -31,11 +32,9 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_solaris.h" #include "memory/allocation.inline.hpp" #include "os_share_solaris.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ // no precompiled headers +#include "jvm.h" #include "asm/macroAssembler.hpp" #include "classfile/classLoader.hpp" #include "classfile/systemDictionary.hpp" @@ -30,13 +31,11 @@ #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "interpreter/interpreter.hpp" -#include "jvm_windows.h" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "nativeInst_x86.hpp" #include "os_share_windows.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/extendedPC.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp --- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -81,7 +81,7 @@ frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { -#if defined(COMPILER2) || INCLUDE_JVMCI +#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()); if (!ret_frame2.safe_for_sender(jt)) { @@ -92,7 +92,7 @@ #else // nothing else to try if the frame isn't good return false; -#endif /* COMPILER2 || INCLUDE_JVMCI */ +#endif // COMPILER2_OR_JVMCI } *fr_addr = ret_frame; return true; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/aot/aotCodeHeap.cpp --- a/src/hotspot/share/aot/aotCodeHeap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/aot/aotCodeHeap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -490,6 +490,8 @@ SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_checkcast_arraycopy", address, StubRoutines::_checkcast_arraycopy); + SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_generic_arraycopy", address, StubRoutines::_generic_arraycopy); + SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_encryptBlock", address, StubRoutines::_aescrypt_encryptBlock); SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_decryptBlock", address, StubRoutines::_aescrypt_decryptBlock); SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_cipherBlockChaining_encryptAESCrypt", address, StubRoutines::_cipherBlockChaining_encryptAESCrypt); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/aot/aotLoader.cpp --- a/src/hotspot/share/aot/aotLoader.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/aot/aotLoader.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,12 +22,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "aot/aotCodeHeap.hpp" #include "aot/aotLoader.inline.hpp" #include "jvmci/jvmciRuntime.hpp" #include "oops/method.hpp" -#include "prims/jvm.h" #include "runtime/os.hpp" #include "runtime/timerTrace.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/c1/c1_CFGPrinter.cpp --- a/src/hotspot/share/c1/c1_CFGPrinter.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/c1/c1_CFGPrinter.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,13 +23,13 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "c1/c1_CFGPrinter.hpp" #include "c1/c1_IR.hpp" #include "c1/c1_InstructionPrinter.hpp" #include "c1/c1_LIR.hpp" #include "c1/c1_LinearScan.hpp" #include "c1/c1_ValueStack.hpp" -#include "prims/jvm.h" #ifndef PRODUCT diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/c1/c1_Canonicalizer.hpp --- a/src/hotspot/share/c1/c1_Canonicalizer.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/c1/c1_Canonicalizer.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -40,6 +40,10 @@ void set_constant(jlong x) { set_canonical(new Constant(new LongConstant(x))); } void set_constant(jfloat x) { set_canonical(new Constant(new FloatConstant(x))); } void set_constant(jdouble x) { set_canonical(new Constant(new DoubleConstant(x))); } +#ifdef _WINDOWS + // jint is defined as long in jni_md.h, so convert from int to jint + void set_constant(int x) { set_constant((jint)x); } +#endif void move_const_to_right(Op2* x); void do_Op2(Op2* x); void do_UnsafeRawOp(UnsafeRawOp* x); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/c1/c1_Compiler.cpp --- a/src/hotspot/share/c1/c1_Compiler.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/c1/c1_Compiler.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -213,7 +213,7 @@ case vmIntrinsics::_updateCRC32: case vmIntrinsics::_updateBytesCRC32: case vmIntrinsics::_updateByteBufferCRC32: -#if defined(SPARC) || defined(S390) || defined(PPC64) +#if defined(SPARC) || defined(S390) || defined(PPC64) || defined(AARCH64) case vmIntrinsics::_updateBytesCRC32C: case vmIntrinsics::_updateDirectByteBufferCRC32C: #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/c1/c1_LinearScan.cpp --- a/src/hotspot/share/c1/c1_LinearScan.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/c1/c1_LinearScan.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2507,7 +2507,7 @@ // use). ConstantOopWriteValue* LinearScan::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL); ConstantIntValue* LinearScan::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1); -ConstantIntValue* LinearScan::_int_0_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0); +ConstantIntValue* LinearScan::_int_0_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue((jint)0); ConstantIntValue* LinearScan::_int_1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1); ConstantIntValue* LinearScan::_int_2_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2); LocationValue* _illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location()); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/ci/ciEnv.cpp --- a/src/hotspot/share/ci/ciEnv.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/ci/ciEnv.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "ci/ciConstant.hpp" #include "ci/ciEnv.hpp" #include "ci/ciField.hpp" @@ -49,7 +50,6 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "runtime/init.hpp" #include "runtime/reflection.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/ci/ciFlags.hpp --- a/src/hotspot/share/ci/ciFlags.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/ci/ciFlags.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -25,9 +25,9 @@ #ifndef SHARE_VM_CI_CIFLAGS_HPP #define SHARE_VM_CI_CIFLAGS_HPP +#include "jvm.h" #include "ci/ciClassList.hpp" #include "memory/allocation.hpp" -#include "prims/jvm.h" #include "utilities/accessFlags.hpp" #include "utilities/ostream.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/ci/ciReplay.cpp --- a/src/hotspot/share/ci/ciReplay.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/ci/ciReplay.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "ci/ciMethodData.hpp" #include "ci/ciReplay.hpp" #include "ci/ciSymbol.hpp" @@ -33,7 +34,6 @@ #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "utilities/copy.hpp" #include "utilities/macros.hpp" @@ -790,7 +790,7 @@ while (field_signature[rank] == '[') { rank++; } - int* dims = NEW_RESOURCE_ARRAY(int, rank); + jint* dims = NEW_RESOURCE_ARRAY(jint, rank); dims[0] = length; for (int i = 1; i < rank; i++) { dims[i] = 1; // These aren't relevant to the compiler diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/altHashing.cpp --- a/src/hotspot/share/classfile/altHashing.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/altHashing.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -42,15 +42,15 @@ juint AltHashing::compute_seed() { jlong nanos = os::javaTimeNanos(); jlong now = os::javaTimeMillis(); - int SEED_MATERIAL[8] = { - (int) object_hash(SystemDictionary::String_klass()), - (int) object_hash(SystemDictionary::System_klass()), - os::random(), // current thread isn't a java thread - (int) (((julong)nanos) >> 32), - (int) nanos, - (int) (((julong)now) >> 32), - (int) now, - (int) (os::javaTimeNanos() >> 2) + jint SEED_MATERIAL[8] = { + (jint) object_hash(SystemDictionary::String_klass()), + (jint) object_hash(SystemDictionary::System_klass()), + (jint) os::random(), // current thread isn't a java thread + (jint) (((julong)nanos) >> 32), + (jint) nanos, + (jint) (((julong)now) >> 32), + (jint) now, + (jint) (os::javaTimeNanos() >> 2) }; return murmur3_32(SEED_MATERIAL, 8); @@ -167,7 +167,7 @@ } // Hash used for the seed. -juint AltHashing::murmur3_32(juint seed, const int* data, int len) { +juint AltHashing::murmur3_32(juint seed, const jint* data, int len) { juint h1 = seed; int off = 0; @@ -202,6 +202,6 @@ return h1; } -juint AltHashing::murmur3_32(const int* data, int len) { +juint AltHashing::murmur3_32(const jint* data, int len) { return murmur3_32(0, data, len); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/altHashing.hpp --- a/src/hotspot/share/classfile/altHashing.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/altHashing.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -43,8 +43,8 @@ static juint Integer_rotateLeft(juint i, int distance) { return (i << distance) | (i >> (32 - distance)); } - static juint murmur3_32(const int* data, int len); - static juint murmur3_32(juint seed, const int* data, int len); + static juint murmur3_32(const jint* data, int len); + static juint murmur3_32(juint seed, const jint* data, int len); public: static juint compute_seed(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/classFileParser.cpp --- a/src/hotspot/share/classfile/classFileParser.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/classFileParser.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,6 +22,7 @@ * */ #include "precompiled.hpp" +#include "jvm.h" #include "aot/aotLoader.hpp" #include "classfile/classFileParser.hpp" #include "classfile/classFileStream.hpp" @@ -54,7 +55,6 @@ #include "oops/method.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" #include "runtime/javaCalls.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/classLoader.cpp --- a/src/hotspot/share/classfile/classLoader.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/classLoader.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" @@ -53,7 +54,6 @@ #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" #include "runtime/compilationPolicy.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/classLoaderData.cpp --- a/src/hotspot/share/classfile/classLoaderData.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/classLoaderData.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -604,40 +604,27 @@ const int _boot_loader_dictionary_size = 1009; const int _default_loader_dictionary_size = 107; -const int _prime_array_size = 8; // array of primes for system dictionary size -const int _average_depth_goal = 3; // goal for lookup length -const int _primelist[_prime_array_size] = {107, 1009, 2017, 4049, 5051, 10103, 20201, 40423}; - -// Calculate a "good" dictionary size based -// on predicted or current loaded classes count. -static int calculate_dictionary_size(int classcount) { - int newsize = _primelist[0]; - if (classcount > 0 && !DumpSharedSpaces) { - int index = 0; - int desiredsize = classcount/_average_depth_goal; - for (newsize = _primelist[index]; index < _prime_array_size -1; - newsize = _primelist[++index]) { - if (desiredsize <= newsize) { - break; - } - } - } - return newsize; -} Dictionary* ClassLoaderData::create_dictionary() { assert(!is_anonymous(), "anonymous class loader data do not have a dictionary"); int size; + bool resizable = false; if (_the_null_class_loader_data == NULL) { size = _boot_loader_dictionary_size; + resizable = true; } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { size = 1; // there's only one class in relection class loader and no initiated classes } else if (is_system_class_loader_data()) { - size = calculate_dictionary_size(PredictedLoadedClassCount); + size = _boot_loader_dictionary_size; + resizable = true; } else { size = _default_loader_dictionary_size; + resizable = true; } - return new Dictionary(this, size); + if (!DynamicallyResizeSystemDictionaries || DumpSharedSpaces || UseSharedSpaces) { + resizable = false; + } + return new Dictionary(this, size, resizable); } // Unloading support @@ -1325,6 +1312,19 @@ } } +int ClassLoaderDataGraph::resize_if_needed() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); + int resized = 0; + if (Dictionary::does_any_dictionary_needs_resizing()) { + FOR_ALL_DICTIONARY(cld) { + if (cld->dictionary()->resize_if_needed()) { + resized++; + } + } + } + return resized; +} + void ClassLoaderDataGraph::post_class_unload_events() { #if INCLUDE_TRACE assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/classLoaderData.hpp --- a/src/hotspot/share/classfile/classLoaderData.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/classLoaderData.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -143,6 +143,8 @@ } } + static int resize_if_needed(); + static bool has_metaspace_oom() { return _metaspace_oom; } static void set_metaspace_oom(bool value) { _metaspace_oom = value; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/compactHashtable.cpp --- a/src/hotspot/share/classfile/compactHashtable.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/compactHashtable.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/compactHashtable.inline.hpp" #include "classfile/javaClasses.hpp" #include "logging/logMessage.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceShared.hpp" -#include "prims/jvm.h" #include "runtime/vmThread.hpp" #include "utilities/numberSeq.hpp" #include diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/dictionary.cpp --- a/src/hotspot/share/classfile/dictionary.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/dictionary.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -29,6 +29,7 @@ #include "classfile/protectionDomainCache.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" +#include "gc/shared/gcLocker.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/iterator.hpp" @@ -39,6 +40,11 @@ #include "runtime/orderAccess.inline.hpp" #include "utilities/hashtable.inline.hpp" +// Optimization: if any dictionary needs resizing, we set this flag, +// so that we dont't have to walk all dictionaries to check if any actually +// needs resizing, which is costly to do at Safepoint. +bool Dictionary::_some_dictionary_needs_resizing = false; + size_t Dictionary::entry_size() { if (DumpSharedSpaces) { return SystemDictionaryShared::dictionary_entry_size(); @@ -47,15 +53,17 @@ } } -Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size) - : _loader_data(loader_data), Hashtable(table_size, (int)entry_size()) { +Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable) + : _loader_data(loader_data), _resizable(resizable), _needs_resizing(false), + Hashtable(table_size, (int)entry_size()) { }; Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket* t, - int number_of_entries) - : _loader_data(loader_data), Hashtable(table_size, (int)entry_size(), t, number_of_entries) { + int number_of_entries, bool resizable) + : _loader_data(loader_data), _resizable(resizable), _needs_resizing(false), + Hashtable(table_size, (int)entry_size(), t, number_of_entries) { }; Dictionary::~Dictionary() { @@ -96,6 +104,60 @@ FREE_C_HEAP_ARRAY(char, entry); } +const int _resize_load_trigger = 5; // load factor that will trigger the resize +const double _resize_factor = 2.0; // by how much we will resize using current number of entries +const int _resize_max_size = 40423; // the max dictionary size allowed +const int _primelist[] = {107, 1009, 2017, 4049, 5051, 10103, 20201, _resize_max_size}; +const int _prime_array_size = sizeof(_primelist)/sizeof(int); + +// Calculate next "good" dictionary size based on requested count +static int calculate_dictionary_size(int requested) { + int newsize = _primelist[0]; + int index = 0; + for (newsize = _primelist[index]; index < (_prime_array_size - 1); + newsize = _primelist[++index]) { + if (requested <= newsize) { + break; + } + } + return newsize; +} + +bool Dictionary::does_any_dictionary_needs_resizing() { + return Dictionary::_some_dictionary_needs_resizing; +} + +void Dictionary::check_if_needs_resize() { + if (_resizable == true) { + if (number_of_entries() > (_resize_load_trigger*table_size())) { + _needs_resizing = true; + Dictionary::_some_dictionary_needs_resizing = true; + } + } +} + +bool Dictionary::resize_if_needed() { + int desired_size = 0; + if (_needs_resizing == true) { + desired_size = calculate_dictionary_size((int)(_resize_factor*number_of_entries())); + if (desired_size >= _resize_max_size) { + desired_size = _resize_max_size; + // We have reached the limit, turn resizing off + _resizable = false; + } + if ((desired_size != 0) && (desired_size != table_size())) { + if (!resize(desired_size)) { + // Something went wrong, turn resizing off + _resizable = false; + } + } + } + + _needs_resizing = false; + Dictionary::_some_dictionary_needs_resizing = false; + + return (desired_size != 0); +} bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { #ifdef ASSERT @@ -264,14 +326,16 @@ // also cast to volatile; we do this to ensure store order is maintained // by the compilers. -void Dictionary::add_klass(int index, unsigned int hash, Symbol* class_name, +void Dictionary::add_klass(unsigned int hash, Symbol* class_name, InstanceKlass* obj) { assert_locked_or_safepoint(SystemDictionary_lock); assert(obj != NULL, "adding NULL obj"); assert(obj->name() == class_name, "sanity check on name"); DictionaryEntry* entry = new_entry(hash, obj); + int index = hash_to_index(hash); add_entry(index, entry); + check_if_needs_resize(); } @@ -299,8 +363,11 @@ } -InstanceKlass* Dictionary::find(int index, unsigned int hash, Symbol* name, +InstanceKlass* Dictionary::find(unsigned int hash, Symbol* name, Handle protection_domain) { + NoSafepointVerifier nsv; + + int index = hash_to_index(hash); DictionaryEntry* entry = get_entry(index, hash, name); if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { return entry->instance_klass(); @@ -350,13 +417,24 @@ } -bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, +bool Dictionary::is_valid_protection_domain(unsigned int hash, Symbol* name, Handle protection_domain) { + int index = hash_to_index(hash); DictionaryEntry* entry = get_entry(index, hash, name); return entry->is_valid_protection_domain(protection_domain); } +#if INCLUDE_CDS +static bool is_jfr_event_class(Klass *k) { + while (k) { + if (k->name()->equals("jdk/jfr/Event")) { + return true; + } + k = k->super(); + } + return false; +} void Dictionary::reorder_dictionary_for_sharing() { @@ -368,14 +446,22 @@ while (p != NULL) { DictionaryEntry* next = p->next(); InstanceKlass*ik = p->instance_klass(); - // we cannot include signed classes in the archive because the certificates - // used during dump time may be different than those used during - // runtime (due to expiration, etc). if (ik->signers() != NULL) { + // We cannot include signed classes in the archive because the certificates + // used during dump time may be different than those used during + // runtime (due to expiration, etc). ResourceMark rm; tty->print_cr("Preload Warning: Skipping %s from signed JAR", ik->name()->as_C_string()); free_entry(p); + } else if (is_jfr_event_class(ik)) { + // We cannot include JFR event classes because they need runtime-specific + // instrumentation in order to work with -XX:FlightRecorderOptions=retransform=false. + // There are only a small number of these classes, so it's not worthwhile to + // support them and make CDS more complicated. + ResourceMark rm; + tty->print_cr("Skipping JFR event class %s", ik->name()->as_C_string()); + free_entry(p); } else { p->set_next(master_list); master_list = p; @@ -400,7 +486,7 @@ set_entry(index, p); } } - +#endif SymbolPropertyTable::SymbolPropertyTable(int table_size) : Hashtable(table_size, sizeof(SymbolPropertyEntry)) diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/dictionary.hpp --- a/src/hotspot/share/classfile/dictionary.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/dictionary.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -43,6 +43,11 @@ class Dictionary : public Hashtable { friend class VMStructs; + static bool _some_dictionary_needs_resizing; + bool _resizable; + bool _needs_resizing; + void check_if_needs_resize(); + ClassLoaderData* _loader_data; // backpointer to owning loader ClassLoaderData* loader_data() const { return _loader_data; } @@ -51,13 +56,16 @@ protected: static size_t entry_size(); public: - Dictionary(ClassLoaderData* loader_data, int table_size); - Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket* t, int number_of_entries); + Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable = false); + Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket* t, int number_of_entries, bool resizable = false); ~Dictionary(); + static bool does_any_dictionary_needs_resizing(); + bool resize_if_needed(); + DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass); - void add_klass(int index, unsigned int hash, Symbol* class_name, InstanceKlass* obj); + void add_klass(unsigned int hash, Symbol* class_name, InstanceKlass* obj); InstanceKlass* find_class(int index, unsigned int hash, Symbol* name); @@ -79,8 +87,8 @@ void do_unloading(); // Protection domains - InstanceKlass* find(int index, unsigned int hash, Symbol* name, Handle protection_domain); - bool is_valid_protection_domain(int index, unsigned int hash, + InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain); + bool is_valid_protection_domain(unsigned int hash, Symbol* name, Handle protection_domain); void add_protection_domain(int index, unsigned int hash, @@ -88,7 +96,7 @@ Handle protection_domain, TRAPS); // Sharing support - void reorder_dictionary_for_sharing(); + void reorder_dictionary_for_sharing() NOT_CDS_RETURN; void print_on(outputStream* st) const; void verify(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/javaClasses.cpp --- a/src/hotspot/share/classfile/javaClasses.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/javaClasses.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2258,8 +2258,9 @@ void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) { ResourceMark rm(THREAD); - Handle k (THREAD, stackFrame->obj_field(_declaringClass_offset)); - InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k())); + Handle mname(THREAD, stackFrame->obj_field(java_lang_StackFrameInfo::_memberName_offset)); + Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname())); + InstanceKlass* holder = InstanceKlass::cast(clazz); Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK); short version = stackFrame->short_field(_version_offset); @@ -2270,7 +2271,6 @@ void java_lang_StackFrameInfo::compute_offsets() { Klass* k = SystemDictionary::StackFrameInfo_klass(); - compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(), vmSymbols::class_signature()); compute_offset(_memberName_offset, k, vmSymbols::memberName_name(), vmSymbols::object_signature()); compute_offset(_bci_offset, k, vmSymbols::bci_name(), vmSymbols::short_signature()); STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); @@ -3679,7 +3679,6 @@ int java_lang_StackTraceElement::classLoaderName_offset; int java_lang_StackTraceElement::declaringClass_offset; int java_lang_StackTraceElement::declaringClassObject_offset; -int java_lang_StackFrameInfo::_declaringClass_offset; int java_lang_StackFrameInfo::_memberName_offset; int java_lang_StackFrameInfo::_bci_offset; int java_lang_StackFrameInfo::_version_offset; @@ -3732,11 +3731,6 @@ element->obj_field_put(declaringClassObject_offset, value); } -// Support for java_lang_StackFrameInfo -void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) { - element->obj_field_put(_declaringClass_offset, value); -} - void java_lang_StackFrameInfo::set_version(oop element, short value) { element->short_field_put(_version_offset, value); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/javaClasses.hpp --- a/src/hotspot/share/classfile/javaClasses.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/javaClasses.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -1370,7 +1370,6 @@ class java_lang_StackFrameInfo: AllStatic { private: - static int _declaringClass_offset; static int _memberName_offset; static int _bci_offset; static int _version_offset; @@ -1379,7 +1378,6 @@ public: // Setters - static void set_declaringClass(oop info, oop value); static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci, TRAPS); static void set_bci(oop info, int value); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/modules.cpp --- a/src/hotspot/share/classfile/modules.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/modules.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classFileParser.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" @@ -40,7 +41,6 @@ #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" -#include "prims/jvm.h" #include "runtime/arguments.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/systemDictionary.cpp --- a/src/hotspot/share/classfile/systemDictionary.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/systemDictionary.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "aot/aotLoader.hpp" #include "classfile/classFileParser.hpp" #include "classfile/classFileStream.hpp" @@ -61,7 +62,6 @@ #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" -#include "prims/jvm.h" #include "prims/jvmtiEnvBase.hpp" #include "prims/resolvedMethodTable.hpp" #include "prims/methodHandles.hpp" @@ -371,7 +371,6 @@ ClassLoaderData* loader_data = class_loader_data(class_loader); Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(child_name); - int d_index = dictionary->hash_to_index(d_hash); unsigned int p_hash = placeholders()->compute_hash(child_name); int p_index = placeholders()->hash_to_index(p_hash); // can't throw error holding a lock @@ -379,7 +378,7 @@ bool throw_circularity_error = false; { MutexLocker mu(SystemDictionary_lock, THREAD); - Klass* childk = find_class(d_index, d_hash, child_name, dictionary); + Klass* childk = find_class(d_hash, child_name, dictionary); Klass* quicksuperk; // to support // loading: if child done loading, just return superclass // if class_name, & class_loader don't match: @@ -487,9 +486,9 @@ Symbol* kn = klass->name(); unsigned int d_hash = dictionary->compute_hash(kn); - int d_index = dictionary->hash_to_index(d_hash); MutexLocker mu(SystemDictionary_lock, THREAD); + int d_index = dictionary->hash_to_index(d_hash); dictionary->add_protection_domain(d_index, d_hash, klass, protection_domain, THREAD); } @@ -555,7 +554,6 @@ ClassLoaderData* loader_data = class_loader_data(class_loader); Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(name); - int d_index = dictionary->hash_to_index(d_hash); unsigned int p_hash = placeholders()->compute_hash(name); int p_index = placeholders()->hash_to_index(p_hash); @@ -579,7 +577,7 @@ if (!class_loader.is_null() && is_parallelCapable(class_loader)) { MutexLocker mu(SystemDictionary_lock, THREAD); // Check if classloading completed while we were loading superclass or waiting - return find_class(d_index, d_hash, name, dictionary); + return find_class(d_hash, name, dictionary); } // must loop to both handle other placeholder updates @@ -589,7 +587,7 @@ while (super_load_in_progress) { MutexLocker mu(SystemDictionary_lock, THREAD); // Check if classloading completed while we were loading superclass or waiting - InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); + InstanceKlass* check = find_class(d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it return check; @@ -670,6 +668,7 @@ class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL); Dictionary* dictionary = loader_data->dictionary(); + unsigned int d_hash = dictionary->compute_hash(name); // Do lookup to see if class already exist and the protection domain // has the right access @@ -677,11 +676,10 @@ // All subsequent calls use find_class, and set has_loaded_class so that // before we return a result we call out to java to check for valid protection domain // to allow returning the Klass* and add it to the pd_set if it is valid - unsigned int d_hash = dictionary->compute_hash(name); - int d_index = dictionary->hash_to_index(d_hash); - Klass* probe = dictionary->find(d_index, d_hash, name, protection_domain); - if (probe != NULL) return probe; - + { + Klass* probe = dictionary->find(d_hash, name, protection_domain); + if (probe != NULL) return probe; + } // Non-bootstrap class loaders will call out to class loader and // define via jvm/jni_DefineClass which will acquire the @@ -716,7 +714,7 @@ { MutexLocker mu(SystemDictionary_lock, THREAD); - InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); + InstanceKlass* check = find_class(d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it class_has_been_loaded = true; @@ -800,7 +798,7 @@ double_lock_wait(lockObject, THREAD); } // Check if classloading completed while we were waiting - InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); + InstanceKlass* check = find_class(d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it k = check; @@ -825,7 +823,7 @@ // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL // one final check if the load has already completed // class loaders holding the ObjectLock shouldn't find the class here - InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); + InstanceKlass* check = find_class(d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so return it after checking/adding protection domain k = check; @@ -858,7 +856,7 @@ if (k == NULL && HAS_PENDING_EXCEPTION && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { MutexLocker mu(SystemDictionary_lock, THREAD); - InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); + InstanceKlass* check = find_class(d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just use it k = check; @@ -873,7 +871,7 @@ if (!HAS_PENDING_EXCEPTION && k != NULL && k->class_loader() != class_loader()) { - check_constraints(d_index, d_hash, k, class_loader, false, THREAD); + check_constraints(d_hash, k, class_loader, false, THREAD); // Need to check for a PENDING_EXCEPTION again; check_constraints // can throw and doesn't use the CHECK macro. @@ -881,7 +879,7 @@ { // Grabbing the Compile_lock prevents systemDictionary updates // during compilations. MutexLocker mu(Compile_lock, THREAD); - update_dictionary(d_index, d_hash, p_index, p_hash, + update_dictionary(d_hash, p_index, p_hash, k, class_loader, THREAD); } @@ -923,7 +921,7 @@ if (protection_domain() == NULL) return k; // Check the protection domain has the right access - if (dictionary->is_valid_protection_domain(d_index, d_hash, name, + if (dictionary->is_valid_protection_domain(d_hash, name, protection_domain)) { return k; } @@ -965,8 +963,7 @@ Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(class_name); - int d_index = dictionary->hash_to_index(d_hash); - return dictionary->find(d_index, d_hash, class_name, + return dictionary->find(d_hash, class_name, protection_domain); } @@ -1644,8 +1641,7 @@ Symbol* name_h = k->name(); Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(name_h); - int d_index = dictionary->hash_to_index(d_hash); - check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK); + check_constraints(d_hash, k, class_loader_h, true, CHECK); // Register class just loaded with class loader (placed in Vector) // Note we do this before updating the dictionary, as this can @@ -1673,7 +1669,7 @@ // Add to systemDictionary - so other classes can see it. // Grabs and releases SystemDictionary_lock - update_dictionary(d_index, d_hash, p_index, p_hash, + update_dictionary(d_hash, p_index, p_hash, k, class_loader_h, THREAD); } k->eager_initialize(THREAD); @@ -1715,7 +1711,6 @@ Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(name_h); - int d_index = dictionary->hash_to_index(d_hash); // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS unsigned int p_hash = placeholders()->compute_hash(name_h); @@ -1726,7 +1721,7 @@ MutexLocker mu(SystemDictionary_lock, THREAD); // First check if class already defined if (UnsyncloadClass || (is_parallelDefine(class_loader))) { - InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary); + InstanceKlass* check = find_class(d_hash, name_h, dictionary); if (check != NULL) { return check; } @@ -1748,7 +1743,7 @@ placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD); SystemDictionary_lock->notify_all(); #ifdef ASSERT - InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary); + InstanceKlass* check = find_class(d_hash, name_h, dictionary); assert(check != NULL, "definer missed recording success"); #endif return probe->instance_klass(); @@ -1823,10 +1818,11 @@ // ---------------------------------------------------------------------------- // Lookup -InstanceKlass* SystemDictionary::find_class(int index, unsigned int hash, +InstanceKlass* SystemDictionary::find_class(unsigned int hash, Symbol* class_name, Dictionary* dictionary) { assert_locked_or_safepoint(SystemDictionary_lock); + int index = dictionary->hash_to_index(hash); return dictionary->find_class(index, hash, class_name); } @@ -1856,8 +1852,7 @@ Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(class_name); - int d_index = dictionary->hash_to_index(d_hash); - return find_class(d_index, d_hash, class_name, dictionary); + return find_class(d_hash, class_name, dictionary); } @@ -2210,7 +2205,7 @@ // if defining is true, then LinkageError if already in dictionary // if initiating loader, then ok if InstanceKlass matches existing entry -void SystemDictionary::check_constraints(int d_index, unsigned int d_hash, +void SystemDictionary::check_constraints(unsigned int d_hash, InstanceKlass* k, Handle class_loader, bool defining, TRAPS) { @@ -2222,7 +2217,7 @@ MutexLocker mu(SystemDictionary_lock, THREAD); - InstanceKlass* check = find_class(d_index, d_hash, name, loader_data->dictionary()); + InstanceKlass* check = find_class(d_hash, name, loader_data->dictionary()); if (check != NULL) { // if different InstanceKlass - duplicate class definition, // else - ok, class loaded by a different thread in parallel, @@ -2270,7 +2265,7 @@ // Update class loader data dictionary - done after check_constraint and add_to_hierachy // have been called. -void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash, +void SystemDictionary::update_dictionary(unsigned int d_hash, int p_index, unsigned int p_hash, InstanceKlass* k, Handle class_loader, @@ -2305,13 +2300,13 @@ // Make a new dictionary entry. Dictionary* dictionary = loader_data->dictionary(); - InstanceKlass* sd_check = find_class(d_index, d_hash, name, dictionary); + InstanceKlass* sd_check = find_class(d_hash, name, dictionary); if (sd_check == NULL) { - dictionary->add_klass(d_index, d_hash, name, k); + dictionary->add_klass(d_hash, name, k); notice_modification(); } #ifdef ASSERT - sd_check = find_class(d_index, d_hash, name, dictionary); + sd_check = find_class(d_hash, name, dictionary); assert (sd_check != NULL, "should have entry in dictionary"); // Note: there may be a placeholder entry: for circularity testing // or for parallel defines @@ -2388,16 +2383,14 @@ Dictionary* dictionary1 = loader_data1->dictionary(); unsigned int d_hash1 = dictionary1->compute_hash(constraint_name); - int d_index1 = dictionary1->hash_to_index(d_hash1); Dictionary* dictionary2 = loader_data2->dictionary(); unsigned int d_hash2 = dictionary2->compute_hash(constraint_name); - int d_index2 = dictionary2->hash_to_index(d_hash2); { MutexLocker mu_s(SystemDictionary_lock, THREAD); - InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, dictionary1); - InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, dictionary2); + InstanceKlass* klass1 = find_class(d_hash1, constraint_name, dictionary1); + InstanceKlass* klass2 = find_class(d_hash2, constraint_name, dictionary2); return constraints()->add_entry(constraint_name, klass1, class_loader1, klass2, class_loader2); } @@ -2855,9 +2848,11 @@ return _pd_cache_table->get(protection_domain); } +#if INCLUDE_CDS void SystemDictionary::reorder_dictionary_for_sharing() { ClassLoaderData::the_null_class_loader_data()->dictionary()->reorder_dictionary_for_sharing(); } +#endif size_t SystemDictionary::count_bytes_for_buckets() { return ClassLoaderData::the_null_class_loader_data()->dictionary()->count_bytes_for_buckets(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/systemDictionary.hpp --- a/src/hotspot/share/classfile/systemDictionary.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/systemDictionary.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -384,7 +384,7 @@ public: // Sharing support. - static void reorder_dictionary_for_sharing(); + static void reorder_dictionary_for_sharing() NOT_CDS_RETURN; static void combine_shared_dictionaries(); static size_t count_bytes_for_buckets(); static size_t count_bytes_for_table(); @@ -655,11 +655,8 @@ // Setup link to hierarchy static void add_to_hierarchy(InstanceKlass* k, TRAPS); - // We pass in the hashtable index so we can calculate it outside of - // the SystemDictionary_lock. - // Basic find on loaded classes - static InstanceKlass* find_class(int index, unsigned int hash, + static InstanceKlass* find_class(unsigned int hash, Symbol* name, Dictionary* dictionary); static InstanceKlass* find_class(Symbol* class_name, ClassLoaderData* loader_data); @@ -685,10 +682,10 @@ static void initialize_preloaded_classes(TRAPS); // Class loader constraints - static void check_constraints(int index, unsigned int hash, + static void check_constraints(unsigned int hash, InstanceKlass* k, Handle loader, bool defining, TRAPS); - static void update_dictionary(int d_index, unsigned int d_hash, + static void update_dictionary(unsigned int d_hash, int p_index, unsigned int p_hash, InstanceKlass* k, Handle loader, TRAPS); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/verifier.cpp --- a/src/hotspot/share/classfile/verifier.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/verifier.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classFileStream.hpp" #include "classfile/javaClasses.hpp" #include "classfile/stackMapTable.hpp" @@ -40,7 +41,6 @@ #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayOop.hpp" -#include "prims/jvm.h" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/vmSymbols.cpp --- a/src/hotspot/share/classfile/vmSymbols.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/vmSymbols.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/vmSymbols.hpp" #include "compiler/compilerDirectives.hpp" #include "memory/oopFactory.hpp" #include "memory/metaspaceClosure.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/handles.inline.hpp" #include "utilities/xmlstream.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/classfile/vmSymbols.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -429,7 +429,6 @@ template(append_name, "append") \ template(klass_name, "klass") \ template(array_klass_name, "array_klass") \ - template(declaringClass_name, "declaringClass") \ template(memberName_name, "memberName") \ template(mid_name, "mid") \ template(cpref_name, "cpref") \ diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/code/codeBlob.cpp --- a/src/hotspot/share/code/codeBlob.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/code/codeBlob.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" #include "code/relocInfo.hpp" @@ -33,7 +34,6 @@ #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "prims/forte.hpp" -#include "prims/jvm.h" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutexLocker.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/code/codeBlob.hpp --- a/src/hotspot/share/code/codeBlob.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/code/codeBlob.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -49,21 +49,35 @@ // CodeBlob - superclass for all entries in the CodeCache. // // Subtypes are: -// CompiledMethod : Compiled Java methods (include method that calls to native code) -// nmethod : JIT Compiled Java methods -// RuntimeBlob : Non-compiled method code; generated glue code -// RuntimeStub : Call to VM runtime methods -// DeoptimizationBlob : Used for deoptimization -// ExceptionBlob : Used for stack unrolling -// SafepointBlob : Used to handle illegal instruction exceptions +// CompiledMethod : Compiled Java methods (include method that calls to native code) +// nmethod : JIT Compiled Java methods +// AOTCompiledMethod : AOT Compiled Java methods - Not in the CodeCache! +// AOTCompiledMethod objects are allocated in the C-Heap, the code they +// point to is allocated in the AOTCodeHeap which is in the C-Heap as +// well (i.e. it's the memory where the shared library was loaded to) +// RuntimeBlob : Non-compiled method code; generated glue code +// BufferBlob : Used for non-relocatable code such as interpreter, stubroutines, etc. +// AdapterBlob : Used to hold C2I/I2C adapters +// MethodHandlesAdapterBlob : Used to hold MethodHandles adapters +// RuntimeStub : Call to VM runtime methods +// SingletonBlob : Super-class for all blobs that exist in only one instance +// DeoptimizationBlob : Used for deoptimization +// ExceptionBlob : Used for stack unrolling +// SafepointBlob : Used to handle illegal instruction exceptions +// UncommonTrapBlob : Used to handle uncommon traps // // -// Layout: +// Layout (all except AOTCompiledMethod) : continuous in the CodeCache // - header // - relocation // - content space // - instruction space // - data space +// +// Layout (AOTCompiledMethod) : in the C-Heap +// - header -\ +// ... | +// - code <-/ class CodeBlobLayout; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/code/nmethod.cpp --- a/src/hotspot/share/code/nmethod.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/code/nmethod.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" #include "code/dependencies.hpp" @@ -41,7 +42,6 @@ #include "memory/resourceArea.hpp" #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/jvmtiImpl.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" @@ -409,6 +409,7 @@ #if INCLUDE_JVMCI _jvmci_installed_code = NULL; _speculation_log = NULL; + _jvmci_installed_code_triggers_unloading = false; #endif } @@ -461,8 +462,8 @@ AbstractCompiler* compiler, int comp_level #if INCLUDE_JVMCI - , Handle installed_code, - Handle speculationLog + , jweak installed_code, + jweak speculationLog #endif ) { @@ -642,8 +643,8 @@ AbstractCompiler* compiler, int comp_level #if INCLUDE_JVMCI - , Handle installed_code, - Handle speculation_log + , jweak installed_code, + jweak speculation_log #endif ) : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false), @@ -671,8 +672,14 @@ set_ctable_begin(header_begin() + _consts_offset); #if INCLUDE_JVMCI - _jvmci_installed_code = installed_code(); - _speculation_log = (instanceOop)speculation_log(); + _jvmci_installed_code = installed_code; + _speculation_log = speculation_log; + oop obj = JNIHandles::resolve(installed_code); + if (obj == NULL || (obj->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(obj))) { + _jvmci_installed_code_triggers_unloading = false; + } else { + _jvmci_installed_code_triggers_unloading = true; + } if (compiler->is_jvmci()) { // JVMCI might not produce any stub sections @@ -1026,8 +1033,6 @@ " unloadable, Method*(" INTPTR_FORMAT "), cause(" INTPTR_FORMAT ")", p2i(this), p2i(_method), p2i(cause)); - if (!Universe::heap()->is_gc_active()) - cause->klass()->print_on(&ls); } // Unlink the osr method, so we do not look this up again if (is_osr_method()) { @@ -1077,14 +1082,8 @@ #if INCLUDE_JVMCI // The method can only be unloaded after the pointer to the installed code // Java wrapper is no longer alive. Here we need to clear out this weak - // reference to the dead object. Nulling out the reference has to happen - // after the method is unregistered since the original value may be still - // tracked by the rset. + // reference to the dead object. maybe_invalidate_installed_code(); - // Clear these out after the nmethod has been unregistered and any - // updates to the InstalledCode instance have been performed. - _jvmci_installed_code = NULL; - _speculation_log = NULL; #endif // The Method* is gone at this point @@ -1246,10 +1245,6 @@ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); if (nmethod_needs_unregister) { Universe::heap()->unregister_nmethod(this); -#ifdef JVMCI - _jvmci_installed_code = NULL; - _speculation_log = NULL; -#endif } flush_dependencies(NULL); } @@ -1314,6 +1309,11 @@ CodeCache::drop_scavenge_root_nmethod(this); } +#if INCLUDE_JVMCI + assert(_jvmci_installed_code == NULL, "should have been nulled out when transitioned to zombie"); + assert(_speculation_log == NULL, "should have been nulled out when transitioned to zombie"); +#endif + CodeBlob::flush(); CodeCache::free(this); } @@ -1500,29 +1500,18 @@ #if INCLUDE_JVMCI bool nmethod::do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred) { - bool is_unloaded = false; - // Follow JVMCI method - BarrierSet* bs = Universe::heap()->barrier_set(); if (_jvmci_installed_code != NULL) { - if (_jvmci_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_jvmci_installed_code)) { - if (!is_alive->do_object_b(_jvmci_installed_code)) { + if (JNIHandles::is_global_weak_cleared(_jvmci_installed_code)) { + if (_jvmci_installed_code_triggers_unloading) { + // jweak reference processing has already cleared the referent + make_unloaded(is_alive, NULL); + return true; + } else { clear_jvmci_installed_code(); } - } else { - if (can_unload(is_alive, (oop*)&_jvmci_installed_code, unloading_occurred)) { - return true; - } } } - - if (_speculation_log != NULL) { - if (!is_alive->do_object_b(_speculation_log)) { - bs->write_ref_nmethod_pre(&_speculation_log, this); - _speculation_log = NULL; - bs->write_ref_nmethod_post(&_speculation_log, this); - } - } - return is_unloaded; + return false; } #endif @@ -1594,15 +1583,6 @@ // (See comment above.) } -#if INCLUDE_JVMCI - if (_jvmci_installed_code != NULL) { - f->do_oop((oop*) &_jvmci_installed_code); - } - if (_speculation_log != NULL) { - f->do_oop((oop*) &_speculation_log); - } -#endif - RelocIterator iter(this, low_boundary); while (iter.next()) { @@ -2860,43 +2840,49 @@ #if INCLUDE_JVMCI void nmethod::clear_jvmci_installed_code() { - // write_ref_method_pre/post can only be safely called at a - // safepoint or while holding the CodeCache_lock - assert(CodeCache_lock->is_locked() || - SafepointSynchronize::is_at_safepoint(), "should be performed under a lock for consistency"); + assert_locked_or_safepoint(Patching_lock); if (_jvmci_installed_code != NULL) { - // This must be done carefully to maintain nmethod remembered sets properly - BarrierSet* bs = Universe::heap()->barrier_set(); - bs->write_ref_nmethod_pre(&_jvmci_installed_code, this); + JNIHandles::destroy_weak_global(_jvmci_installed_code); _jvmci_installed_code = NULL; - bs->write_ref_nmethod_post(&_jvmci_installed_code, this); + } +} + +void nmethod::clear_speculation_log() { + assert_locked_or_safepoint(Patching_lock); + if (_speculation_log != NULL) { + JNIHandles::destroy_weak_global(_speculation_log); + _speculation_log = NULL; } } void nmethod::maybe_invalidate_installed_code() { assert(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "should be performed under a lock for consistency"); - oop installed_code = jvmci_installed_code(); + oop installed_code = JNIHandles::resolve(_jvmci_installed_code); if (installed_code != NULL) { + // Update the values in the InstalledCode instance if it still refers to this nmethod nmethod* nm = (nmethod*)InstalledCode::address(installed_code); - if (nm == NULL || nm != this) { - // The link has been broken or the InstalledCode instance is - // associated with another nmethod so do nothing. - return; + if (nm == this) { + if (!is_alive()) { + // Break the link between nmethod and InstalledCode such that the nmethod + // can subsequently be flushed safely. The link must be maintained while + // the method could have live activations since invalidateInstalledCode + // might want to invalidate all existing activations. + InstalledCode::set_address(installed_code, 0); + InstalledCode::set_entryPoint(installed_code, 0); + } else if (is_not_entrant()) { + // Remove the entry point so any invocation will fail but keep + // the address link around that so that existing activations can + // be invalidated. + InstalledCode::set_entryPoint(installed_code, 0); + } } - if (!is_alive()) { - // Break the link between nmethod and InstalledCode such that the nmethod - // can subsequently be flushed safely. The link must be maintained while - // the method could have live activations since invalidateInstalledCode - // might want to invalidate all existing activations. - InstalledCode::set_address(installed_code, 0); - InstalledCode::set_entryPoint(installed_code, 0); - } else if (is_not_entrant()) { - // Remove the entry point so any invocation will fail but keep - // the address link around that so that existing activations can - // be invalidated. - InstalledCode::set_entryPoint(installed_code, 0); - } + } + if (!is_alive()) { + // Clear these out after the nmethod has been unregistered and any + // updates to the InstalledCode instance have been performed. + clear_jvmci_installed_code(); + clear_speculation_log(); } } @@ -2916,45 +2902,49 @@ { MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); // This relationship can only be checked safely under a lock - assert(nm == NULL || !nm->is_alive() || nm->jvmci_installed_code() == installedCode(), "sanity check"); + assert(!nm->is_alive() || nm->jvmci_installed_code() == installedCode(), "sanity check"); } #endif if (nm->is_alive()) { - // The nmethod state machinery maintains the link between the - // HotSpotInstalledCode and nmethod* so as long as the nmethod appears to be - // alive assume there is work to do and deoptimize the nmethod. + // Invalidating the InstalledCode means we want the nmethod + // to be deoptimized. nm->mark_for_deoptimization(); VM_Deoptimize op; VMThread::execute(&op); } + // Multiple threads could reach this point so we now need to + // lock and re-check the link to the nmethod so that only one + // thread clears it. MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); - // Check that it's still associated with the same nmethod and break - // the link if it is. if (InstalledCode::address(installedCode) == nativeMethod) { - InstalledCode::set_address(installedCode, 0); + InstalledCode::set_address(installedCode, 0); } } +oop nmethod::jvmci_installed_code() { + return JNIHandles::resolve(_jvmci_installed_code); +} + +oop nmethod::speculation_log() { + return JNIHandles::resolve(_speculation_log); +} + char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) { if (!this->is_compiled_by_jvmci()) { return NULL; } - oop installedCode = this->jvmci_installed_code(); - if (installedCode != NULL) { - oop installedCodeName = NULL; - if (installedCode->is_a(InstalledCode::klass())) { - installedCodeName = InstalledCode::name(installedCode); + oop installed_code = JNIHandles::resolve(_jvmci_installed_code); + if (installed_code != NULL) { + oop installed_code_name = NULL; + if (installed_code->is_a(InstalledCode::klass())) { + installed_code_name = InstalledCode::name(installed_code); } - if (installedCodeName != NULL) { - return java_lang_String::as_utf8_string(installedCodeName, buf, (int)buflen); - } else { - jio_snprintf(buf, buflen, "null"); - return buf; + if (installed_code_name != NULL) { + return java_lang_String::as_utf8_string(installed_code_name, buf, (int)buflen); } } - jio_snprintf(buf, buflen, "noInstalledCode"); - return buf; + return NULL; } #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/code/nmethod.hpp --- a/src/hotspot/share/code/nmethod.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/code/nmethod.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -63,9 +63,22 @@ jmethodID _jmethod_id; // Cache of method()->jmethod_id() #if INCLUDE_JVMCI - // Needed to keep nmethods alive that are not the default nmethod for the associated Method. - oop _jvmci_installed_code; - oop _speculation_log; + // A weak reference to an InstalledCode object associated with + // this nmethod. + jweak _jvmci_installed_code; + + // A weak reference to a SpeculationLog object associated with + // this nmethod. + jweak _speculation_log; + + // Determines whether this nmethod is unloaded when the + // referent in _jvmci_installed_code is cleared. This + // will be false if the referent is initialized to a + // HotSpotNMethod object whose isDefault field is true. + // That is, installed code other than a "default" + // HotSpotNMethod causes nmethod unloading. + // This field is ignored once _jvmci_installed_code is NULL. + bool _jvmci_installed_code_triggers_unloading; #endif // To support simple linked-list chaining of nmethods: @@ -192,8 +205,8 @@ AbstractCompiler* compiler, int comp_level #if INCLUDE_JVMCI - , Handle installed_code, - Handle speculation_log + , jweak installed_code, + jweak speculation_log #endif ); @@ -236,8 +249,8 @@ AbstractCompiler* compiler, int comp_level #if INCLUDE_JVMCI - , Handle installed_code = Handle(), - Handle speculation_log = Handle() + , jweak installed_code = NULL, + jweak speculation_log = NULL #endif ); @@ -433,27 +446,46 @@ void set_method(Method* method) { _method = method; } #if INCLUDE_JVMCI - oop jvmci_installed_code() { return _jvmci_installed_code ; } + // Gets the InstalledCode object associated with this nmethod + // which may be NULL if this nmethod was not compiled by JVMCI + // or the weak reference has been cleared. + oop jvmci_installed_code(); + + // Copies the value of the name field in the InstalledCode + // object (if any) associated with this nmethod into buf. + // Returns the value of buf if it was updated otherwise NULL. char* jvmci_installed_code_name(char* buf, size_t buflen); - // Update the state of any InstalledCode instance associated with + // Updates the state of the InstalledCode (if any) associated with // this nmethod based on the current value of _state. void maybe_invalidate_installed_code(); - // Helper function to invalidate InstalledCode instances + // Deoptimizes the nmethod (if any) in the address field of a given + // InstalledCode object. The address field is zeroed upon return. static void invalidate_installed_code(Handle installed_code, TRAPS); - oop speculation_log() { return _speculation_log ; } + // Gets the SpeculationLog object associated with this nmethod + // which may be NULL if this nmethod was not compiled by JVMCI + // or the weak reference has been cleared. + oop speculation_log(); private: + // Deletes the weak reference (if any) to the InstalledCode object + // associated with this nmethod. void clear_jvmci_installed_code(); + // Deletes the weak reference (if any) to the SpeculationLog object + // associated with this nmethod. + void clear_speculation_log(); + public: #endif protected: virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred); #if INCLUDE_JVMCI + // See comment for _jvmci_installed_code_triggers_unloading field. + // Returns whether this nmethod was unloaded. virtual bool do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/code/relocInfo.cpp --- a/src/hotspot/share/code/relocInfo.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/code/relocInfo.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -489,7 +489,7 @@ #ifndef _LP64 _target = (address) (intptr_t)unpack_1_int(); #else - int32_t lo, hi; + jint lo, hi; unpack_2_ints(lo, hi); jlong t = jlong_from(hi, lo);; _target = (address) t; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/code/scopeDesc.cpp --- a/src/hotspot/share/code/scopeDesc.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/code/scopeDesc.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -228,7 +228,7 @@ } } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (NOT_JVMCI(DoEscapeAnalysis &&) is_top() && _objects != NULL) { st->print_cr(" Objects"); for (int i = 0; i < _objects->length(); i++) { @@ -239,7 +239,7 @@ st->cr(); } } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI } #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/compiler/compileBroker.cpp --- a/src/hotspot/share/compiler/compileBroker.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/compiler/compileBroker.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -40,7 +41,6 @@ #include "oops/methodData.hpp" #include "oops/method.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/nativeLookup.hpp" #include "prims/whitebox.hpp" #include "runtime/arguments.hpp" @@ -108,7 +108,7 @@ bool CompileBroker::_initialized = false; volatile bool CompileBroker::_should_block = false; -volatile jint CompileBroker::_print_compilation_warning = 0; +volatile int CompileBroker::_print_compilation_warning = 0; volatile jint CompileBroker::_should_compile_new_jobs = run_compilation; // The installed compiler(s) diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/compiler/compileBroker.hpp --- a/src/hotspot/share/compiler/compileBroker.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/compiler/compileBroker.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -217,7 +217,7 @@ static int _sum_nmethod_code_size; static long _peak_compilation_time; - static volatile jint _print_compilation_warning; + static volatile int _print_compilation_warning; static JavaThread* make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, bool compiler_thread, TRAPS); static void init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/compiler/compileLog.cpp --- a/src/hotspot/share/compiler/compileLog.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/compiler/compileLog.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "ci/ciMethod.hpp" #include "code/codeCache.hpp" #include "compiler/compileLog.hpp" #include "memory/allocation.inline.hpp" #include "oops/method.hpp" -#include "prims/jvm.h" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/compiler/compilerOracle.cpp --- a/src/hotspot/share/compiler/compilerOracle.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/compiler/compilerOracle.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "compiler/compilerOracle.hpp" #include "compiler/methodMatcher.hpp" #include "memory/allocation.inline.hpp" @@ -31,7 +32,6 @@ #include "oops/klass.hpp" #include "oops/method.hpp" #include "oops/symbol.hpp" -#include "prims/jvm.h" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" #include "runtime/os.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/compiler/oopMap.cpp --- a/src/hotspot/share/compiler/oopMap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/compiler/oopMap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -268,9 +268,9 @@ #if !defined(TIERED) && !defined(INCLUDE_JVMCI) COMPILER1_PRESENT(ShouldNotReachHere();) #endif // !defined(TIERED) && !defined(INCLUDE_JVMCI) -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::add(derived, base); -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI } @@ -461,12 +461,12 @@ #if !defined(TIERED) && !defined(INCLUDE_JVMCI) COMPILER1_PRESENT(return false); #endif // !TIERED -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI OopMapStream oms(this,OopMapValue::derived_oop_value); return oms.is_done(); #else return false; -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI } #endif //PRODUCT @@ -726,7 +726,7 @@ //------------------------------DerivedPointerTable--------------------------- -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI class DerivedPointerEntry : public CHeapObj { private: @@ -819,4 +819,4 @@ _active = false; } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/compiler/oopMap.hpp --- a/src/hotspot/share/compiler/oopMap.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/compiler/oopMap.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -427,7 +427,7 @@ // oops, it is filled in with references to all locations that contains a // derived oop (assumed to be very few). When the GC is complete, the derived // pointers are updated based on their base pointers new value and an offset. -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI class DerivedPointerTable : public AllStatic { friend class VMStructs; private: @@ -463,6 +463,6 @@ } } }; -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI #endif // SHARE_VM_COMPILER_OOPMAP_HPP diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/cms/cmsHeap.hpp --- a/src/hotspot/share/gc/cms/cmsHeap.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/cms/cmsHeap.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -39,14 +39,16 @@ class WorkGang; class CMSHeap : public GenCollectedHeap { + +protected: + virtual void check_gen_kinds(); + public: CMSHeap(GenCollectorPolicy *policy); // Returns JNI_OK on success virtual jint initialize(); - virtual void check_gen_kinds(); - // Convenience function to be used in situations where the heap type can be // asserted to be this type. static CMSHeap* heap(); @@ -70,10 +72,6 @@ // supports. Caller does not hold the Heap_lock on entry. void collect(GCCause::Cause cause); - bool is_in_closed_subset(const void* p) const { - return is_in_reserved(p); - } - bool card_mark_must_follow_store() const { return true; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp --- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -57,6 +57,7 @@ // Defaults are 0 so things will break badly if incorrectly initialized. size_t CompactibleFreeListSpace::IndexSetStart = 0; size_t CompactibleFreeListSpace::IndexSetStride = 0; +size_t CompactibleFreeListSpace::_min_chunk_size_in_bytes = 0; size_t MinChunkSize = 0; @@ -66,8 +67,8 @@ // MinChunkSize should be a multiple of MinObjAlignment and be large enough // for chunks to contain a FreeChunk. - size_t min_chunk_size_in_bytes = align_up(sizeof(FreeChunk), MinObjAlignmentInBytes); - MinChunkSize = min_chunk_size_in_bytes / BytesPerWord; + _min_chunk_size_in_bytes = align_up(sizeof(FreeChunk), MinObjAlignmentInBytes); + MinChunkSize = _min_chunk_size_in_bytes / BytesPerWord; assert(IndexSetStart == 0 && IndexSetStride == 0, "already set"); IndexSetStart = MinChunkSize; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp --- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -118,6 +118,7 @@ }; static size_t IndexSetStart; static size_t IndexSetStride; + static size_t _min_chunk_size_in_bytes; private: enum FitStrategyOptions { @@ -134,6 +135,7 @@ // A lock protecting the free lists and free blocks; // mutable because of ubiquity of locking even for otherwise const methods mutable Mutex _freelistLock; + // Locking verifier convenience function void assert_locked() const PRODUCT_RETURN; void assert_locked(const Mutex* lock) const PRODUCT_RETURN; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp --- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2296,7 +2296,7 @@ // way with the marking information used by GC. NoRefDiscovery no_discovery(ref_processor()); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTableDeactivate dpt_deact; #endif @@ -2869,7 +2869,7 @@ print_eden_and_survivor_chunk_arrays(); { -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTableDeactivate dpt_deact; #endif if (CMSParallelInitialMarkEnabled) { @@ -4171,7 +4171,7 @@ print_eden_and_survivor_chunk_arrays(); { -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTableDeactivate dpt_deact; #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/cms/vmStructs_cms.hpp --- a/src/hotspot/share/gc/cms/vmStructs_cms.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/cms/vmStructs_cms.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -30,7 +30,8 @@ static_field) \ nonstatic_field(CompactibleFreeListSpace, _collector, CMSCollector*) \ nonstatic_field(CompactibleFreeListSpace, _bt, BlockOffsetArrayNonContigSpace) \ - \ + static_field(CompactibleFreeListSpace, _min_chunk_size_in_bytes, size_t) \ + nonstatic_field(CMSBitMap, _bmStartWord, HeapWord*) \ nonstatic_field(CMSBitMap, _bmWordSize, size_t) \ nonstatic_field(CMSBitMap, _shifter, const int) \ nonstatic_field(CMSBitMap, _bm, BitMapView) \ @@ -63,6 +64,7 @@ declare_toplevel_type(LinearAllocBlock) #define VM_INT_CONSTANTS_CMS(declare_constant) \ + declare_constant(CompactibleFreeListSpace::IndexSetSize) \ declare_constant(Generation::ConcurrentMarkSweep) \ #endif // SHARE_VM_GC_CMS_VMSTRUCTS_CMS_HPP diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/concurrentG1Refine.cpp --- a/src/hotspot/share/gc/g1/concurrentG1Refine.cpp Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,370 +0,0 @@ -/* - * Copyright (c) 2001, 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. - * - * 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 "gc/g1/concurrentG1Refine.hpp" -#include "gc/g1/concurrentG1RefineThread.hpp" -#include "gc/g1/g1YoungRemSetSamplingThread.hpp" -#include "logging/log.hpp" -#include "runtime/java.hpp" -#include "runtime/thread.hpp" -#include "utilities/debug.hpp" -#include "utilities/globalDefinitions.hpp" -#include "utilities/pair.hpp" -#include - -// Arbitrary but large limits, to simplify some of the zone calculations. -// The general idea is to allow expressions like -// MIN2(x OP y, max_XXX_zone) -// without needing to check for overflow in "x OP y", because the -// ranges for x and y have been restricted. -STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2)); -const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort); -const size_t max_green_zone = max_yellow_zone / 2; -const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue. -STATIC_ASSERT(max_yellow_zone <= max_red_zone); - -// Range check assertions for green zone values. -#define assert_zone_constraints_g(green) \ - do { \ - size_t azc_g_green = (green); \ - assert(azc_g_green <= max_green_zone, \ - "green exceeds max: " SIZE_FORMAT, azc_g_green); \ - } while (0) - -// Range check assertions for green and yellow zone values. -#define assert_zone_constraints_gy(green, yellow) \ - do { \ - size_t azc_gy_green = (green); \ - size_t azc_gy_yellow = (yellow); \ - assert_zone_constraints_g(azc_gy_green); \ - assert(azc_gy_yellow <= max_yellow_zone, \ - "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow); \ - assert(azc_gy_green <= azc_gy_yellow, \ - "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")", \ - azc_gy_green, azc_gy_yellow); \ - } while (0) - -// Range check assertions for green, yellow, and red zone values. -#define assert_zone_constraints_gyr(green, yellow, red) \ - do { \ - size_t azc_gyr_green = (green); \ - size_t azc_gyr_yellow = (yellow); \ - size_t azc_gyr_red = (red); \ - assert_zone_constraints_gy(azc_gyr_green, azc_gyr_yellow); \ - assert(azc_gyr_red <= max_red_zone, \ - "red exceeds max: " SIZE_FORMAT, azc_gyr_red); \ - assert(azc_gyr_yellow <= azc_gyr_red, \ - "yellow (" SIZE_FORMAT ") exceeds red (" SIZE_FORMAT ")", \ - azc_gyr_yellow, azc_gyr_red); \ - } while (0) - -// Logging tag sequence for refinement control updates. -#define CTRL_TAGS gc, ergo, refine - -// For logging zone values, ensuring consistency of level and tags. -#define LOG_ZONES(...) log_debug( CTRL_TAGS )(__VA_ARGS__) - -// Package for pair of refinement thread activation and deactivation -// thresholds. The activation and deactivation levels are resp. the first -// and second values of the pair. -typedef Pair Thresholds; -inline size_t activation_level(const Thresholds& t) { return t.first; } -inline size_t deactivation_level(const Thresholds& t) { return t.second; } - -static Thresholds calc_thresholds(size_t green_zone, - size_t yellow_zone, - uint worker_i) { - double yellow_size = yellow_zone - green_zone; - double step = yellow_size / ConcurrentG1Refine::thread_num(); - if (worker_i == 0) { - // Potentially activate worker 0 more aggressively, to keep - // available buffers near green_zone value. When yellow_size is - // large we don't want to allow a full step to accumulate before - // doing any processing, as that might lead to significantly more - // than green_zone buffers to be processed by update_rs. - step = MIN2(step, ParallelGCThreads / 2.0); - } - size_t activate_offset = static_cast(ceil(step * (worker_i + 1))); - size_t deactivate_offset = static_cast(floor(step * worker_i)); - return Thresholds(green_zone + activate_offset, - green_zone + deactivate_offset); -} - -ConcurrentG1Refine::ConcurrentG1Refine(size_t green_zone, - size_t yellow_zone, - size_t red_zone, - size_t min_yellow_zone_size) : - _threads(NULL), - _sample_thread(NULL), - _n_worker_threads(thread_num()), - _green_zone(green_zone), - _yellow_zone(yellow_zone), - _red_zone(red_zone), - _min_yellow_zone_size(min_yellow_zone_size) -{ - assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone); -} - -static size_t calc_min_yellow_zone_size() { - size_t step = G1ConcRefinementThresholdStep; - uint n_workers = ConcurrentG1Refine::thread_num(); - if ((max_yellow_zone / step) < n_workers) { - return max_yellow_zone; - } else { - return step * n_workers; - } -} - -static size_t calc_init_green_zone() { - size_t green = G1ConcRefinementGreenZone; - if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) { - green = ParallelGCThreads; - } - return MIN2(green, max_green_zone); -} - -static size_t calc_init_yellow_zone(size_t green, size_t min_size) { - size_t config = G1ConcRefinementYellowZone; - size_t size = 0; - if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) { - size = green * 2; - } else if (green < config) { - size = config - green; - } - size = MAX2(size, min_size); - size = MIN2(size, max_yellow_zone); - return MIN2(green + size, max_yellow_zone); -} - -static size_t calc_init_red_zone(size_t green, size_t yellow) { - size_t size = yellow - green; - if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) { - size_t config = G1ConcRefinementRedZone; - if (yellow < config) { - size = MAX2(size, config - yellow); - } - } - return MIN2(yellow + size, max_red_zone); -} - -ConcurrentG1Refine* ConcurrentG1Refine::create(jint* ecode) { - size_t min_yellow_zone_size = calc_min_yellow_zone_size(); - size_t green_zone = calc_init_green_zone(); - size_t yellow_zone = calc_init_yellow_zone(green_zone, min_yellow_zone_size); - size_t red_zone = calc_init_red_zone(green_zone, yellow_zone); - - LOG_ZONES("Initial Refinement Zones: " - "green: " SIZE_FORMAT ", " - "yellow: " SIZE_FORMAT ", " - "red: " SIZE_FORMAT ", " - "min yellow size: " SIZE_FORMAT, - green_zone, yellow_zone, red_zone, min_yellow_zone_size); - - ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(green_zone, - yellow_zone, - red_zone, - min_yellow_zone_size); - - if (cg1r == NULL) { - *ecode = JNI_ENOMEM; - vm_shutdown_during_initialization("Could not create ConcurrentG1Refine"); - return NULL; - } - - cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_worker_threads, mtGC); - if (cg1r->_threads == NULL) { - *ecode = JNI_ENOMEM; - vm_shutdown_during_initialization("Could not allocate an array for ConcurrentG1RefineThread"); - return NULL; - } - - uint worker_id_offset = DirtyCardQueueSet::num_par_ids(); - - ConcurrentG1RefineThread *next = NULL; - for (uint i = cg1r->_n_worker_threads - 1; i != UINT_MAX; i--) { - Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i); - ConcurrentG1RefineThread* t = - new ConcurrentG1RefineThread(cg1r, - next, - worker_id_offset, - i, - activation_level(thresholds), - deactivation_level(thresholds)); - assert(t != NULL, "Conc refine should have been created"); - if (t->osthread() == NULL) { - *ecode = JNI_ENOMEM; - vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread"); - return NULL; - } - - assert(t->cg1r() == cg1r, "Conc refine thread should refer to this"); - cg1r->_threads[i] = t; - next = t; - } - - cg1r->_sample_thread = new G1YoungRemSetSamplingThread(); - if (cg1r->_sample_thread->osthread() == NULL) { - *ecode = JNI_ENOMEM; - vm_shutdown_during_initialization("Could not create G1YoungRemSetSamplingThread"); - return NULL; - } - - *ecode = JNI_OK; - return cg1r; -} - -void ConcurrentG1Refine::stop() { - for (uint i = 0; i < _n_worker_threads; i++) { - _threads[i]->stop(); - } - _sample_thread->stop(); -} - -void ConcurrentG1Refine::update_thread_thresholds() { - for (uint i = 0; i < _n_worker_threads; i++) { - Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i); - _threads[i]->update_thresholds(activation_level(thresholds), - deactivation_level(thresholds)); - } -} - -ConcurrentG1Refine::~ConcurrentG1Refine() { - for (uint i = 0; i < _n_worker_threads; i++) { - delete _threads[i]; - } - FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads); - - delete _sample_thread; -} - -void ConcurrentG1Refine::threads_do(ThreadClosure *tc) { - worker_threads_do(tc); - tc->do_thread(_sample_thread); -} - -void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) { - for (uint i = 0; i < _n_worker_threads; i++) { - tc->do_thread(_threads[i]); - } -} - -uint ConcurrentG1Refine::thread_num() { - return G1ConcRefinementThreads; -} - -void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const { - for (uint i = 0; i < _n_worker_threads; ++i) { - _threads[i]->print_on(st); - st->cr(); - } - _sample_thread->print_on(st); - st->cr(); -} - -static size_t calc_new_green_zone(size_t green, - double update_rs_time, - size_t update_rs_processed_buffers, - double goal_ms) { - // Adjust green zone based on whether we're meeting the time goal. - // Limit to max_green_zone. - const double inc_k = 1.1, dec_k = 0.9; - if (update_rs_time > goal_ms) { - if (green > 0) { - green = static_cast(green * dec_k); - } - } else if (update_rs_time < goal_ms && - update_rs_processed_buffers > green) { - green = static_cast(MAX2(green * inc_k, green + 1.0)); - green = MIN2(green, max_green_zone); - } - return green; -} - -static size_t calc_new_yellow_zone(size_t green, size_t min_yellow_size) { - size_t size = green * 2; - size = MAX2(size, min_yellow_size); - return MIN2(green + size, max_yellow_zone); -} - -static size_t calc_new_red_zone(size_t green, size_t yellow) { - return MIN2(yellow + (yellow - green), max_red_zone); -} - -void ConcurrentG1Refine::update_zones(double update_rs_time, - size_t update_rs_processed_buffers, - double goal_ms) { - log_trace( CTRL_TAGS )("Updating Refinement Zones: " - "update_rs time: %.3fms, " - "update_rs buffers: " SIZE_FORMAT ", " - "update_rs goal time: %.3fms", - update_rs_time, - update_rs_processed_buffers, - goal_ms); - - _green_zone = calc_new_green_zone(_green_zone, - update_rs_time, - update_rs_processed_buffers, - goal_ms); - _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size); - _red_zone = calc_new_red_zone(_green_zone, _yellow_zone); - - assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone); - LOG_ZONES("Updated Refinement Zones: " - "green: " SIZE_FORMAT ", " - "yellow: " SIZE_FORMAT ", " - "red: " SIZE_FORMAT, - _green_zone, _yellow_zone, _red_zone); -} - -void ConcurrentG1Refine::adjust(double update_rs_time, - size_t update_rs_processed_buffers, - double goal_ms) { - DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - - if (G1UseAdaptiveConcRefinement) { - update_zones(update_rs_time, update_rs_processed_buffers, goal_ms); - update_thread_thresholds(); - - // Change the barrier params - if (_n_worker_threads == 0) { - // Disable dcqs notification when there are no threads to notify. - dcqs.set_process_completed_threshold(INT_MAX); - } else { - // Worker 0 is the primary; wakeup is via dcqs notification. - STATIC_ASSERT(max_yellow_zone <= INT_MAX); - size_t activate = _threads[0]->activation_threshold(); - dcqs.set_process_completed_threshold((int)activate); - } - dcqs.set_max_completed_queue((int)red_zone()); - } - - size_t curr_queue_size = dcqs.completed_buffers_num(); - if (curr_queue_size >= yellow_zone()) { - dcqs.set_completed_queue_padding(curr_queue_size); - } else { - dcqs.set_completed_queue_padding(0); - } - dcqs.notify_if_necessary(); -} diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/concurrentG1Refine.hpp --- a/src/hotspot/share/gc/g1/concurrentG1Refine.hpp Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2001, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP -#define SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP - -#include "memory/allocation.hpp" -#include "utilities/globalDefinitions.hpp" - -// Forward decl -class CardTableEntryClosure; -class ConcurrentG1RefineThread; -class G1YoungRemSetSamplingThread; -class outputStream; -class ThreadClosure; - -class ConcurrentG1Refine: public CHeapObj { - G1YoungRemSetSamplingThread* _sample_thread; - - ConcurrentG1RefineThread** _threads; - uint _n_worker_threads; - /* - * The value of the update buffer queue length falls into one of 3 zones: - * green, yellow, red. If the value is in [0, green) nothing is - * done, the buffers are left unprocessed to enable the caching effect of the - * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement - * threads are gradually activated. In [yellow, red) all threads are - * running. If the length becomes red (max queue length) the mutators start - * processing the buffers. - * - * There are some interesting cases (when G1UseAdaptiveConcRefinement - * is turned off): - * 1) green = yellow = red = 0. In this case the mutator will process all - * buffers. Except for those that are created by the deferred updates - * machinery during a collection. - * 2) green = 0. Means no caching. Can be a good way to minimize the - * amount of time spent updating rsets during a collection. - */ - size_t _green_zone; - size_t _yellow_zone; - size_t _red_zone; - size_t _min_yellow_zone_size; - - ConcurrentG1Refine(size_t green_zone, - size_t yellow_zone, - size_t red_zone, - size_t min_yellow_zone_size); - - // Update green/yellow/red zone values based on how well goals are being met. - void update_zones(double update_rs_time, - size_t update_rs_processed_buffers, - double goal_ms); - - // Update thread thresholds to account for updated zone values. - void update_thread_thresholds(); - - public: - ~ConcurrentG1Refine(); - - // Returns ConcurrentG1Refine instance if succeeded to create/initialize ConcurrentG1Refine and ConcurrentG1RefineThread. - // Otherwise, returns NULL with error code. - static ConcurrentG1Refine* create(jint* ecode); - - void stop(); - - void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms); - - // Iterate over all concurrent refinement threads - void threads_do(ThreadClosure *tc); - - // Iterate over all worker refinement threads - void worker_threads_do(ThreadClosure * tc); - - // The RS sampling thread has nothing to do with refinement, but is here for now. - G1YoungRemSetSamplingThread * sampling_thread() const { return _sample_thread; } - - static uint thread_num(); - - void print_worker_threads_on(outputStream* st) const; - - size_t green_zone() const { return _green_zone; } - size_t yellow_zone() const { return _yellow_zone; } - size_t red_zone() const { return _red_zone; } -}; - -#endif // SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/concurrentG1RefineThread.cpp --- a/src/hotspot/share/gc/g1/concurrentG1RefineThread.cpp Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2001, 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. - * - * 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 "gc/g1/concurrentG1Refine.hpp" -#include "gc/g1/concurrentG1RefineThread.hpp" -#include "gc/g1/g1CollectedHeap.inline.hpp" -#include "gc/g1/g1RemSet.hpp" -#include "gc/shared/suspendibleThreadSet.hpp" -#include "logging/log.hpp" -#include "memory/resourceArea.hpp" -#include "runtime/handles.inline.hpp" -#include "runtime/mutexLocker.hpp" - -ConcurrentG1RefineThread:: -ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next, - uint worker_id_offset, uint worker_id, - size_t activate, size_t deactivate) : - ConcurrentGCThread(), - _worker_id_offset(worker_id_offset), - _worker_id(worker_id), - _active(false), - _next(next), - _monitor(NULL), - _cg1r(cg1r), - _vtime_accum(0.0), - _activation_threshold(activate), - _deactivation_threshold(deactivate) -{ - - // Each thread has its own monitor. The i-th thread is responsible for signaling - // to thread i+1 if the number of buffers in the queue exceeds a threshold for this - // thread. Monitors are also used to wake up the threads during termination. - // The 0th (primary) worker is notified by mutator threads and has a special monitor. - if (!is_primary()) { - _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true, - Monitor::_safepoint_check_never); - } else { - _monitor = DirtyCardQ_CBL_mon; - } - - // set name - set_name("G1 Refine#%d", worker_id); - create_and_start(); -} - -void ConcurrentG1RefineThread::update_thresholds(size_t activate, - size_t deactivate) { - assert(deactivate < activate, "precondition"); - _activation_threshold = activate; - _deactivation_threshold = deactivate; -} - -void ConcurrentG1RefineThread::wait_for_completed_buffers() { - MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); - while (!should_terminate() && !is_active()) { - _monitor->wait(Mutex::_no_safepoint_check_flag); - } -} - -bool ConcurrentG1RefineThread::is_active() { - DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - return is_primary() ? dcqs.process_completed_buffers() : _active; -} - -void ConcurrentG1RefineThread::activate() { - MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); - if (!is_primary()) { - set_active(true); - } else { - DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - dcqs.set_process_completed(true); - } - _monitor->notify(); -} - -void ConcurrentG1RefineThread::deactivate() { - MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); - if (!is_primary()) { - set_active(false); - } else { - DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - dcqs.set_process_completed(false); - } -} - -void ConcurrentG1RefineThread::run_service() { - _vtime_start = os::elapsedVTime(); - - while (!should_terminate()) { - // Wait for work - wait_for_completed_buffers(); - if (should_terminate()) { - break; - } - - size_t buffers_processed = 0; - DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT, - _worker_id, _activation_threshold, dcqs.completed_buffers_num()); - - { - SuspendibleThreadSetJoiner sts_join; - - while (!should_terminate()) { - if (sts_join.should_yield()) { - sts_join.yield(); - continue; // Re-check for termination after yield delay. - } - - size_t curr_buffer_num = dcqs.completed_buffers_num(); - // If the number of the buffers falls down into the yellow zone, - // that means that the transition period after the evacuation pause has ended. - if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) { - dcqs.set_completed_queue_padding(0); - } - - // Check if we need to activate the next thread. - if ((_next != NULL) && - !_next->is_active() && - (curr_buffer_num > _next->_activation_threshold)) { - _next->activate(); - } - - // Process the next buffer, if there are enough left. - if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) { - break; // Deactivate, number of buffers fell below threshold. - } - ++buffers_processed; - } - } - - deactivate(); - log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT - ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT, - _worker_id, _deactivation_threshold, - dcqs.completed_buffers_num(), - buffers_processed); - - if (os::supports_vtime()) { - _vtime_accum = (os::elapsedVTime() - _vtime_start); - } else { - _vtime_accum = 0.0; - } - } - - log_debug(gc, refine)("Stopping %d", _worker_id); -} - -void ConcurrentG1RefineThread::stop_service() { - MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); - _monitor->notify(); -} diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/concurrentG1RefineThread.hpp --- a/src/hotspot/share/gc/g1/concurrentG1RefineThread.hpp Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2001, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_GC_G1_CONCURRENTG1REFINETHREAD_HPP -#define SHARE_VM_GC_G1_CONCURRENTG1REFINETHREAD_HPP - -#include "gc/g1/dirtyCardQueue.hpp" -#include "gc/shared/concurrentGCThread.hpp" - -// Forward Decl. -class CardTableEntryClosure; -class ConcurrentG1Refine; - -// One or more G1 Concurrent Refinement Threads may be active if concurrent -// refinement is in progress. -class ConcurrentG1RefineThread: public ConcurrentGCThread { - friend class VMStructs; - friend class G1CollectedHeap; - - double _vtime_start; // Initial virtual time. - double _vtime_accum; // Accumulated virtual time. - uint _worker_id; - uint _worker_id_offset; - - // The refinement threads collection is linked list. A predecessor can activate a successor - // when the number of the rset update buffer crosses a certain threshold. A successor - // would self-deactivate when the number of the buffers falls below the threshold. - bool _active; - ConcurrentG1RefineThread* _next; - Monitor* _monitor; - ConcurrentG1Refine* _cg1r; - - // This thread's activation/deactivation thresholds - size_t _activation_threshold; - size_t _deactivation_threshold; - - void wait_for_completed_buffers(); - - void set_active(bool x) { _active = x; } - bool is_active(); - void activate(); - void deactivate(); - - bool is_primary() { return (_worker_id == 0); } - - void run_service(); - void stop_service(); - -public: - // Constructor - ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next, - uint worker_id_offset, uint worker_id, - size_t activate, size_t deactivate); - - void update_thresholds(size_t activate, size_t deactivate); - size_t activation_threshold() const { return _activation_threshold; } - - // Total virtual time so far. - double vtime_accum() { return _vtime_accum; } - - ConcurrentG1Refine* cg1r() { return _cg1r; } -}; - -#endif // SHARE_VM_GC_G1_CONCURRENTG1REFINETHREAD_HPP diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/concurrentMarkThread.cpp --- a/src/hotspot/share/gc/g1/concurrentMarkThread.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/concurrentMarkThread.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -111,16 +111,31 @@ } }; -// Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU. +double ConcurrentMarkThread::mmu_sleep_time(G1Policy* g1_policy, bool remark) { + // There are 3 reasons to use SuspendibleThreadSetJoiner. + // 1. To avoid concurrency problem. + // - G1MMUTracker::add_pause(), when_sec() and its variation(when_ms() etc..) can be called + // concurrently from ConcurrentMarkThread and VMThread. + // 2. If currently a gc is running, but it has not yet updated the MMU, + // we will not forget to consider that pause in the MMU calculation. + // 3. If currently a gc is running, ConcurrentMarkThread will wait it to be finished. + // And then sleep for predicted amount of time by delay_to_keep_mmu(). + SuspendibleThreadSetJoiner sts_join; + + const G1Analytics* analytics = g1_policy->analytics(); + double now = os::elapsedTime(); + double prediction_ms = remark ? analytics->predict_remark_time_ms() + : analytics->predict_cleanup_time_ms(); + G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker(); + return mmu_tracker->when_ms(now, prediction_ms); +} + void ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) { - const G1Analytics* analytics = g1_policy->analytics(); if (g1_policy->adaptive_young_list_length()) { - double now = os::elapsedTime(); - double prediction_ms = remark ? analytics->predict_remark_time_ms() - : analytics->predict_cleanup_time_ms(); - G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker(); - jlong sleep_time_ms = mmu_tracker->when_ms(now, prediction_ms); - os::sleep(this, sleep_time_ms, false); + jlong sleep_time_ms = mmu_sleep_time(g1_policy, remark); + if (!cm()->has_aborted() && sleep_time_ms > 0) { + os::sleep(this, sleep_time_ms, false); + } } } @@ -349,9 +364,11 @@ if (!cm()->has_aborted()) { delay_to_keep_mmu(g1_policy, false /* cleanup */); - CMCleanUp cl_cl(_cm); - VM_CGC_Operation op(&cl_cl, "Pause Cleanup"); - VMThread::execute(&op); + if (!cm()->has_aborted()) { + CMCleanUp cl_cl(_cm); + VM_CGC_Operation op(&cl_cl, "Pause Cleanup"); + VMThread::execute(&op); + } } else { // We don't want to update the marking status if a GC pause // is already underway. diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/concurrentMarkThread.hpp --- a/src/hotspot/share/gc/g1/concurrentMarkThread.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/concurrentMarkThread.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -55,7 +55,9 @@ ConcurrentGCPhaseManager::Stack _phase_manager_stack; void sleepBeforeNextCycle(); + // Delay marking to meet MMU. void delay_to_keep_mmu(G1Policy* g1_policy, bool remark); + double mmu_sleep_time(G1Policy* g1_policy, bool remark); void run_service(); void stop_service(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1CollectedHeap.cpp --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -29,14 +29,14 @@ #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "gc/g1/bufferingOopClosure.hpp" -#include "gc/g1/concurrentG1Refine.hpp" -#include "gc/g1/concurrentG1RefineThread.hpp" #include "gc/g1/concurrentMarkThread.inline.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectionSet.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorState.hpp" +#include "gc/g1/g1ConcurrentRefine.hpp" +#include "gc/g1/g1ConcurrentRefineThread.hpp" #include "gc/g1/g1EvacStats.inline.hpp" #include "gc/g1/g1FullGCScope.hpp" #include "gc/g1/g1GCPhaseTimes.hpp" @@ -54,6 +54,7 @@ #include "gc/g1/g1SerialFullCollector.hpp" #include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1YCTypes.hpp" +#include "gc/g1/g1YoungRemSetSamplingThread.hpp" #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/g1/heapRegionSet.inline.hpp" @@ -1541,6 +1542,7 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* collector_policy) : CollectedHeap(), + _young_gen_sampling_thread(NULL), _collector_policy(collector_policy), _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()), _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()), @@ -1554,7 +1556,7 @@ _bot(NULL), _hot_card_cache(NULL), _g1_rem_set(NULL), - _cg1r(NULL), + _cr(NULL), _g1mm(NULL), _preserved_marks_set(true /* in_c_heap */), _secondary_free_list("Secondary Free List", new SecondaryFreeRegionListMtSafeChecker()), @@ -1633,10 +1635,19 @@ jint G1CollectedHeap::initialize_concurrent_refinement() { jint ecode = JNI_OK; - _cg1r = ConcurrentG1Refine::create(&ecode); + _cr = G1ConcurrentRefine::create(&ecode); return ecode; } +jint G1CollectedHeap::initialize_young_gen_sampling_thread() { + _young_gen_sampling_thread = new G1YoungRemSetSamplingThread(); + if (_young_gen_sampling_thread->osthread() == NULL) { + vm_shutdown_during_initialization("Could not create G1YoungRemSetSamplingThread"); + return JNI_ENOMEM; + } + return JNI_OK; +} + jint G1CollectedHeap::initialize() { CollectedHeap::pre_initialize(); os::enable_vtime(); @@ -1789,10 +1800,15 @@ return ecode; } + ecode = initialize_young_gen_sampling_thread(); + if (ecode != JNI_OK) { + return ecode; + } + JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, DirtyCardQ_FL_lock, - (int)concurrent_g1_refine()->yellow_zone(), - (int)concurrent_g1_refine()->red_zone(), + (int)concurrent_refine()->yellow_zone(), + (int)concurrent_refine()->red_zone(), Shared_DirtyCardQ_lock, NULL, // fl_owner true); // init_free_ids @@ -1836,7 +1852,8 @@ // Stop all concurrent threads. We do this to make sure these threads // do not continue to execute and access resources (e.g. logging) // that are destroyed during shutdown. - _cg1r->stop(); + _cr->stop(); + _young_gen_sampling_thread->stop(); _cmThread->stop(); if (G1StringDedup::is_enabled()) { G1StringDedup::stop(); @@ -2390,9 +2407,8 @@ st->print(" %-20s", "garbage-first heap"); st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", capacity()/K, used_unlocked()/K); - st->print(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", + st->print(" [" PTR_FORMAT ", " PTR_FORMAT ")", p2i(_hrm.reserved().start()), - p2i(_hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords), p2i(_hrm.reserved().end())); st->cr(); st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K); @@ -2437,7 +2453,8 @@ _cmThread->print_on(st); st->cr(); _cm->print_worker_threads_on(st); - _cg1r->print_worker_threads_on(st); // also prints the sample thread + _cr->print_threads_on(st); + _young_gen_sampling_thread->print_on(st); if (G1StringDedup::is_enabled()) { G1StringDedup::print_worker_threads_on(st); } @@ -2447,7 +2464,8 @@ workers()->threads_do(tc); tc->do_thread(_cmThread); _cm->threads_do(tc); - _cg1r->threads_do(tc); // also iterates over the sample thread + _cr->threads_do(tc); + tc->do_thread(_young_gen_sampling_thread); if (G1StringDedup::is_enabled()) { G1StringDedup::threads_do(tc); } @@ -2579,7 +2597,7 @@ // FIXME: what is this about? // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled" // is set. -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_empty(), "derived pointer present"); #endif // always_do_update_barrier = true; @@ -2992,7 +3010,7 @@ _verifier->check_bitmaps("GC Start"); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::clear(); #endif @@ -3622,7 +3640,7 @@ class G1KlassCleaningTask : public StackObj { BoolObjectClosure* _is_alive; - volatile jint _clean_klass_tree_claimed; + volatile int _clean_klass_tree_claimed; ClassLoaderDataGraphKlassIteratorAtomic _klass_iterator; public: @@ -3638,7 +3656,7 @@ return false; } - return Atomic::cmpxchg(1, (jint*)&_clean_klass_tree_claimed, 0) == 0; + return Atomic::cmpxchg(1, &_clean_klass_tree_claimed, 0) == 0; } InstanceKlass* claim_next_klass() { @@ -3675,7 +3693,7 @@ class G1ResolvedMethodCleaningTask : public StackObj { BoolObjectClosure* _is_alive; - volatile jint _resolved_method_task_claimed; + volatile int _resolved_method_task_claimed; public: G1ResolvedMethodCleaningTask(BoolObjectClosure* is_alive) : _is_alive(is_alive), _resolved_method_task_claimed(0) {} @@ -3684,7 +3702,7 @@ if (_resolved_method_task_claimed) { return false; } - return Atomic::cmpxchg(1, (jint*)&_resolved_method_task_claimed, 0) == 0; + return Atomic::cmpxchg(1, &_resolved_method_task_claimed, 0) == 0; } // These aren't big, one thread can do it all. @@ -4421,7 +4439,7 @@ purge_code_root_memory(); redirty_logged_cards(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI double start = os::elapsedTime(); DerivedPointerTable::update_pointers(); g1_policy()->phase_times()->record_derived_pointer_table_update_time((os::elapsedTime() - start) * 1000.0); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1CollectedHeap.hpp --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -73,10 +73,11 @@ class G1Policy; class G1HotCardCache; class G1RemSet; +class G1YoungRemSetSamplingThread; class HeapRegionRemSetIterator; class G1ConcurrentMark; class ConcurrentMarkThread; -class ConcurrentG1Refine; +class G1ConcurrentRefine; class GenerationCounters; class STWGCTimer; class G1NewTracer; @@ -142,6 +143,8 @@ friend class G1CheckCSetFastTableClosure; private: + G1YoungRemSetSamplingThread* _young_gen_sampling_thread; + WorkGang* _workers; G1CollectorPolicy* _collector_policy; @@ -553,6 +556,8 @@ // during GC into global variables. void merge_per_thread_state_info(G1ParScanThreadStateSet* per_thread_states); public: + G1YoungRemSetSamplingThread* sampling_thread() const { return _young_gen_sampling_thread; } + WorkGang* workers() const { return _workers; } G1Allocator* allocator() { @@ -806,7 +811,7 @@ ConcurrentMarkThread* _cmThread; // The concurrent refiner. - ConcurrentG1Refine* _cg1r; + G1ConcurrentRefine* _cr; // The parallel task queues RefToScanQueueSet *_task_queues; @@ -959,6 +964,7 @@ private: jint initialize_concurrent_refinement(); + jint initialize_young_gen_sampling_thread(); public: // Initialize the G1CollectedHeap to have the initial and // maximum sizes and remembered and barrier sets @@ -1389,7 +1395,7 @@ // Refinement - ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; } + G1ConcurrentRefine* concurrent_refine() const { return _cr; } // Optimized nmethod scanning support routines diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2001, 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. + * + * 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 "gc/g1/g1ConcurrentRefine.hpp" +#include "gc/g1/g1ConcurrentRefineThread.hpp" +#include "logging/log.hpp" +#include "runtime/java.hpp" +#include "runtime/thread.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/pair.hpp" +#include + +// Arbitrary but large limits, to simplify some of the zone calculations. +// The general idea is to allow expressions like +// MIN2(x OP y, max_XXX_zone) +// without needing to check for overflow in "x OP y", because the +// ranges for x and y have been restricted. +STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2)); +const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort); +const size_t max_green_zone = max_yellow_zone / 2; +const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue. +STATIC_ASSERT(max_yellow_zone <= max_red_zone); + +// Range check assertions for green zone values. +#define assert_zone_constraints_g(green) \ + do { \ + size_t azc_g_green = (green); \ + assert(azc_g_green <= max_green_zone, \ + "green exceeds max: " SIZE_FORMAT, azc_g_green); \ + } while (0) + +// Range check assertions for green and yellow zone values. +#define assert_zone_constraints_gy(green, yellow) \ + do { \ + size_t azc_gy_green = (green); \ + size_t azc_gy_yellow = (yellow); \ + assert_zone_constraints_g(azc_gy_green); \ + assert(azc_gy_yellow <= max_yellow_zone, \ + "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow); \ + assert(azc_gy_green <= azc_gy_yellow, \ + "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")", \ + azc_gy_green, azc_gy_yellow); \ + } while (0) + +// Range check assertions for green, yellow, and red zone values. +#define assert_zone_constraints_gyr(green, yellow, red) \ + do { \ + size_t azc_gyr_green = (green); \ + size_t azc_gyr_yellow = (yellow); \ + size_t azc_gyr_red = (red); \ + assert_zone_constraints_gy(azc_gyr_green, azc_gyr_yellow); \ + assert(azc_gyr_red <= max_red_zone, \ + "red exceeds max: " SIZE_FORMAT, azc_gyr_red); \ + assert(azc_gyr_yellow <= azc_gyr_red, \ + "yellow (" SIZE_FORMAT ") exceeds red (" SIZE_FORMAT ")", \ + azc_gyr_yellow, azc_gyr_red); \ + } while (0) + +// Logging tag sequence for refinement control updates. +#define CTRL_TAGS gc, ergo, refine + +// For logging zone values, ensuring consistency of level and tags. +#define LOG_ZONES(...) log_debug( CTRL_TAGS )(__VA_ARGS__) + +// Package for pair of refinement thread activation and deactivation +// thresholds. The activation and deactivation levels are resp. the first +// and second values of the pair. +typedef Pair Thresholds; +inline size_t activation_level(const Thresholds& t) { return t.first; } +inline size_t deactivation_level(const Thresholds& t) { return t.second; } + +static Thresholds calc_thresholds(size_t green_zone, + size_t yellow_zone, + uint worker_i) { + double yellow_size = yellow_zone - green_zone; + double step = yellow_size / G1ConcurrentRefine::thread_num(); + if (worker_i == 0) { + // Potentially activate worker 0 more aggressively, to keep + // available buffers near green_zone value. When yellow_size is + // large we don't want to allow a full step to accumulate before + // doing any processing, as that might lead to significantly more + // than green_zone buffers to be processed by update_rs. + step = MIN2(step, ParallelGCThreads / 2.0); + } + size_t activate_offset = static_cast(ceil(step * (worker_i + 1))); + size_t deactivate_offset = static_cast(floor(step * worker_i)); + return Thresholds(green_zone + activate_offset, + green_zone + deactivate_offset); +} + +G1ConcurrentRefine::G1ConcurrentRefine(size_t green_zone, + size_t yellow_zone, + size_t red_zone, + size_t min_yellow_zone_size) : + _threads(NULL), + _n_worker_threads(thread_num()), + _green_zone(green_zone), + _yellow_zone(yellow_zone), + _red_zone(red_zone), + _min_yellow_zone_size(min_yellow_zone_size) +{ + assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone); +} + +static size_t calc_min_yellow_zone_size() { + size_t step = G1ConcRefinementThresholdStep; + uint n_workers = G1ConcurrentRefine::thread_num(); + if ((max_yellow_zone / step) < n_workers) { + return max_yellow_zone; + } else { + return step * n_workers; + } +} + +static size_t calc_init_green_zone() { + size_t green = G1ConcRefinementGreenZone; + if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) { + green = ParallelGCThreads; + } + return MIN2(green, max_green_zone); +} + +static size_t calc_init_yellow_zone(size_t green, size_t min_size) { + size_t config = G1ConcRefinementYellowZone; + size_t size = 0; + if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) { + size = green * 2; + } else if (green < config) { + size = config - green; + } + size = MAX2(size, min_size); + size = MIN2(size, max_yellow_zone); + return MIN2(green + size, max_yellow_zone); +} + +static size_t calc_init_red_zone(size_t green, size_t yellow) { + size_t size = yellow - green; + if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) { + size_t config = G1ConcRefinementRedZone; + if (yellow < config) { + size = MAX2(size, config - yellow); + } + } + return MIN2(yellow + size, max_red_zone); +} + +G1ConcurrentRefine* G1ConcurrentRefine::create(jint* ecode) { + size_t min_yellow_zone_size = calc_min_yellow_zone_size(); + size_t green_zone = calc_init_green_zone(); + size_t yellow_zone = calc_init_yellow_zone(green_zone, min_yellow_zone_size); + size_t red_zone = calc_init_red_zone(green_zone, yellow_zone); + + LOG_ZONES("Initial Refinement Zones: " + "green: " SIZE_FORMAT ", " + "yellow: " SIZE_FORMAT ", " + "red: " SIZE_FORMAT ", " + "min yellow size: " SIZE_FORMAT, + green_zone, yellow_zone, red_zone, min_yellow_zone_size); + + G1ConcurrentRefine* cr = new G1ConcurrentRefine(green_zone, + yellow_zone, + red_zone, + min_yellow_zone_size); + + if (cr == NULL) { + *ecode = JNI_ENOMEM; + vm_shutdown_during_initialization("Could not create G1ConcurrentRefine"); + return NULL; + } + + cr->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, cr->_n_worker_threads, mtGC); + if (cr->_threads == NULL) { + *ecode = JNI_ENOMEM; + vm_shutdown_during_initialization("Could not allocate an array for G1ConcurrentRefineThread"); + return NULL; + } + + uint worker_id_offset = DirtyCardQueueSet::num_par_ids(); + + G1ConcurrentRefineThread *next = NULL; + for (uint i = cr->_n_worker_threads - 1; i != UINT_MAX; i--) { + Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i); + G1ConcurrentRefineThread* t = + new G1ConcurrentRefineThread(cr, + next, + worker_id_offset, + i, + activation_level(thresholds), + deactivation_level(thresholds)); + assert(t != NULL, "Conc refine should have been created"); + if (t->osthread() == NULL) { + *ecode = JNI_ENOMEM; + vm_shutdown_during_initialization("Could not create G1ConcurrentRefineThread"); + return NULL; + } + + assert(t->cr() == cr, "Conc refine thread should refer to this"); + cr->_threads[i] = t; + next = t; + } + + *ecode = JNI_OK; + return cr; +} + +void G1ConcurrentRefine::stop() { + for (uint i = 0; i < _n_worker_threads; i++) { + _threads[i]->stop(); + } +} + +void G1ConcurrentRefine::update_thread_thresholds() { + for (uint i = 0; i < _n_worker_threads; i++) { + Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i); + _threads[i]->update_thresholds(activation_level(thresholds), + deactivation_level(thresholds)); + } +} + +G1ConcurrentRefine::~G1ConcurrentRefine() { + for (uint i = 0; i < _n_worker_threads; i++) { + delete _threads[i]; + } + FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads); +} + +void G1ConcurrentRefine::threads_do(ThreadClosure *tc) { + for (uint i = 0; i < _n_worker_threads; i++) { + tc->do_thread(_threads[i]); + } +} + +uint G1ConcurrentRefine::thread_num() { + return G1ConcRefinementThreads; +} + +void G1ConcurrentRefine::print_threads_on(outputStream* st) const { + for (uint i = 0; i < _n_worker_threads; ++i) { + _threads[i]->print_on(st); + st->cr(); + } +} + +static size_t calc_new_green_zone(size_t green, + double update_rs_time, + size_t update_rs_processed_buffers, + double goal_ms) { + // Adjust green zone based on whether we're meeting the time goal. + // Limit to max_green_zone. + const double inc_k = 1.1, dec_k = 0.9; + if (update_rs_time > goal_ms) { + if (green > 0) { + green = static_cast(green * dec_k); + } + } else if (update_rs_time < goal_ms && + update_rs_processed_buffers > green) { + green = static_cast(MAX2(green * inc_k, green + 1.0)); + green = MIN2(green, max_green_zone); + } + return green; +} + +static size_t calc_new_yellow_zone(size_t green, size_t min_yellow_size) { + size_t size = green * 2; + size = MAX2(size, min_yellow_size); + return MIN2(green + size, max_yellow_zone); +} + +static size_t calc_new_red_zone(size_t green, size_t yellow) { + return MIN2(yellow + (yellow - green), max_red_zone); +} + +void G1ConcurrentRefine::update_zones(double update_rs_time, + size_t update_rs_processed_buffers, + double goal_ms) { + log_trace( CTRL_TAGS )("Updating Refinement Zones: " + "update_rs time: %.3fms, " + "update_rs buffers: " SIZE_FORMAT ", " + "update_rs goal time: %.3fms", + update_rs_time, + update_rs_processed_buffers, + goal_ms); + + _green_zone = calc_new_green_zone(_green_zone, + update_rs_time, + update_rs_processed_buffers, + goal_ms); + _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size); + _red_zone = calc_new_red_zone(_green_zone, _yellow_zone); + + assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone); + LOG_ZONES("Updated Refinement Zones: " + "green: " SIZE_FORMAT ", " + "yellow: " SIZE_FORMAT ", " + "red: " SIZE_FORMAT, + _green_zone, _yellow_zone, _red_zone); +} + +void G1ConcurrentRefine::adjust(double update_rs_time, + size_t update_rs_processed_buffers, + double goal_ms) { + DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); + + if (G1UseAdaptiveConcRefinement) { + update_zones(update_rs_time, update_rs_processed_buffers, goal_ms); + update_thread_thresholds(); + + // Change the barrier params + if (_n_worker_threads == 0) { + // Disable dcqs notification when there are no threads to notify. + dcqs.set_process_completed_threshold(INT_MAX); + } else { + // Worker 0 is the primary; wakeup is via dcqs notification. + STATIC_ASSERT(max_yellow_zone <= INT_MAX); + size_t activate = _threads[0]->activation_threshold(); + dcqs.set_process_completed_threshold((int)activate); + } + dcqs.set_max_completed_queue((int)red_zone()); + } + + size_t curr_queue_size = dcqs.completed_buffers_num(); + if (curr_queue_size >= yellow_zone()) { + dcqs.set_completed_queue_padding(curr_queue_size); + } else { + dcqs.set_completed_queue_padding(0); + } + dcqs.notify_if_necessary(); +} diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2001, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_G1_G1CONCURRENTREFINE_HPP +#define SHARE_VM_GC_G1_G1CONCURRENTREFINE_HPP + +#include "memory/allocation.hpp" +#include "utilities/globalDefinitions.hpp" + +// Forward decl +class CardTableEntryClosure; +class G1ConcurrentRefineThread; +class outputStream; +class ThreadClosure; + +class G1ConcurrentRefine : public CHeapObj { + G1ConcurrentRefineThread** _threads; + uint _n_worker_threads; + /* + * The value of the update buffer queue length falls into one of 3 zones: + * green, yellow, red. If the value is in [0, green) nothing is + * done, the buffers are left unprocessed to enable the caching effect of the + * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement + * threads are gradually activated. In [yellow, red) all threads are + * running. If the length becomes red (max queue length) the mutators start + * processing the buffers. + * + * There are some interesting cases (when G1UseAdaptiveConcRefinement + * is turned off): + * 1) green = yellow = red = 0. In this case the mutator will process all + * buffers. Except for those that are created by the deferred updates + * machinery during a collection. + * 2) green = 0. Means no caching. Can be a good way to minimize the + * amount of time spent updating rsets during a collection. + */ + size_t _green_zone; + size_t _yellow_zone; + size_t _red_zone; + size_t _min_yellow_zone_size; + + G1ConcurrentRefine(size_t green_zone, + size_t yellow_zone, + size_t red_zone, + size_t min_yellow_zone_size); + + // Update green/yellow/red zone values based on how well goals are being met. + void update_zones(double update_rs_time, + size_t update_rs_processed_buffers, + double goal_ms); + + // Update thread thresholds to account for updated zone values. + void update_thread_thresholds(); + + public: + ~G1ConcurrentRefine(); + + // Returns a G1ConcurrentRefine instance if succeeded to create/initialize G1ConcurrentRefine and G1ConcurrentRefineThreads. + // Otherwise, returns NULL with error code. + static G1ConcurrentRefine* create(jint* ecode); + + void stop(); + + void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms); + + // Iterate over all concurrent refinement threads applying the given closure. + void threads_do(ThreadClosure *tc); + + static uint thread_num(); + + void print_threads_on(outputStream* st) const; + + size_t green_zone() const { return _green_zone; } + size_t yellow_zone() const { return _yellow_zone; } + size_t red_zone() const { return _red_zone; } +}; + +#endif // SHARE_VM_GC_G1_G1CONCURRENTREFINE_HPP diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2001, 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. + * + * 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 "gc/g1/g1ConcurrentRefine.hpp" +#include "gc/g1/g1ConcurrentRefineThread.hpp" +#include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1RemSet.hpp" +#include "gc/shared/suspendibleThreadSet.hpp" +#include "logging/log.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/handles.inline.hpp" +#include "runtime/mutexLocker.hpp" + +G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, + G1ConcurrentRefineThread *next, + uint worker_id_offset, + uint worker_id, + size_t activate, + size_t deactivate) : + ConcurrentGCThread(), + _worker_id_offset(worker_id_offset), + _worker_id(worker_id), + _active(false), + _next(next), + _monitor(NULL), + _cr(cr), + _vtime_accum(0.0), + _activation_threshold(activate), + _deactivation_threshold(deactivate) +{ + + // Each thread has its own monitor. The i-th thread is responsible for signaling + // to thread i+1 if the number of buffers in the queue exceeds a threshold for this + // thread. Monitors are also used to wake up the threads during termination. + // The 0th (primary) worker is notified by mutator threads and has a special monitor. + if (!is_primary()) { + _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true, + Monitor::_safepoint_check_never); + } else { + _monitor = DirtyCardQ_CBL_mon; + } + + // set name + set_name("G1 Refine#%d", worker_id); + create_and_start(); +} + +void G1ConcurrentRefineThread::update_thresholds(size_t activate, + size_t deactivate) { + assert(deactivate < activate, "precondition"); + _activation_threshold = activate; + _deactivation_threshold = deactivate; +} + +void G1ConcurrentRefineThread::wait_for_completed_buffers() { + MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); + while (!should_terminate() && !is_active()) { + _monitor->wait(Mutex::_no_safepoint_check_flag); + } +} + +bool G1ConcurrentRefineThread::is_active() { + DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); + return is_primary() ? dcqs.process_completed_buffers() : _active; +} + +void G1ConcurrentRefineThread::activate() { + MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); + if (!is_primary()) { + set_active(true); + } else { + DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); + dcqs.set_process_completed(true); + } + _monitor->notify(); +} + +void G1ConcurrentRefineThread::deactivate() { + MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); + if (!is_primary()) { + set_active(false); + } else { + DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); + dcqs.set_process_completed(false); + } +} + +void G1ConcurrentRefineThread::run_service() { + _vtime_start = os::elapsedVTime(); + + while (!should_terminate()) { + // Wait for work + wait_for_completed_buffers(); + if (should_terminate()) { + break; + } + + size_t buffers_processed = 0; + DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); + log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT, + _worker_id, _activation_threshold, dcqs.completed_buffers_num()); + + { + SuspendibleThreadSetJoiner sts_join; + + while (!should_terminate()) { + if (sts_join.should_yield()) { + sts_join.yield(); + continue; // Re-check for termination after yield delay. + } + + size_t curr_buffer_num = dcqs.completed_buffers_num(); + // If the number of the buffers falls down into the yellow zone, + // that means that the transition period after the evacuation pause has ended. + if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cr()->yellow_zone()) { + dcqs.set_completed_queue_padding(0); + } + + // Check if we need to activate the next thread. + if ((_next != NULL) && + !_next->is_active() && + (curr_buffer_num > _next->_activation_threshold)) { + _next->activate(); + } + + // Process the next buffer, if there are enough left. + if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) { + break; // Deactivate, number of buffers fell below threshold. + } + ++buffers_processed; + } + } + + deactivate(); + log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT + ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT, + _worker_id, _deactivation_threshold, + dcqs.completed_buffers_num(), + buffers_processed); + + if (os::supports_vtime()) { + _vtime_accum = (os::elapsedVTime() - _vtime_start); + } else { + _vtime_accum = 0.0; + } + } + + log_debug(gc, refine)("Stopping %d", _worker_id); +} + +void G1ConcurrentRefineThread::stop_service() { + MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); + _monitor->notify(); +} diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2001, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP +#define SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP + +#include "gc/g1/dirtyCardQueue.hpp" +#include "gc/shared/concurrentGCThread.hpp" + +// Forward Decl. +class CardTableEntryClosure; +class G1ConcurrentRefine; + +// One or more G1 Concurrent Refinement Threads may be active if concurrent +// refinement is in progress. +class G1ConcurrentRefineThread: public ConcurrentGCThread { + friend class VMStructs; + friend class G1CollectedHeap; + + double _vtime_start; // Initial virtual time. + double _vtime_accum; // Accumulated virtual time. + uint _worker_id; + uint _worker_id_offset; + + // The refinement threads collection is linked list. A predecessor can activate a successor + // when the number of the rset update buffer crosses a certain threshold. A successor + // would self-deactivate when the number of the buffers falls below the threshold. + bool _active; + G1ConcurrentRefineThread* _next; + Monitor* _monitor; + G1ConcurrentRefine* _cr; + + // This thread's activation/deactivation thresholds + size_t _activation_threshold; + size_t _deactivation_threshold; + + void wait_for_completed_buffers(); + + void set_active(bool x) { _active = x; } + bool is_active(); + void activate(); + void deactivate(); + + bool is_primary() { return (_worker_id == 0); } + + void run_service(); + void stop_service(); + +public: + // Constructor + G1ConcurrentRefineThread(G1ConcurrentRefine* cr, G1ConcurrentRefineThread* next, + uint worker_id_offset, uint worker_id, + size_t activate, size_t deactivate); + + void update_thresholds(size_t activate, size_t deactivate); + size_t activation_threshold() const { return _activation_threshold; } + + // Total virtual time so far. + double vtime_accum() { return _vtime_accum; } + + G1ConcurrentRefine* cr() { return _cr; } +}; + +#endif // SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1DefaultPolicy.cpp --- a/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" -#include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentMarkThread.inline.hpp" #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectionSet.hpp" #include "gc/g1/g1ConcurrentMark.hpp" +#include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/g1DefaultPolicy.hpp" #include "gc/g1/g1HotCardCache.hpp" #include "gc/g1/g1IHOPControl.hpp" @@ -745,7 +745,7 @@ } else { update_rs_time_goal_ms -= scan_hcc_time_ms; } - _g1->concurrent_g1_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms, + _g1->concurrent_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms, phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS), update_rs_time_goal_ms); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -414,7 +414,7 @@ debug_time("Redirty Cards", _recorded_redirty_logged_cards_time_ms); trace_phase(_gc_par_phases[RedirtyCards]); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI debug_time("DerivedPointerTable Update", _cur_derived_pointer_table_update_time_ms); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1MMUTracker.cpp --- a/src/hotspot/share/gc/g1/g1MMUTracker.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1MMUTracker.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -112,19 +112,7 @@ } } -// basically the _internal call does not remove expired entries -// this is for trying things out in the future and a couple -// of other places (debugging) - double G1MMUTrackerQueue::when_sec(double current_time, double pause_time) { - MutexLockerEx x(MMUTracker_lock, Mutex::_no_safepoint_check_flag); - remove_expired_entries(current_time); - - return when_internal(current_time, pause_time); -} - -double G1MMUTrackerQueue::when_internal(double current_time, - double pause_time) { // if the pause is over the maximum, just assume that it's the maximum double adjusted_pause_time = (pause_time > max_gc_time()) ? max_gc_time() : pause_time; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1MMUTracker.hpp --- a/src/hotspot/share/gc/g1/g1MMUTracker.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1MMUTracker.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -134,8 +134,6 @@ void remove_expired_entries(double current_time); double calculate_gc_time(double current_time); - double when_internal(double current_time, double pause_time); - public: G1MMUTrackerQueue(double time_slice, double max_gc_time); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1MarkSweep.cpp --- a/src/hotspot/share/gc/g1/g1MarkSweep.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1MarkSweep.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -62,7 +62,7 @@ assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); HandleMark hm; // Discard invalid handles created during gc -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::clear(); #endif #ifdef ASSERT @@ -96,7 +96,7 @@ // Prepare compaction. mark_sweep_phase2(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // Don't add any more derived pointers during phase3 DerivedPointerTable::set_active(false); #endif @@ -111,7 +111,7 @@ BiasedLocking::restore_marks(); GenMarkSweep::deallocate_stacks(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // Now update the derived pointers. DerivedPointerTable::update_pointers(); #endif @@ -204,7 +204,7 @@ if (VerifyDuringGC) { HandleMark hm; // handle scope -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTableDeactivate dpt_deact; #endif g1h->prepare_for_verify(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1RemSet.cpp --- a/src/hotspot/share/gc/g1/g1RemSet.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,10 +23,10 @@ */ #include "precompiled.hpp" -#include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/dirtyCardQueue.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/g1FromCardCache.hpp" #include "gc/g1/g1GCPhaseTimes.hpp" #include "gc/g1/g1HotCardCache.hpp" @@ -298,7 +298,7 @@ } uint G1RemSet::num_par_rem_sets() { - return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); + return MAX2(DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::thread_num(), ParallelGCThreads); } void G1RemSet::initialize(size_t capacity, uint max_regions) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1RemSetSummary.cpp --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" -#include "gc/g1/concurrentG1Refine.hpp" -#include "gc/g1/concurrentG1RefineThread.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1ConcurrentRefine.hpp" +#include "gc/g1/g1ConcurrentRefineThread.hpp" #include "gc/g1/g1RemSet.inline.hpp" #include "gc/g1/g1RemSetSummary.hpp" #include "gc/g1/g1YoungRemSetSamplingThread.hpp" @@ -45,7 +45,7 @@ } virtual void do_thread(Thread* t) { - ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t; + G1ConcurrentRefineThread* crt = (G1ConcurrentRefineThread*) t; _summary->set_rs_thread_vtime(_counter, crt->vtime_accum()); _counter++; } @@ -59,12 +59,13 @@ _num_coarsenings = HeapRegionRemSet::n_coarsenings(); - ConcurrentG1Refine * cg1r = G1CollectedHeap::heap()->concurrent_g1_refine(); + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + G1ConcurrentRefine* cg1r = g1h->concurrent_refine(); if (_rs_threads_vtimes != NULL) { GetRSThreadVTimeClosure p(this); - cg1r->worker_threads_do(&p); + cg1r->threads_do(&p); } - set_sampling_thread_vtime(cg1r->sampling_thread()->vtime_accum()); + set_sampling_thread_vtime(g1h->sampling_thread()->vtime_accum()); } void G1RemSetSummary::set_rs_thread_vtime(uint thread, double value) { @@ -85,7 +86,7 @@ _num_processed_buf_mutator(0), _num_processed_buf_rs_threads(0), _num_coarsenings(0), - _num_vtimes(ConcurrentG1Refine::thread_num()), + _num_vtimes(G1ConcurrentRefine::thread_num()), _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)), _sampling_thread_vtime(0.0f) { @@ -98,7 +99,7 @@ _num_processed_buf_mutator(0), _num_processed_buf_rs_threads(0), _num_coarsenings(0), - _num_vtimes(ConcurrentG1Refine::thread_num()), + _num_vtimes(G1ConcurrentRefine::thread_num()), _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)), _sampling_thread_vtime(0.0f) { update(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp --- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -214,52 +214,3 @@ } } } - -void G1SATBCardTableModRefBS::write_ref_nmethod_post(oop* dst, nmethod* nm) { - oop obj = oopDesc::load_heap_oop(dst); - if (obj != NULL) { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - HeapRegion* hr = g1h->heap_region_containing(obj); - hr->add_strong_code_root(nm); - } -} - -class G1EnsureLastRefToRegion : public OopClosure { - G1CollectedHeap* _g1h; - HeapRegion* _hr; - oop* _dst; - - bool _value; -public: - G1EnsureLastRefToRegion(G1CollectedHeap* g1h, HeapRegion* hr, oop* dst) : - _g1h(g1h), _hr(hr), _dst(dst), _value(true) {} - - void do_oop(oop* p) { - if (_value && p != _dst) { - oop obj = oopDesc::load_heap_oop(p); - if (obj != NULL) { - HeapRegion* hr = _g1h->heap_region_containing(obj); - if (hr == _hr) { - // Another reference to the same region. - _value = false; - } - } - } - } - void do_oop(narrowOop* p) { ShouldNotReachHere(); } - bool value() const { return _value; } -}; - -void G1SATBCardTableModRefBS::write_ref_nmethod_pre(oop* dst, nmethod* nm) { - oop obj = oopDesc::load_heap_oop(dst); - if (obj != NULL) { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - HeapRegion* hr = g1h->heap_region_containing(obj); - G1EnsureLastRefToRegion ensure_last_ref(g1h, hr, dst); - nm->oops_do(&ensure_last_ref); - if (ensure_last_ref.value()) { - // Last reference to this region, remove the nmethod from the rset. - hr->remove_strong_code_root(nm); - } - } -} diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp --- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -95,9 +95,6 @@ jbyte val = _byte_map[card_index]; return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); } - virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm); - virtual void write_ref_nmethod_post(oop* dst, nmethod* nm); - }; template<> diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/g1_globals.hpp --- a/src/hotspot/share/gc/g1/g1_globals.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1_globals.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -74,10 +74,10 @@ "in milliseconds.") \ range(1.0, DBL_MAX) \ \ - product(intx, G1RefProcDrainInterval, 10, \ + product(int, G1RefProcDrainInterval, 10, \ "The number of discovered reference objects to process before " \ "draining concurrent marking work queues.") \ - range(1, max_intx) \ + range(1, INT_MAX) \ \ experimental(double, G1LastPLABAverageOccupancy, 50.0, \ "The expected average occupancy of the last PLAB in " \ diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/heapRegionManager.cpp --- a/src/hotspot/share/gc/g1/heapRegionManager.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,8 +23,8 @@ */ #include "precompiled.hpp" -#include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionSet.inline.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/heapRegionRemSet.cpp --- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" -#include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/g1CardLiveData.inline.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/g1/satbMarkQueue.cpp --- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/g1/satbMarkQueue.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/satbMarkQueue.hpp" #include "gc/shared/collectedHeap.hpp" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/mutexLocker.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/parallel/psMarkSweep.cpp --- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -192,7 +192,7 @@ allocate_stacks(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::clear(); #endif @@ -203,7 +203,7 @@ mark_sweep_phase2(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // Don't add any more derived pointers during phase3 assert(DerivedPointerTable::is_active(), "Sanity"); DerivedPointerTable::set_active(false); @@ -252,7 +252,7 @@ CodeCache::gc_epilogue(); JvmtiExport::gc_epilogue(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::update_pointers(); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/parallel/psParallelCompact.cpp --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1032,7 +1032,7 @@ CodeCache::gc_epilogue(); JvmtiExport::gc_epilogue(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::update_pointers(); #endif @@ -1783,7 +1783,7 @@ CodeCache::gc_prologue(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::clear(); #endif @@ -1799,7 +1799,7 @@ && GCCause::is_user_requested_gc(gc_cause); summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_active(), "Sanity"); DerivedPointerTable::set_active(false); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/parallel/psScavenge.cpp --- a/src/hotspot/share/gc/parallel/psScavenge.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -331,7 +331,7 @@ save_to_space_top_before_gc(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::clear(); #endif @@ -601,7 +601,7 @@ assert(young_gen->to_space()->is_empty(), "to space should be empty now"); } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI DerivedPointerTable::update_pointers(); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/serial/genMarkSweep.cpp --- a/src/hotspot/share/gc/serial/genMarkSweep.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -92,7 +92,7 @@ mark_sweep_phase2(); // Don't add any more derived pointers during phase3 -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_active(), "Sanity"); DerivedPointerTable::set_active(false); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/serial/serialHeap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/serial/serialHeap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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. + * + * 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 "gc/serial/serialHeap.hpp" + +SerialHeap::SerialHeap(GenCollectorPolicy* policy) : GenCollectedHeap(policy) {} + +void SerialHeap::check_gen_kinds() { + assert(young_gen()->kind() == Generation::DefNew, + "Wrong youngest generation type"); + assert(old_gen()->kind() == Generation::MarkSweepCompact, + "Wrong generation kind"); +} diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/serial/serialHeap.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/serial/serialHeap.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SERIAL_SERIALHEAP_HPP +#define SHARE_VM_GC_SERIAL_SERIALHEAP_HPP + +#include "gc/shared/genCollectedHeap.hpp" + +class GenCollectorPolicy; + +class SerialHeap : public GenCollectedHeap { +protected: + virtual void check_gen_kinds(); + +public: + SerialHeap(GenCollectorPolicy* policy); + + virtual Name kind() const { + return CollectedHeap::SerialHeap; + } + + virtual const char* name() const { + return "Serial"; + } + + // override + virtual bool is_in_closed_subset(const void* p) const { + return is_in(p); + } + + virtual bool card_mark_must_follow_store() const { + return false; + } + +}; + +#endif // SHARE_VM_GC_CMS_CMSHEAP_HPP diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/ageTable.cpp --- a/src/hotspot/share/gc/shared/ageTable.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/ageTable.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "gc/shared/ageTable.inline.hpp" #include "gc/shared/ageTableTracer.hpp" #include "gc/shared/collectedHeap.hpp" @@ -30,7 +31,6 @@ #include "memory/resourceArea.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "utilities/copy.hpp" /* Copyright (c) 1992, 2016, Oracle and/or its affiliates, and Stanford University. diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/allocTracer.cpp --- a/src/hotspot/share/gc/shared/allocTracer.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/allocTracer.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -26,9 +26,11 @@ #include "gc/shared/allocTracer.hpp" #include "runtime/handles.hpp" #include "trace/tracing.hpp" +#include "trace/traceMacros.hpp" #include "utilities/globalDefinitions.hpp" -void AllocTracer::send_allocation_outside_tlab_event(Klass* klass, size_t alloc_size) { +void AllocTracer::send_allocation_outside_tlab(Klass* klass, HeapWord* obj, size_t alloc_size, Thread* thread) { + TRACE_ALLOCATION(obj, alloc_size, thread); EventObjectAllocationOutsideTLAB event; if (event.should_commit()) { event.set_objectClass(klass); @@ -37,7 +39,8 @@ } } -void AllocTracer::send_allocation_in_new_tlab_event(Klass* klass, size_t tlab_size, size_t alloc_size) { +void AllocTracer::send_allocation_in_new_tlab(Klass* klass, HeapWord* obj, size_t tlab_size, size_t alloc_size, Thread* thread) { + TRACE_ALLOCATION(obj, tlab_size, thread); EventObjectAllocationInNewTLAB event; if (event.should_commit()) { event.set_objectClass(klass); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/allocTracer.hpp --- a/src/hotspot/share/gc/shared/allocTracer.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/allocTracer.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -30,8 +30,8 @@ class AllocTracer : AllStatic { public: - static void send_allocation_outside_tlab_event(Klass* klass, size_t alloc_size); - static void send_allocation_in_new_tlab_event(Klass* klass, size_t tlab_size, size_t alloc_size); + static void send_allocation_outside_tlab(Klass* klass, HeapWord* obj, size_t alloc_size, Thread* thread); + static void send_allocation_in_new_tlab(Klass* klass, HeapWord* obj, size_t tlab_size, size_t alloc_size, Thread* thread); static void send_allocation_requiring_gc_event(size_t size, uint gcId); }; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/barrierSet.hpp --- a/src/hotspot/share/gc/shared/barrierSet.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/barrierSet.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -120,9 +120,6 @@ static void static_write_ref_array_pre(HeapWord* start, size_t count); static void static_write_ref_array_post(HeapWord* start, size_t count); - virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm) {} - virtual void write_ref_nmethod_post(oop* dst, nmethod* nm) {} - protected: virtual void write_ref_array_work(MemRegion mr) = 0; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/collectedHeap.cpp --- a/src/hotspot/share/gc/shared/collectedHeap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -241,7 +241,7 @@ void CollectedHeap::pre_initialize() { // Used for ReduceInitialCardMarks (when COMPILER2 is used); // otherwise remains unused. -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI _defer_initial_card_mark = is_server_compilation_mode_vm() && ReduceInitialCardMarks && can_elide_tlab_store_barriers() && (DeferInitialCardMark || card_mark_must_follow_store()); #else @@ -313,7 +313,7 @@ return NULL; } - AllocTracer::send_allocation_in_new_tlab_event(klass, new_tlab_size * HeapWordSize, size * HeapWordSize); + AllocTracer::send_allocation_in_new_tlab(klass, obj, new_tlab_size * HeapWordSize, size * HeapWordSize, thread); if (ZeroTLAB) { // ..and clear it. @@ -545,7 +545,7 @@ " to threads list is doomed to failure!"); for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) { if (use_tlab) thread->tlab().make_parsable(retire_tlabs); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // The deferred store barriers must all have been flushed to the // card-table (or other remembered set structure) before GC starts // processing the card-table (or other remembered set). diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/collectedHeap.hpp --- a/src/hotspot/share/gc/shared/collectedHeap.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -81,9 +81,10 @@ // // CollectedHeap // GenCollectedHeap +// SerialHeap +// CMSHeap // G1CollectedHeap // ParallelScavengeHeap -// CMSHeap // class CollectedHeap : public CHeapObj { friend class VMStructs; @@ -193,7 +194,7 @@ public: enum Name { - GenCollectedHeap, + SerialHeap, ParallelScavengeHeap, G1CollectedHeap, CMSHeap diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/collectedHeap.inline.hpp --- a/src/hotspot/share/gc/shared/collectedHeap.inline.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/collectedHeap.inline.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -156,7 +156,7 @@ "Unexpected exception, will result in uninitialized storage"); THREAD->incr_allocated_bytes(size * HeapWordSize); - AllocTracer::send_allocation_outside_tlab_event(klass, size * HeapWordSize); + AllocTracer::send_allocation_outside_tlab(klass, result, size * HeapWordSize, THREAD); return result; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/gcId.cpp --- a/src/hotspot/share/gc/shared/gcId.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/gcId.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,8 +23,8 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "gc/shared/gcId.hpp" -#include "prims/jvm.h" #include "runtime/safepoint.hpp" #include "runtime/thread.inline.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/gcTimer.hpp --- a/src/hotspot/share/gc/shared/gcTimer.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/gcTimer.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -26,7 +26,6 @@ #define SHARE_VM_GC_SHARED_GCTIMER_HPP #include "memory/allocation.hpp" -#include "prims/jni_md.h" #include "utilities/macros.hpp" #include "utilities/ticks.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/gcTraceTime.inline.hpp --- a/src/hotspot/share/gc/shared/gcTraceTime.inline.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/gcTraceTime.inline.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -32,7 +32,6 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/universe.hpp" -#include "prims/jni_md.h" #include "utilities/ticks.hpp" #define LOG_STOP_HEAP_FORMAT SIZE_FORMAT "M->" SIZE_FORMAT "M(" SIZE_FORMAT "M)" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/genCollectedHeap.cpp --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -153,13 +153,6 @@ _gen_policy->initialize_gc_policy_counters(); } -void GenCollectedHeap::check_gen_kinds() { - assert(young_gen()->kind() == Generation::DefNew, - "Wrong youngest generation type"); - assert(old_gen()->kind() == Generation::MarkSweepCompact, - "Wrong generation kind"); -} - void GenCollectedHeap::ref_processing_init() { _young_gen->ref_processor_init(); _old_gen->ref_processor_init(); @@ -984,7 +977,7 @@ GenCollectedHeap* GenCollectedHeap::heap() { CollectedHeap* heap = Universe::heap(); assert(heap != NULL, "Uninitialized access to GenCollectedHeap::heap()"); - assert(heap->kind() == CollectedHeap::GenCollectedHeap || + assert(heap->kind() == CollectedHeap::SerialHeap || heap->kind() == CollectedHeap::CMSHeap, "Not a GenCollectedHeap"); return (GenCollectedHeap*) heap; } @@ -1067,11 +1060,11 @@ }; void GenCollectedHeap::gc_epilogue(bool full) { -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_empty(), "derived pointer present"); size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr())); guarantee(is_client_compilation_mode_vm() || actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps"); -#endif /* COMPILER2 || INCLUDE_JVMCI */ +#endif // COMPILER2_OR_JVMCI resize_all_tlabs(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/genCollectedHeap.hpp --- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -83,6 +83,12 @@ bool run_verification, bool clear_soft_refs, bool restore_marks_for_biased_locking); + // Reserve aligned space for the heap as needed by the contained generations. + char* allocate(size_t alignment, ReservedSpace* heap_rs); + + // Initialize ("weak") refs processing support + void ref_processing_init(); + protected: // The set of potentially parallel tasks in root scanning. @@ -134,31 +140,18 @@ // we absolutely __must__ clear soft refs? bool must_clear_all_soft_refs(); + GenCollectedHeap(GenCollectorPolicy *policy); + + virtual void check_gen_kinds() = 0; + public: - GenCollectedHeap(GenCollectorPolicy *policy); // Returns JNI_OK on success virtual jint initialize(); - // Reserve aligned space for the heap as needed by the contained generations. - char* allocate(size_t alignment, ReservedSpace* heap_rs); - // Does operations required after initialization has been done. void post_initialize(); - virtual void check_gen_kinds(); - - // Initialize ("weak") refs processing support - virtual void ref_processing_init(); - - virtual Name kind() const { - return CollectedHeap::GenCollectedHeap; - } - - virtual const char* name() const { - return "Serial"; - } - Generation* young_gen() const { return _young_gen; } Generation* old_gen() const { return _old_gen; } @@ -215,11 +208,6 @@ // assertion checking or verification only. bool is_in(const void* p) const; - // override - virtual bool is_in_closed_subset(const void* p) const { - return is_in(p); - } - // Returns true if the reference is to an object in the reserved space // for the young generation. // Assumes the the young gen address range is less than that of the old gen. @@ -286,10 +274,6 @@ return true; } - virtual bool card_mark_must_follow_store() const { - return false; - } - // We don't need barriers for stores to objects in the // young gen and, a fortiori, for initializing stores to // objects therein. This applies to DefNew+Tenured and ParNew+CMS diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/gc/shared/weakProcessor.cpp --- a/src/hotspot/share/gc/shared/weakProcessor.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/gc/shared/weakProcessor.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -26,10 +26,13 @@ #include "gc/shared/weakProcessor.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/jniHandles.hpp" +#include "trace/tracing.hpp" +#include "trace/traceMacros.hpp" void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) { JNIHandles::weak_oops_do(is_alive, keep_alive); JvmtiExport::weak_oops_do(is_alive, keep_alive); + TRACE_WEAK_OOPS_DO(is_alive, keep_alive); } void WeakProcessor::oops_do(OopClosure* closure) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/interpreter/interpreterRuntime.cpp --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -87,14 +87,15 @@ // State accessors void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) { - last_frame(thread).interpreter_frame_set_bcp(bcp); + LastFrameAccessor last_frame(thread); + last_frame.set_bcp(bcp); if (ProfileInterpreter) { // ProfileTraps uses MDOs independently of ProfileInterpreter. // That is why we must check both ProfileInterpreter and mdo != NULL. - MethodData* mdo = last_frame(thread).interpreter_frame_method()->method_data(); + MethodData* mdo = last_frame.method()->method_data(); if (mdo != NULL) { NEEDS_CLEANUP; - last_frame(thread).interpreter_frame_set_mdp(mdo->bci_to_dp(last_frame(thread).interpreter_frame_bci())); + last_frame.set_mdp(mdo->bci_to_dp(last_frame.bci())); } } } @@ -105,8 +106,9 @@ IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide)) // access constant pool - ConstantPool* pool = method(thread)->constants(); - int index = wide ? get_index_u2(thread, Bytecodes::_ldc_w) : get_index_u1(thread, Bytecodes::_ldc); + LastFrameAccessor last_frame(thread); + ConstantPool* pool = last_frame.method()->constants(); + int index = wide ? last_frame.get_index_u2(Bytecodes::_ldc_w) : last_frame.get_index_u1(Bytecodes::_ldc); constantTag tag = pool->tag_at(index); assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call"); @@ -119,13 +121,14 @@ assert(bytecode == Bytecodes::_fast_aldc || bytecode == Bytecodes::_fast_aldc_w, "wrong bc"); ResourceMark rm(thread); - methodHandle m (thread, method(thread)); - Bytecode_loadconstant ldc(m, bci(thread)); + LastFrameAccessor last_frame(thread); + methodHandle m (thread, last_frame.method()); + Bytecode_loadconstant ldc(m, last_frame.bci()); oop result = ldc.resolve_constant(CHECK); #ifdef ASSERT { // The bytecode wrappers aren't GC-safe so construct a new one - Bytecode_loadconstant ldc2(m, bci(thread)); + Bytecode_loadconstant ldc2(m, last_frame.bci()); oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index()); assert(result == coop, "expected result for assembly code"); } @@ -182,10 +185,11 @@ IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address)) // We may want to pass in more arguments - could make this slightly faster - ConstantPool* constants = method(thread)->constants(); - int i = get_index_u2(thread, Bytecodes::_multianewarray); - Klass* klass = constants->klass_at(i, CHECK); - int nof_dims = number_of_dimensions(thread); + LastFrameAccessor last_frame(thread); + ConstantPool* constants = last_frame.method()->constants(); + int i = last_frame.get_index_u2(Bytecodes::_multianewarray); + Klass* klass = constants->klass_at(i, CHECK); + int nof_dims = last_frame.number_of_dimensions(); assert(klass->is_klass(), "not a class"); assert(nof_dims >= 1, "multianewarray rank must be nonzero"); @@ -217,8 +221,9 @@ // Quicken instance-of and check-cast bytecodes IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread)) // Force resolving; quicken the bytecode - int which = get_index_u2(thread, Bytecodes::_checkcast); - ConstantPool* cpool = method(thread)->constants(); + LastFrameAccessor last_frame(thread); + int which = last_frame.get_index_u2(Bytecodes::_checkcast); + ConstantPool* cpool = last_frame.method()->constants(); // We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded // program we might have seen an unquick'd bytecode in the interpreter but have another // thread quicken the bytecode before we get here. @@ -257,8 +262,9 @@ // If necessary, create an MDO to hold the information, and record it. void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) { assert(ProfileTraps, "call me only if profiling"); - methodHandle trap_method(thread, method(thread)); - int trap_bci = trap_method->bci_from(bcp(thread)); + LastFrameAccessor last_frame(thread); + methodHandle trap_method(thread, last_frame.method()); + int trap_bci = trap_method->bci_from(last_frame.bcp()); note_trap_inner(thread, reason, trap_method, trap_bci, THREAD); } @@ -391,12 +397,13 @@ // invoke w/o arguments (i.e., as if one were inside the call). IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)) + LastFrameAccessor last_frame(thread); Handle h_exception(thread, exception); - methodHandle h_method (thread, method(thread)); + methodHandle h_method (thread, last_frame.method()); constantPoolHandle h_constants(thread, h_method->constants()); bool should_repeat; int handler_bci; - int current_bci = bci(thread); + int current_bci = last_frame.bci(); if (thread->frames_to_pop_failed_realloc() > 0) { // Allocation of scalar replaced object used in this frame @@ -493,7 +500,7 @@ // notify JVMTI of an exception throw; JVMTI will detect if this is a first // time throw or a stack unwinding throw and accordingly notify the debugger if (JvmtiExport::can_post_on_exceptions()) { - JvmtiExport::post_exception_throw(thread, h_method(), bcp(thread), h_exception()); + JvmtiExport::post_exception_throw(thread, h_method(), last_frame.bcp(), h_exception()); } #ifdef CC_INTERP @@ -556,20 +563,21 @@ Thread* THREAD = thread; // resolve field fieldDescriptor info; - constantPoolHandle pool(thread, method(thread)->constants()); - methodHandle m(thread, method(thread)); + LastFrameAccessor last_frame(thread); + constantPoolHandle pool(thread, last_frame.method()->constants()); + methodHandle m(thread, last_frame.method()); bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_nofast_putfield || bytecode == Bytecodes::_putstatic); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); { JvmtiHideSingleStepping jhss(thread); - LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode), + LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode), m, bytecode, CHECK); } // end JvmtiHideSingleStepping // check if link resolution caused cpCache to be updated - ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread); + ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry(); if (cp_cache_entry->is_resolved(bytecode)) return; // compute auxiliary field attributes @@ -718,16 +726,17 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) { Thread* THREAD = thread; + LastFrameAccessor last_frame(thread); // extract receiver from the outgoing argument list if necessary Handle receiver(thread, NULL); if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface || bytecode == Bytecodes::_invokespecial) { ResourceMark rm(thread); - methodHandle m (thread, method(thread)); - Bytecode_invoke call(m, bci(thread)); + methodHandle m (thread, last_frame.method()); + Bytecode_invoke call(m, last_frame.bci()); Symbol* signature = call.signature(); - receiver = Handle(thread, - thread->last_frame().interpreter_callee_receiver(signature)); + receiver = Handle(thread, last_frame.callee_receiver(signature)); + assert(Universe::heap()->is_in_reserved_or_null(receiver()), "sanity check"); assert(receiver.is_null() || @@ -737,12 +746,12 @@ // resolve method CallInfo info; - constantPoolHandle pool(thread, method(thread)->constants()); + constantPoolHandle pool(thread, last_frame.method()->constants()); { JvmtiHideSingleStepping jhss(thread); LinkResolver::resolve_invoke(info, receiver, pool, - get_index_u2_cpcache(thread, bytecode), bytecode, + last_frame.get_index_u2_cpcache(bytecode), bytecode, CHECK); if (JvmtiExport::can_hotswap_or_post_breakpoint()) { int retry_count = 0; @@ -754,14 +763,14 @@ "Could not resolve to latest version of redefined method"); // method is redefined in the middle of resolve so re-try. LinkResolver::resolve_invoke(info, receiver, pool, - get_index_u2_cpcache(thread, bytecode), bytecode, + last_frame.get_index_u2_cpcache(bytecode), bytecode, CHECK); } } } // end JvmtiHideSingleStepping // check if link resolution caused cpCache to be updated - ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread); + ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry(); if (cp_cache_entry->is_resolved(bytecode)) return; #ifdef ASSERT @@ -825,33 +834,35 @@ void InterpreterRuntime::resolve_invokehandle(JavaThread* thread) { Thread* THREAD = thread; const Bytecodes::Code bytecode = Bytecodes::_invokehandle; + LastFrameAccessor last_frame(thread); // resolve method CallInfo info; - constantPoolHandle pool(thread, method(thread)->constants()); + constantPoolHandle pool(thread, last_frame.method()->constants()); { JvmtiHideSingleStepping jhss(thread); LinkResolver::resolve_invoke(info, Handle(), pool, - get_index_u2_cpcache(thread, bytecode), bytecode, + last_frame.get_index_u2_cpcache(bytecode), bytecode, CHECK); } // end JvmtiHideSingleStepping - ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread); + ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry(); cp_cache_entry->set_method_handle(pool, info); } // First time execution: Resolve symbols, create a permanent CallSite object. void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) { Thread* THREAD = thread; + LastFrameAccessor last_frame(thread); const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; //TO DO: consider passing BCI to Java. - // int caller_bci = method(thread)->bci_from(bcp(thread)); + // int caller_bci = last_frame.method()->bci_from(last_frame.bcp()); // resolve method CallInfo info; - constantPoolHandle pool(thread, method(thread)->constants()); - int index = get_index_u4(thread, bytecode); + constantPoolHandle pool(thread, last_frame.method()->constants()); + int index = last_frame.get_index_u4(bytecode); { JvmtiHideSingleStepping jhss(thread); LinkResolver::resolve_invoke(info, Handle(), pool, @@ -905,11 +916,19 @@ // nm could have been unloaded so look it up again. It's unsafe // to examine nm directly since it might have been freed and used // for something else. - frame fr = thread->last_frame(); - Method* method = fr.interpreter_frame_method(); - int bci = method->bci_from(fr.interpreter_frame_bcp()); + LastFrameAccessor last_frame(thread); + Method* method = last_frame.method(); + int bci = method->bci_from(last_frame.bcp()); nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false); } + if (nm != NULL && thread->is_interp_only_mode()) { + // Normally we never get an nm if is_interp_only_mode() is true, because + // policy()->event has a check for this and won't compile the method when + // true. However, it's possible for is_interp_only_mode() to become true + // during the compilation. We don't want to return the nm in that case + // because we want to continue to execute interpreted. + nm = NULL; + } #ifndef PRODUCT if (TraceOnStackReplacement) { if (nm != NULL) { @@ -927,11 +946,11 @@ // flag, in case this method triggers classloading which will call into Java. UnlockFlagSaver fs(thread); - frame fr = thread->last_frame(); - assert(fr.is_interpreted_frame(), "must come from interpreter"); - methodHandle method(thread, fr.interpreter_frame_method()); + LastFrameAccessor last_frame(thread); + assert(last_frame.is_interpreted_frame(), "must come from interpreter"); + methodHandle method(thread, last_frame.method()); const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci; - const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci; + const int bci = branch_bcp != NULL ? method->bci_from(last_frame.bcp()) : InvocationEntryBci; assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending"); nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread); @@ -947,9 +966,9 @@ if (UseBiasedLocking) { ResourceMark rm; GrowableArray* objects_to_revoke = new GrowableArray(); - for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end(); - kptr < fr.interpreter_frame_monitor_begin(); - kptr = fr.next_monitor_in_interpreter_frame(kptr) ) { + for( BasicObjectLock *kptr = last_frame.monitor_end(); + kptr < last_frame.monitor_begin(); + kptr = last_frame.next_monitor(kptr) ) { if( kptr->obj() != NULL ) { objects_to_revoke->append(Handle(THREAD, kptr->obj())); } @@ -974,9 +993,9 @@ UnlockFlagSaver fs(thread); assert(ProfileInterpreter, "must be profiling interpreter"); - frame fr = thread->last_frame(); - assert(fr.is_interpreted_frame(), "must come from interpreter"); - methodHandle method(thread, fr.interpreter_frame_method()); + LastFrameAccessor last_frame(thread); + assert(last_frame.is_interpreted_frame(), "must come from interpreter"); + methodHandle method(thread, last_frame.method()); Method::build_interpreter_method_data(method, THREAD); if (HAS_PENDING_EXCEPTION) { assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); @@ -1021,9 +1040,9 @@ assert(ProfileInterpreter, "must be profiling interpreter"); ResourceMark rm(thread); HandleMark hm(thread); - frame fr = thread->last_frame(); - assert(fr.is_interpreted_frame(), "must come from interpreter"); - MethodData* h_mdo = fr.interpreter_frame_method()->method_data(); + LastFrameAccessor last_frame(thread); + assert(last_frame.is_interpreted_frame(), "must come from interpreter"); + MethodData* h_mdo = last_frame.method()->method_data(); // Grab a lock to ensure atomic access to setting the return bci and // the displacement. This can block and GC, invalidating all naked oops. @@ -1031,11 +1050,11 @@ // ProfileData is essentially a wrapper around a derived oop, so we // need to take the lock before making any ProfileData structures. - ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(fr.interpreter_frame_mdp())); + ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(last_frame.mdp())); guarantee(data != NULL, "profile data must be valid"); RetData* rdata = data->as_RetData(); address new_mdp = rdata->fixup_ret(return_bci, h_mdo); - fr.interpreter_frame_set_mdp(new_mdp); + last_frame.set_mdp(new_mdp); IRT_END IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m)) @@ -1060,7 +1079,8 @@ // We are called during regular safepoints and when the VM is // single stepping. If any thread is marked for single stepping, // then we may have JVMTI work to do. - JvmtiExport::at_single_stepping_point(thread, method(thread), bcp(thread)); + LastFrameAccessor last_frame(thread); + JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp()); } IRT_END @@ -1083,7 +1103,8 @@ } InstanceKlass* cp_entry_f1 = InstanceKlass::cast(cp_entry->f1_as_klass()); jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static); - JvmtiExport::post_field_access(thread, method(thread), bcp(thread), cp_entry_f1, h_obj, fid); + LastFrameAccessor last_frame(thread); + JvmtiExport::post_field_access(thread, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid); IRT_END IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, @@ -1138,17 +1159,20 @@ h_obj = Handle(thread, obj); } - JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), ik, h_obj, + LastFrameAccessor last_frame(thread); + JvmtiExport::post_raw_field_modification(thread, last_frame.method(), last_frame.bcp(), ik, h_obj, fid, sig_type, &fvalue); IRT_END IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread)) - JvmtiExport::post_method_entry(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread)); + LastFrameAccessor last_frame(thread); + JvmtiExport::post_method_entry(thread, last_frame.method(), last_frame.get_frame()); IRT_END IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread)) - JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread)); + LastFrameAccessor last_frame(thread); + JvmtiExport::post_method_exit(thread, last_frame.method(), last_frame.get_frame()); IRT_END IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc)) @@ -1372,10 +1396,10 @@ ResetNoHandleMark rnm; // In a LEAF entry. HandleMark hm; ResourceMark rm; - frame fr = thread->last_frame(); - assert(fr.is_interpreted_frame(), ""); - jint bci = fr.interpreter_frame_bci(); - methodHandle mh(thread, fr.interpreter_frame_method()); + LastFrameAccessor last_frame(thread); + assert(last_frame.is_interpreted_frame(), ""); + jint bci = last_frame.bci(); + methodHandle mh(thread, last_frame.method()); Bytecode_invoke invoke(mh, bci); ArgumentSizeComputer asc(invoke.signature()); int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver @@ -1421,10 +1445,10 @@ // The generated code still uses call_VM because that will set up the frame pointer for // bcp and method. IRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2)) - const frame f = thread->last_frame(); - assert(f.is_interpreted_frame(), "must be an interpreted frame"); - methodHandle mh(thread, f.interpreter_frame_method()); - BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2); + LastFrameAccessor last_frame(thread); + assert(last_frame.is_interpreted_frame(), "must be an interpreted frame"); + methodHandle mh(thread, last_frame.method()); + BytecodeTracer::trace(mh, last_frame.bcp(), tos, tos2); return preserve_this_value; IRT_END #endif // !PRODUCT diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/interpreter/interpreterRuntime.hpp --- a/src/hotspot/share/interpreter/interpreterRuntime.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/interpreter/interpreterRuntime.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -42,29 +42,54 @@ friend class PrintingClosure; // for method and bcp private: - // Helper functions to access current interpreter state - static frame last_frame(JavaThread *thread) { return thread->last_frame(); } - static Method* method(JavaThread *thread) { return last_frame(thread).interpreter_frame_method(); } - static address bcp(JavaThread *thread) { return last_frame(thread).interpreter_frame_bcp(); } - static int bci(JavaThread *thread) { return last_frame(thread).interpreter_frame_bci(); } - static void set_bcp_and_mdp(address bcp, JavaThread*thread); - static Bytecodes::Code code(JavaThread *thread) { + // Helper class to access current interpreter state + class LastFrameAccessor : public StackObj { + frame _last_frame; + public: + LastFrameAccessor(JavaThread* thread) { + assert(thread == Thread::current(), "sanity"); + _last_frame = thread->last_frame(); + } + bool is_interpreted_frame() const { return _last_frame.is_interpreted_frame(); } + Method* method() const { return _last_frame.interpreter_frame_method(); } + address bcp() const { return _last_frame.interpreter_frame_bcp(); } + int bci() const { return _last_frame.interpreter_frame_bci(); } + address mdp() const { return _last_frame.interpreter_frame_mdp(); } + + void set_bcp(address bcp) { _last_frame.interpreter_frame_set_bcp(bcp); } + void set_mdp(address dp) { _last_frame.interpreter_frame_set_mdp(dp); } + // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272) - return Bytecodes::code_at(method(thread), bcp(thread)); - } - static Bytecode bytecode(JavaThread *thread) { return Bytecode(method(thread), bcp(thread)); } - static int get_index_u1(JavaThread *thread, Bytecodes::Code bc) - { return bytecode(thread).get_index_u1(bc); } - static int get_index_u2(JavaThread *thread, Bytecodes::Code bc) - { return bytecode(thread).get_index_u2(bc); } - static int get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc) - { return bytecode(thread).get_index_u2_cpcache(bc); } - static int get_index_u4(JavaThread *thread, Bytecodes::Code bc) - { return bytecode(thread).get_index_u4(bc); } - static int number_of_dimensions(JavaThread *thread) { return bcp(thread)[3]; } + Bytecodes::Code code() const { return Bytecodes::code_at(method(), bcp()); } + + Bytecode bytecode() const { return Bytecode(method(), bcp()); } + int get_index_u1(Bytecodes::Code bc) const { return bytecode().get_index_u1(bc); } + int get_index_u2(Bytecodes::Code bc) const { return bytecode().get_index_u2(bc); } + int get_index_u2_cpcache(Bytecodes::Code bc) const + { return bytecode().get_index_u2_cpcache(bc); } + int get_index_u4(Bytecodes::Code bc) const { return bytecode().get_index_u4(bc); } + int number_of_dimensions() const { return bcp()[3]; } + ConstantPoolCacheEntry* cache_entry_at(int i) const + { return method()->constants()->cache()->entry_at(i); } + ConstantPoolCacheEntry* cache_entry() const { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); } - static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i) { return method(thread)->constants()->cache()->entry_at(i); } - static ConstantPoolCacheEntry* cache_entry(JavaThread *thread) { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); } + oop callee_receiver(Symbol* signature) { + return _last_frame.interpreter_callee_receiver(signature); + } + BasicObjectLock* monitor_begin() const { + return _last_frame.interpreter_frame_monitor_begin(); + } + BasicObjectLock* monitor_end() const { + return _last_frame.interpreter_frame_monitor_end(); + } + BasicObjectLock* next_monitor(BasicObjectLock* current) const { + return _last_frame.next_monitor_in_interpreter_frame(current); + } + + frame& get_frame() { return _last_frame; } + }; + + static void set_bcp_and_mdp(address bcp, JavaThread*thread); static void note_trap_inner(JavaThread* thread, int reason, const methodHandle& trap_method, int trap_bci, TRAPS); static void note_trap(JavaThread *thread, int reason, TRAPS); @@ -139,7 +164,7 @@ static void _breakpoint(JavaThread* thread, Method* method, address bcp); static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp); static void set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code); - static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(bcp(thread)) == Bytecodes::_breakpoint; } + static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint; } // Safepoints static void at_safepoint(JavaThread* thread); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/interpreter/linkResolver.cpp --- a/src/hotspot/share/interpreter/linkResolver.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/interpreter/linkResolver.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/defaultMethods.hpp" #include "classfile/javaClasses.hpp" #include "classfile/resolutionErrors.hpp" @@ -42,7 +43,6 @@ #include "oops/method.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/methodHandles.hpp" #include "prims/nativeLookup.hpp" #include "runtime/compilationPolicy.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/jvmci/jvmciCodeInstaller.cpp --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -45,7 +45,7 @@ // use). ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL); ConstantIntValue* CodeInstaller::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1); -ConstantIntValue* CodeInstaller::_int_0_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0); +ConstantIntValue* CodeInstaller::_int_0_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue((jint)0); ConstantIntValue* CodeInstaller::_int_1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1); ConstantIntValue* CodeInstaller::_int_2_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2); LocationValue* CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location()); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/jvmci/jvmciCompiler.cpp --- a/src/hotspot/share/jvmci/jvmciCompiler.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,10 +22,10 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/javaCalls.hpp" #include "runtime/handles.hpp" #include "jvmci/jvmciJavaClasses.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/jvmci/jvmciCompiler.hpp --- a/src/hotspot/share/jvmci/jvmciCompiler.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciCompiler.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -55,10 +55,13 @@ public: JVMCICompiler(); - static JVMCICompiler* instance(TRAPS) { + static JVMCICompiler* instance(bool require_non_null, TRAPS) { if (!EnableJVMCI) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled") } + if (_instance == NULL && require_non_null) { + THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "The JVMCI compiler instance has not been created"); + } return _instance; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/jvmci/jvmciCompilerToVM.cpp --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1000,7 +1000,7 @@ return -1; C2V_END -C2V_VMENTRY(void, setNotInlineableOrCompileable,(JNIEnv *, jobject, jobject jvmci_method)) +C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv *, jobject, jobject jvmci_method)) methodHandle method = CompilerToVM::asMethod(jvmci_method); method->set_not_c1_compilable(); method->set_not_c2_compilable(); @@ -1018,7 +1018,7 @@ Handle installed_code_handle(THREAD, JNIHandles::resolve(installed_code)); Handle speculation_log_handle(THREAD, JNIHandles::resolve(speculation_log)); - JVMCICompiler* compiler = JVMCICompiler::instance(CHECK_JNI_ERR); + JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR); TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer()); bool is_immutable_PIC = HotSpotCompiledCode::isImmutablePIC(compiled_code_handle) > 0; @@ -1039,7 +1039,7 @@ if (result != JVMCIEnv::ok) { assert(cb == NULL, "should be"); } else { - if (!installed_code_handle.is_null()) { + if (installed_code_handle.not_null()) { assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type"); nmethod::invalidate_installed_code(installed_code_handle, CHECK_0); { @@ -1058,13 +1058,6 @@ HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size()); } } - nmethod* nm = cb->as_nmethod_or_null(); - if (nm != NULL && installed_code_handle->is_scavengable()) { - assert(nm->detect_scavenge_root_oops(), "nm should be scavengable if installed_code is scavengable"); - if (!UseG1GC) { - assert(nm->on_scavenge_root_list(), "nm should be on scavengable list"); - } - } } } return result; @@ -1143,7 +1136,7 @@ C2V_END C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject)) - JVMCICompiler* compiler = JVMCICompiler::instance(CHECK); + JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK); CompilerStatistics* stats = compiler->stats(); stats->_standard.reset(); stats->_osr.reset(); @@ -1697,7 +1690,7 @@ } while (length > 0) { jbyte* start = array->byte_at_addr(offset); - tty->write((char*) start, MIN2(length, O_BUFLEN)); + tty->write((char*) start, MIN2(length, (jint)O_BUFLEN)); length -= O_BUFLEN; offset += O_BUFLEN; } @@ -1820,7 +1813,7 @@ {CC "getImplementor", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getImplementor)}, {CC "getStackTraceElement", CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, {CC "methodIsIgnoredBySecurityStackWalk", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)}, - {CC "setNotInlineableOrCompileable", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(setNotInlineableOrCompileable)}, + {CC "setNotInlinableOrCompilable", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(setNotInlinableOrCompilable)}, {CC "isCompilable", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(isCompilable)}, {CC "hasNeverInlineDirective", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(hasNeverInlineDirective)}, {CC "shouldInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(shouldInlineMethod)}, diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/jvmci/jvmciEnv.cpp --- a/src/hotspot/share/jvmci/jvmciEnv.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -521,7 +521,9 @@ debug_info, dependencies, code_buffer, frame_words, oop_map_set, handler_table, &implicit_tbl, - compiler, comp_level, installed_code, speculation_log); + compiler, comp_level, + JNIHandles::make_weak_global(installed_code), + JNIHandles::make_weak_global(speculation_log)); // Free codeBlobs //code_buffer->free_blob(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/jvmci/jvmciRuntime.cpp --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "asm/codeBuffer.hpp" #include "classfile/javaClasses.inline.hpp" #include "code/codeCache.hpp" @@ -37,7 +38,6 @@ #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "oops/objArrayOop.inline.hpp" -#include "prims/jvm.h" #include "runtime/biasedLocking.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/reflection.hpp" @@ -611,7 +611,7 @@ } JRT_END -JRT_ENTRY(jint, JVMCIRuntime::test_deoptimize_call_int(JavaThread* thread, int value)) +JRT_ENTRY(int, JVMCIRuntime::test_deoptimize_call_int(JavaThread* thread, int value)) deopt_caller(); return value; JRT_END @@ -821,28 +821,37 @@ } CompLevel JVMCIRuntime::adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) { - JVMCICompiler* compiler = JVMCICompiler::instance(thread); + JVMCICompiler* compiler = JVMCICompiler::instance(false, thread); if (compiler != NULL && compiler->is_bootstrapping()) { return level; } - if (!is_HotSpotJVMCIRuntime_initialized() || !_comp_level_adjustment) { + if (!is_HotSpotJVMCIRuntime_initialized() || _comp_level_adjustment == JVMCIRuntime::none) { // JVMCI cannot participate in compilation scheduling until // JVMCI is initialized and indicates it wants to participate. return level; } #define CHECK_RETURN THREAD); \ -if (HAS_PENDING_EXCEPTION) { \ - Handle exception(THREAD, PENDING_EXCEPTION); \ - CLEAR_PENDING_EXCEPTION; \ -\ - java_lang_Throwable::java_printStackTrace(exception, THREAD); \ if (HAS_PENDING_EXCEPTION) { \ + Handle exception(THREAD, PENDING_EXCEPTION); \ CLEAR_PENDING_EXCEPTION; \ + \ + if (exception->is_a(SystemDictionary::ThreadDeath_klass())) { \ + /* In the special case of ThreadDeath, we need to reset the */ \ + /* pending async exception so that it is propagated. */ \ + thread->set_pending_async_exception(exception()); \ + return level; \ + } \ + tty->print("Uncaught exception while adjusting compilation level: "); \ + java_lang_Throwable::print(exception(), tty); \ + tty->cr(); \ + java_lang_Throwable::print_stack_trace(exception, tty); \ + if (HAS_PENDING_EXCEPTION) { \ + CLEAR_PENDING_EXCEPTION; \ + } \ + return level; \ } \ - return level; \ -} \ -(void)(0 + (void)(0 Thread* THREAD = thread; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/jvmci/jvmci_globals.cpp --- a/src/hotspot/share/jvmci/jvmci_globals.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmci_globals.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,8 +23,8 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "jvmci/jvmci_globals.hpp" -#include "prims/jvm.h" #include "utilities/defaultStream.hpp" #include "runtime/globals_extension.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/logging/logConfiguration.cpp --- a/src/hotspot/share/logging/logConfiguration.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/logging/logConfiguration.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,6 +22,7 @@ * */ #include "precompiled.hpp" +#include "jvm.h" #include "logging/log.hpp" #include "logging/logConfiguration.hpp" #include "logging/logDecorations.hpp" @@ -34,7 +35,6 @@ #include "logging/logTagSet.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/os.inline.hpp" #include "runtime/semaphore.hpp" #include "utilities/globalDefinitions.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/logging/logDecorations.cpp --- a/src/hotspot/share/logging/logDecorations.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/logging/logDecorations.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,9 +22,9 @@ * */ #include "precompiled.hpp" +#include "jvm.h" #include "logging/logConfiguration.hpp" #include "logging/logDecorations.hpp" -#include "prims/jvm.h" #include "runtime/os.inline.hpp" #include "runtime/thread.inline.hpp" #include "services/management.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/logging/logFileOutput.cpp --- a/src/hotspot/share/logging/logFileOutput.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/logging/logFileOutput.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,11 +22,11 @@ * */ #include "precompiled.hpp" +#include "jvm.h" #include "logging/log.hpp" #include "logging/logConfiguration.hpp" #include "logging/logFileOutput.hpp" #include "memory/allocation.inline.hpp" -#include "prims/jvm.h" #include "runtime/arguments.hpp" #include "runtime/os.inline.hpp" #include "utilities/globalDefinitions.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/logging/logFileStreamOutput.cpp --- a/src/hotspot/share/logging/logFileStreamOutput.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/logging/logFileStreamOutput.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,12 +22,12 @@ * */ #include "precompiled.hpp" +#include "jvm.h" #include "logging/logDecorators.hpp" #include "logging/logDecorations.hpp" #include "logging/logFileStreamOutput.hpp" #include "logging/logMessageBuffer.hpp" #include "memory/allocation.inline.hpp" -#include "prims/jvm.h" static bool initialized; static union { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/logging/logOutput.cpp --- a/src/hotspot/share/logging/logOutput.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/logging/logOutput.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,11 +22,11 @@ * */ #include "precompiled.hpp" +#include "jvm.h" #include "logging/logFileStreamOutput.hpp" #include "logging/logOutput.hpp" #include "logging/logTagSet.hpp" #include "memory/allocation.inline.hpp" -#include "prims/jvm.h" #include "runtime/mutexLocker.hpp" #include "runtime/os.inline.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/logging/logTagSet.cpp --- a/src/hotspot/share/logging/logTagSet.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/logging/logTagSet.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,6 +22,7 @@ * */ #include "precompiled.hpp" +#include "jvm.h" #include "logging/logDecorations.hpp" #include "logging/logFileStreamOutput.hpp" #include "logging/logLevel.hpp" @@ -31,7 +32,6 @@ #include "logging/logTagSet.hpp" #include "logging/logTagSetDescriptions.hpp" #include "memory/allocation.inline.hpp" -#include "prims/jvm.h" #include "utilities/ostream.hpp" LogTagSet* LogTagSet::_list = NULL; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/filemap.cpp --- a/src/hotspot/share/memory/filemap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/filemap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/compactHashtable.inline.hpp" #include "classfile/sharedClassUtil.hpp" @@ -42,7 +43,6 @@ #include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "oops/objArrayOop.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/java.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/heap.hpp --- a/src/hotspot/share/memory/heap.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/heap.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -160,7 +160,18 @@ char* high_boundary() const { return _memory.high_boundary(); } bool contains(const void* p) const { return low_boundary() <= p && p < high(); } - bool contains_blob(const CodeBlob* blob) const { return contains(blob->code_begin()); } + bool contains_blob(const CodeBlob* blob) const { + // AOT CodeBlobs (i.e. AOTCompiledMethod) objects aren't allocated in the AOTCodeHeap but on the C-Heap. + // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated + // directly in their corresponding CodeHeap with their code appended to the actual C++ object. + // So all CodeBlobs except AOTCompiledMethod are continuous in memory with their data and code while + // AOTCompiledMethod and their code/data is distributed in the C-Heap. This means we can use the + // address of a CodeBlob object in order to locate it in its heap while we have to use the address + // of the actual code an AOTCompiledMethod object is pointing to in order to locate it. + // Notice that for an ordinary CodeBlob with code size zero, code_begin() may point beyond the object! + const void* start = AOT_ONLY( (code_blob_type() == CodeBlobType::AOT) ? blob->code_begin() : ) (void*)blob; + return contains(start); + } virtual void* find_start(void* p) const; // returns the block containing p or NULL virtual CodeBlob* find_blob_unsafe(void* start) const; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/metachunk.cpp --- a/src/hotspot/share/memory/metachunk.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/metachunk.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -55,8 +55,8 @@ _container(container) { _top = initial_top(); + set_is_tagged_free(false); #ifdef ASSERT - set_is_tagged_free(false); mangle(uninitMetaWordVal); #endif } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/metachunk.hpp --- a/src/hotspot/share/memory/metachunk.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/metachunk.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -102,7 +102,7 @@ // Current allocation top. MetaWord* _top; - DEBUG_ONLY(bool _is_tagged_free;) + bool _is_tagged_free; MetaWord* initial_top() const { return (MetaWord*)this + overhead(); } MetaWord* top() const { return _top; } @@ -138,10 +138,8 @@ size_t used_word_size() const; size_t free_word_size() const; -#ifdef ASSERT bool is_tagged_free() { return _is_tagged_free; } void set_is_tagged_free(bool v) { _is_tagged_free = v; } -#endif bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/metaspace.cpp --- a/src/hotspot/share/memory/metaspace.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/metaspace.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -108,6 +108,18 @@ return (ChunkIndex) (i+1); } +static const char* scale_unit(size_t scale) { + switch(scale) { + case 1: return "BYTES"; + case K: return "KB"; + case M: return "MB"; + case G: return "GB"; + default: + ShouldNotReachHere(); + return NULL; + } +} + volatile intptr_t MetaspaceGC::_capacity_until_GC = 0; uint MetaspaceGC::_shrink_factor = 0; bool MetaspaceGC::_should_concurrent_collect = false; @@ -176,7 +188,7 @@ void locked_get_statistics(ChunkManagerStatistics* stat) const; void get_statistics(ChunkManagerStatistics* stat) const; - static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out); + static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale); public: @@ -283,7 +295,7 @@ // Prints composition for both non-class and (if available) // class chunk manager. - static void print_all_chunkmanagers(outputStream* out); + static void print_all_chunkmanagers(outputStream* out, size_t scale = 1); }; class SmallBlocks : public CHeapObj { @@ -480,6 +492,7 @@ #endif void print_on(outputStream* st) const; + void print_map(outputStream* st, bool is_class) const; }; #define assert_is_aligned(value, alignment) \ @@ -531,6 +544,94 @@ } } +void VirtualSpaceNode::print_map(outputStream* st, bool is_class) const { + + // Format: + // + // . .. . . .. + // SSxSSMMMMMMMMMMMMMMMMsssXX + // 112114444444444444444 + // . .. . . .. + // SSxSSMMMMMMMMMMMMMMMMsssXX + // 112114444444444444444 + + if (bottom() == top()) { + return; + } + + // First line: dividers for every med-chunk-sized interval + // Second line: a dot for the start of a chunk + // Third line: a letter per chunk type (x,s,m,h), uppercase if in use. + + const size_t spec_chunk_size = is_class ? ClassSpecializedChunk : SpecializedChunk; + const size_t small_chunk_size = is_class ? ClassSmallChunk : SmallChunk; + const size_t med_chunk_size = is_class ? ClassMediumChunk : MediumChunk; + + int line_len = 100; + const size_t section_len = align_up(spec_chunk_size * line_len, med_chunk_size); + line_len = (int)(section_len / spec_chunk_size); + + char* line1 = (char*)os::malloc(line_len, mtInternal); + char* line2 = (char*)os::malloc(line_len, mtInternal); + char* line3 = (char*)os::malloc(line_len, mtInternal); + int pos = 0; + const MetaWord* p = bottom(); + const Metachunk* chunk = (const Metachunk*)p; + const MetaWord* chunk_end = p + chunk->word_size(); + while (p < top()) { + if (pos == line_len) { + pos = 0; + st->fill_to(22); + st->print_raw(line1, line_len); + st->cr(); + st->fill_to(22); + st->print_raw(line2, line_len); + st->cr(); + } + if (pos == 0) { + st->print(PTR_FORMAT ":", p2i(p)); + } + if (p == chunk_end) { + chunk = (Metachunk*)p; + chunk_end = p + chunk->word_size(); + } + if (p == (const MetaWord*)chunk) { + // chunk starts. + line1[pos] = '.'; + } else { + line1[pos] = ' '; + } + // Line 2: chunk type (x=spec, s=small, m=medium, h=humongous), uppercase if + // chunk is in use. + const bool chunk_is_free = ((Metachunk*)chunk)->is_tagged_free(); + if (chunk->word_size() == spec_chunk_size) { + line2[pos] = chunk_is_free ? 'x' : 'X'; + } else if (chunk->word_size() == small_chunk_size) { + line2[pos] = chunk_is_free ? 's' : 'S'; + } else if (chunk->word_size() == med_chunk_size) { + line2[pos] = chunk_is_free ? 'm' : 'M'; + } else if (chunk->word_size() > med_chunk_size) { + line2[pos] = chunk_is_free ? 'h' : 'H'; + } else { + ShouldNotReachHere(); + } + p += spec_chunk_size; + pos ++; + } + if (pos > 0) { + st->fill_to(22); + st->print_raw(line1, pos); + st->cr(); + st->fill_to(22); + st->print_raw(line2, pos); + st->cr(); + } + os::free(line1); + os::free(line2); + os::free(line3); +} + + #ifdef ASSERT uintx VirtualSpaceNode::container_count_slow() { uintx count = 0; @@ -637,6 +738,7 @@ void purge(ChunkManager* chunk_manager); void print_on(outputStream* st) const; + void print_map(outputStream* st) const; class VirtualSpaceListIterator : public StackObj { VirtualSpaceNode* _virtual_spaces; @@ -1449,6 +1551,18 @@ } } +void VirtualSpaceList::print_map(outputStream* st) const { + VirtualSpaceNode* list = virtual_space_list(); + VirtualSpaceListIterator iter(list); + unsigned i = 0; + while (iter.repeat()) { + st->print_cr("Node %u:", i); + VirtualSpaceNode* node = iter.get_next(); + node->print_map(st, this->is_class()); + i ++; + } +} + // MetaspaceGC methods // VM_CollectForMetadataAllocation is the vm operation used to GC. @@ -1724,7 +1838,6 @@ #endif // ChunkManager methods - size_t ChunkManager::free_chunks_total_words() { return _free_chunks_total; } @@ -1923,11 +2036,10 @@ // Remove it from the links to this freelist chunk->set_next(NULL); chunk->set_prev(NULL); -#ifdef ASSERT + // Chunk is no longer on any freelist. Setting to false make container_count_slow() // work. chunk->set_is_tagged_free(false); -#endif chunk->container()->inc_container_count(); slow_locked_verify(); @@ -1995,7 +2107,7 @@ chunk_size_name(index), p2i(chunk), chunk->word_size()); } chunk->container()->dec_container_count(); - DEBUG_ONLY(chunk->set_is_tagged_free(true);) + chunk->set_is_tagged_free(true); // Chunk has been added; update counters. account_for_added_chunk(chunk); @@ -2057,22 +2169,45 @@ locked_get_statistics(stat); } -void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out) { +void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) { size_t total = 0; + assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale"); + + const char* unit = scale_unit(scale); for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { - out->print_cr(" " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total " SIZE_FORMAT " bytes", - stat->num_by_type[i], chunk_size_name(i), - stat->single_size_by_type[i], - stat->total_size_by_type[i]); + out->print(" " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total ", + stat->num_by_type[i], chunk_size_name(i), + stat->single_size_by_type[i]); + if (scale == 1) { + out->print_cr(SIZE_FORMAT " bytes", stat->total_size_by_type[i]); + } else { + out->print_cr("%.2f%s", (float)stat->total_size_by_type[i] / scale, unit); + } + total += stat->total_size_by_type[i]; } - out->print_cr(" " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes", - stat->num_humongous_chunks, stat->total_size_humongous_chunks); + + total += stat->total_size_humongous_chunks; - out->print_cr(" total size: " SIZE_FORMAT ".", total); + + if (scale == 1) { + out->print_cr(" " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes", + stat->num_humongous_chunks, stat->total_size_humongous_chunks); + + out->print_cr(" total size: " SIZE_FORMAT " bytes.", total); + } else { + out->print_cr(" " SIZE_FORMAT " humongous chunks, total %.2f%s", + stat->num_humongous_chunks, + (float)stat->total_size_humongous_chunks / scale, unit); + + out->print_cr(" total size: %.2f%s.", (float)total / scale, unit); + } + } -void ChunkManager::print_all_chunkmanagers(outputStream* out) { +void ChunkManager::print_all_chunkmanagers(outputStream* out, size_t scale) { + assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale"); + // Note: keep lock protection only to retrieving statistics; keep printing // out of lock protection ChunkManagerStatistics stat; @@ -2080,7 +2215,7 @@ const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata(); if (non_class_cm != NULL) { non_class_cm->get_statistics(&stat); - ChunkManager::print_statistics(&stat, out); + ChunkManager::print_statistics(&stat, out, scale); } else { out->print_cr("unavailable."); } @@ -2088,7 +2223,7 @@ const ChunkManager* const class_cm = Metaspace::chunk_manager_class(); if (class_cm != NULL) { class_cm->get_statistics(&stat); - ChunkManager::print_statistics(&stat, out); + ChunkManager::print_statistics(&stat, out, scale); } else { out->print_cr("unavailable."); } @@ -2911,9 +3046,9 @@ size_t free_bytes = free_bytes_slow(mdtype); size_t used_and_free = used_bytes + free_bytes + free_chunks_capacity_bytes; - out->print_cr(" Chunk accounting: used in chunks " SIZE_FORMAT + out->print_cr(" Chunk accounting: (used in chunks " SIZE_FORMAT "K + unused in chunks " SIZE_FORMAT "K + " - " capacity in free chunks " SIZE_FORMAT "K = " SIZE_FORMAT + " capacity in free chunks " SIZE_FORMAT "K) = " SIZE_FORMAT "K capacity in allocated chunks " SIZE_FORMAT "K", used_bytes / K, free_bytes / K, @@ -2981,6 +3116,194 @@ } } +class MetadataStats VALUE_OBJ_CLASS_SPEC { +private: + size_t _capacity; + size_t _used; + size_t _free; + size_t _waste; + +public: + MetadataStats() : _capacity(0), _used(0), _free(0), _waste(0) { } + MetadataStats(size_t capacity, size_t used, size_t free, size_t waste) + : _capacity(capacity), _used(used), _free(free), _waste(waste) { } + + void add(const MetadataStats& stats) { + _capacity += stats.capacity(); + _used += stats.used(); + _free += stats.free(); + _waste += stats.waste(); + } + + size_t capacity() const { return _capacity; } + size_t used() const { return _used; } + size_t free() const { return _free; } + size_t waste() const { return _waste; } + + void print_on(outputStream* out, size_t scale) const; +}; + + +void MetadataStats::print_on(outputStream* out, size_t scale) const { + const char* unit = scale_unit(scale); + out->print_cr("capacity=%10.2f%s used=%10.2f%s free=%10.2f%s waste=%10.2f%s", + (float)capacity() / scale, unit, + (float)used() / scale, unit, + (float)free() / scale, unit, + (float)waste() / scale, unit); +} + +class PrintCLDMetaspaceInfoClosure : public CLDClosure { +private: + outputStream* _out; + size_t _scale; + + size_t _total_count; + MetadataStats _total_metadata; + MetadataStats _total_class; + + size_t _total_anon_count; + MetadataStats _total_anon_metadata; + MetadataStats _total_anon_class; + +public: + PrintCLDMetaspaceInfoClosure(outputStream* out, size_t scale = K) + : _out(out), _scale(scale), _total_count(0), _total_anon_count(0) { } + + ~PrintCLDMetaspaceInfoClosure() { + print_summary(); + } + + void do_cld(ClassLoaderData* cld) { + assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); + + if (cld->is_unloading()) return; + Metaspace* msp = cld->metaspace_or_null(); + if (msp == NULL) { + return; + } + + bool anonymous = false; + if (cld->is_anonymous()) { + _out->print_cr("ClassLoader: for anonymous class"); + anonymous = true; + } else { + ResourceMark rm; + _out->print_cr("ClassLoader: %s", cld->loader_name()); + } + + print_metaspace(msp, anonymous); + _out->cr(); + } + +private: + void print_metaspace(Metaspace* msp, bool anonymous); + void print_summary() const; +}; + +void PrintCLDMetaspaceInfoClosure::print_metaspace(Metaspace* msp, bool anonymous){ + assert(msp != NULL, "Sanity"); + SpaceManager* vsm = msp->vsm(); + const char* unit = scale_unit(_scale); + + size_t capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord; + size_t used = vsm->sum_used_in_chunks_in_use() * BytesPerWord; + size_t free = vsm->sum_free_in_chunks_in_use() * BytesPerWord; + size_t waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord; + + _total_count ++; + MetadataStats metadata_stats(capacity, used, free, waste); + _total_metadata.add(metadata_stats); + + if (anonymous) { + _total_anon_count ++; + _total_anon_metadata.add(metadata_stats); + } + + _out->print(" Metadata "); + metadata_stats.print_on(_out, _scale); + + if (Metaspace::using_class_space()) { + vsm = msp->class_vsm(); + + capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord; + used = vsm->sum_used_in_chunks_in_use() * BytesPerWord; + free = vsm->sum_free_in_chunks_in_use() * BytesPerWord; + waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord; + + MetadataStats class_stats(capacity, used, free, waste); + _total_class.add(class_stats); + + if (anonymous) { + _total_anon_class.add(class_stats); + } + + _out->print(" Class data "); + class_stats.print_on(_out, _scale); + } +} + +void PrintCLDMetaspaceInfoClosure::print_summary() const { + const char* unit = scale_unit(_scale); + _out->cr(); + _out->print_cr("Summary:"); + + MetadataStats total; + total.add(_total_metadata); + total.add(_total_class); + + _out->print(" Total class loaders=" SIZE_FORMAT_W(6) " ", _total_count); + total.print_on(_out, _scale); + + _out->print(" Metadata "); + _total_metadata.print_on(_out, _scale); + + if (Metaspace::using_class_space()) { + _out->print(" Class data "); + _total_class.print_on(_out, _scale); + } + _out->cr(); + + MetadataStats total_anon; + total_anon.add(_total_anon_metadata); + total_anon.add(_total_anon_class); + + _out->print("For anonymous classes=" SIZE_FORMAT_W(6) " ", _total_anon_count); + total_anon.print_on(_out, _scale); + + _out->print(" Metadata "); + _total_anon_metadata.print_on(_out, _scale); + + if (Metaspace::using_class_space()) { + _out->print(" Class data "); + _total_anon_class.print_on(_out, _scale); + } +} + +void MetaspaceAux::print_metadata_for_nmt(outputStream* out, size_t scale) { + const char* unit = scale_unit(scale); + out->print_cr("Metaspaces:"); + out->print_cr(" Metadata space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s", + reserved_bytes(Metaspace::NonClassType) / scale, unit, + committed_bytes(Metaspace::NonClassType) / scale, unit); + if (Metaspace::using_class_space()) { + out->print_cr(" Class space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s", + reserved_bytes(Metaspace::ClassType) / scale, unit, + committed_bytes(Metaspace::ClassType) / scale, unit); + } + + out->cr(); + ChunkManager::print_all_chunkmanagers(out, scale); + + out->cr(); + out->print_cr("Per-classloader metadata:"); + out->cr(); + + PrintCLDMetaspaceInfoClosure cl(out, scale); + ClassLoaderDataGraph::cld_do(&cl); +} + + // Dump global metaspace things from the end of ClassLoaderDataGraph void MetaspaceAux::dump(outputStream* out) { out->print_cr("All Metaspace:"); @@ -2989,6 +3312,31 @@ print_waste(out); } +// Prints an ASCII representation of the given space. +void MetaspaceAux::print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype) { + MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); + const bool for_class = mdtype == Metaspace::ClassType ? true : false; + VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list(); + if (vsl != NULL) { + if (for_class) { + if (!Metaspace::using_class_space()) { + out->print_cr("No Class Space."); + return; + } + out->print_raw("---- Metaspace Map (Class Space) ----"); + } else { + out->print_raw("---- Metaspace Map (Non-Class Space) ----"); + } + // Print legend: + out->cr(); + out->print_cr("Chunk Types (uppercase chunks are in use): x-specialized, s-small, m-medium, h-humongous."); + out->cr(); + VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list(); + vsl->print_map(out); + out->cr(); + } +} + void MetaspaceAux::verify_free_chunks() { Metaspace::chunk_manager_metadata()->verify(); if (Metaspace::using_class_space()) { @@ -3627,6 +3975,7 @@ } LogStream ls(log.info()); MetaspaceAux::dump(&ls); + MetaspaceAux::print_metaspace_map(&ls, mdtype); ChunkManager::print_all_chunkmanagers(&ls); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/metaspace.hpp --- a/src/hotspot/share/memory/metaspace.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/metaspace.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -63,6 +63,7 @@ class MetaWord; class Mutex; class outputStream; +class PrintCLDMetaspaceInfoClosure; class SpaceManager; class VirtualSpaceList; @@ -87,6 +88,7 @@ friend class MetaspaceAux; friend class MetaspaceShared; friend class CollectorPolicy; + friend class PrintCLDMetaspaceInfoClosure; public: enum MetadataType { @@ -347,6 +349,8 @@ return min_chunk_size_words() * BytesPerWord; } + static void print_metadata_for_nmt(outputStream* out, size_t scale = K); + static bool has_chunk_free_list(Metaspace::MetadataType mdtype); static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype); @@ -357,6 +361,10 @@ static void print_class_waste(outputStream* out); static void print_waste(outputStream* out); + + // Prints an ASCII representation of the given space. + static void print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype); + static void dump(outputStream* out); static void verify_free_chunks(); // Checks that the values returned by allocated_capacity_bytes() and diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/metaspaceShared.cpp --- a/src/hotspot/share/memory/metaspaceShared.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/metaspaceShared.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classListParser.hpp" #include "classfile/classLoaderExt.hpp" #include "classfile/dictionary.hpp" @@ -55,7 +56,6 @@ #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayKlass.hpp" -#include "prims/jvm.h" #include "prims/jvmtiRedefineClasses.hpp" #include "runtime/timerTrace.hpp" #include "runtime/os.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/memory/universe.cpp --- a/src/hotspot/share/memory/universe.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/memory/universe.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -32,10 +32,10 @@ #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/dependencies.hpp" +#include "gc/serial/serialHeap.hpp" #include "gc/shared/cardTableModRefBS.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/gcLocker.inline.hpp" -#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/generation.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/space.hpp" @@ -762,7 +762,7 @@ return Universe::create_heap_with_policy(); #endif } else if (UseSerialGC) { - return Universe::create_heap_with_policy(); + return Universe::create_heap_with_policy(); } ShouldNotReachHere(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/oops/constantPool.cpp --- a/src/hotspot/share/oops/constantPool.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/oops/constantPool.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/metadataOnStackMark.hpp" @@ -41,7 +42,6 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/fieldType.hpp" #include "runtime/init.hpp" #include "runtime/javaCalls.hpp" @@ -305,14 +305,9 @@ constantPoolHandle cp(THREAD, this); for (int index = 1; index < length(); index++) { // Index 0 is unused - if (tag_at(index).is_string()) { - Symbol* sym = cp->unresolved_string_at(index); - // Look up only. Only resolve references to already interned strings. - oop str = StringTable::lookup(sym); - if (str != NULL) { - int cache_index = cp->cp_to_object_index(index); - cp->string_at_put(index, cache_index, str); - } + if (tag_at(index).is_string() && !cp->is_pseudo_string_at(index)) { + int cache_index = cp->cp_to_object_index(index); + string_at_impl(cp, index, cache_index, CHECK); } } } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/oops/generateOopMap.cpp --- a/src/hotspot/share/oops/generateOopMap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/oops/generateOopMap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,13 +23,13 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "interpreter/bytecodeStream.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "oops/generateOopMap.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" -#include "prims/jvm.h" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/relocator.hpp" @@ -2146,8 +2146,14 @@ // Append method name char msg_buffer2[512]; jio_snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg_buffer, method()->name()->as_C_string()); - _exception = Exceptions::new_exception(Thread::current(), - vmSymbols::java_lang_LinkageError(), msg_buffer2); + if (Thread::current()->can_call_java()) { + _exception = Exceptions::new_exception(Thread::current(), + vmSymbols::java_lang_LinkageError(), msg_buffer2); + } else { + // We cannot instantiate an exception object from a compiler thread. + // Exit the VM with a useful error message. + fatal("%s", msg_buffer2); + } } void GenerateOopMap::report_error(const char *format, ...) { @@ -2159,14 +2165,7 @@ void GenerateOopMap::verify_error(const char *format, ...) { // We do not distinguish between different types of errors for verification // errors. Let the verifier give a better message. - const char *msg = "Illegal class file encountered. Try running with -Xverify:all"; - _got_error = true; - // Append method name - char msg_buffer2[512]; - jio_snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg, - method()->name()->as_C_string()); - _exception = Exceptions::new_exception(Thread::current(), - vmSymbols::java_lang_LinkageError(), msg_buffer2); + report_error("Illegal class file encountered. Try running with -Xverify:all"); } // diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/oops/instanceKlass.cpp --- a/src/hotspot/share/oops/instanceKlass.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/oops/instanceKlass.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "aot/aotLoader.hpp" #include "classfile/classFileParser.hpp" #include "classfile/classFileStream.hpp" @@ -59,7 +60,6 @@ #include "oops/method.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiRedefineClasses.hpp" #include "prims/jvmtiThreadState.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/oops/klassVtable.cpp --- a/src/hotspot/share/oops/klassVtable.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/oops/klassVtable.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "gc/shared/gcLocker.hpp" @@ -36,7 +37,6 @@ #include "oops/method.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/arguments.hpp" #include "runtime/handles.inline.hpp" #include "utilities/copy.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/oops/method.hpp --- a/src/hotspot/share/oops/method.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/oops/method.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -271,7 +271,7 @@ int highest_osr_comp_level() const; void set_highest_osr_comp_level(int level); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // Count of times method was exited via exception while interpreting void interpreter_throwout_increment(TRAPS) { MethodCounters* mcs = get_method_counters(CHECK); @@ -426,7 +426,7 @@ return (mcs == NULL) ? 0 : mcs->interpreter_invocation_count(); } } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI int increment_interpreter_invocation_count(TRAPS) { if (TieredCompilation) ShouldNotReachHere(); MethodCounters* mcs = get_method_counters(CHECK_0); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/oops/methodCounters.hpp --- a/src/hotspot/share/oops/methodCounters.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/oops/methodCounters.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -40,7 +40,7 @@ #if INCLUDE_AOT Method* _method; // Back link to Method #endif -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting #endif @@ -130,7 +130,7 @@ MetaspaceObj::Type type() const { return MethodCountersType; } void clear_counters(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI int interpreter_invocation_count() { return _interpreter_invocation_count; @@ -154,7 +154,7 @@ _interpreter_throwout_count = count; } -#else // defined(COMPILER2) || INCLUDE_JVMCI +#else // COMPILER2_OR_JVMCI int interpreter_invocation_count() { return 0; @@ -170,7 +170,7 @@ assert(count == 0, "count must be 0"); } -#endif // defined(COMPILER2) || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI #if INCLUDE_JVMTI u2 number_of_breakpoints() const { return _number_of_breakpoints; } @@ -213,7 +213,7 @@ return byte_offset_of(MethodCounters, _nmethod_age); } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(MethodCounters, _interpreter_invocation_count); @@ -223,14 +223,14 @@ return offset_of(MethodCounters, _interpreter_invocation_count); } -#else // defined(COMPILER2) || INCLUDE_JVMCI +#else // COMPILER2_OR_JVMCI static ByteSize interpreter_invocation_counter_offset() { ShouldNotReachHere(); return in_ByteSize(0); } -#endif // defined(COMPILER2) || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI static ByteSize invocation_counter_offset() { return byte_offset_of(MethodCounters, _invocation_counter); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/castnode.cpp --- a/src/hotspot/share/opto/castnode.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/castnode.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -237,8 +237,8 @@ if (in_type != NULL && this_type != NULL && (in_type->_lo != this_type->_lo || in_type->_hi != this_type->_hi)) { - int lo1 = this_type->_lo; - int hi1 = this_type->_hi; + jint lo1 = this_type->_lo; + jint hi1 = this_type->_hi; int w1 = this_type->_widen; if (lo1 >= 0) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/loopTransform.cpp --- a/src/hotspot/share/opto/loopTransform.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/loopTransform.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2129,7 +2129,7 @@ // Look for trip_counter + offset vs limit Node *rc_exp = cmp->in(1); Node *limit = cmp->in(2); - jint scale_con= 1; // Assume trip counter not scaled + int scale_con= 1; // Assume trip counter not scaled Node *limit_c = get_ctrl(limit); if( loop->is_member(get_loop(limit_c) ) ) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/mulnode.cpp --- a/src/hotspot/share/opto/mulnode.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/mulnode.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -235,13 +235,13 @@ const TypeInt *r1 = t1->is_int(); // Fetch endpoints of all ranges - int32_t lo0 = r0->_lo; + jint lo0 = r0->_lo; double a = (double)lo0; - int32_t hi0 = r0->_hi; + jint hi0 = r0->_hi; double b = (double)hi0; - int32_t lo1 = r1->_lo; + jint lo1 = r1->_lo; double c = (double)lo1; - int32_t hi1 = r1->_hi; + jint hi1 = r1->_hi; double d = (double)hi1; // Compute all endpoints & check for overflow diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/output.cpp --- a/src/hotspot/share/opto/output.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/output.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -577,10 +577,10 @@ // arbitrary, and are not tied to any machine-level encodings.) #ifdef _LP64 if( t->base() == Type::DoubleBot || t->base() == Type::DoubleCon ) { - array->append(new ConstantIntValue(0)); + array->append(new ConstantIntValue((jint)0)); array->append(new_loc_value( _regalloc, regnum, Location::dbl )); } else if ( t->base() == Type::Long ) { - array->append(new ConstantIntValue(0)); + array->append(new ConstantIntValue((jint)0)); array->append(new_loc_value( _regalloc, regnum, Location::lng )); } else if ( t->base() == Type::RawPtr ) { // jsr/ret return address which must be restored into a the full @@ -663,7 +663,7 @@ case Type::DoubleCon: { jdouble d = t->is_double_constant()->getd(); #ifdef _LP64 - array->append(new ConstantIntValue(0)); + array->append(new ConstantIntValue((jint)0)); array->append(new ConstantDoubleValue(d)); #else // Repack the double as two jints. @@ -683,7 +683,7 @@ case Type::Long: { jlong d = t->is_long()->get_con(); #ifdef _LP64 - array->append(new ConstantIntValue(0)); + array->append(new ConstantIntValue((jint)0)); array->append(new ConstantLongValue(d)); #else // Repack the long as two jints. diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/parse3.cpp --- a/src/hotspot/share/opto/parse3.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/parse3.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -412,11 +412,11 @@ // The original expression was of this form: new T[length0][length1]... // It is often the case that the lengths are small (except the last). // If that happens, use the fast 1-d creator a constant number of times. - const jint expand_limit = MIN2((jint)MultiArrayExpandLimit, 100); - jint expand_count = 1; // count of allocations in the expansion - jint expand_fanout = 1; // running total fanout + const int expand_limit = MIN2((int)MultiArrayExpandLimit, 100); + int expand_count = 1; // count of allocations in the expansion + int expand_fanout = 1; // running total fanout for (j = 0; j < ndimensions-1; j++) { - jint dim_con = find_int_con(length[j], -1); + int dim_con = find_int_con(length[j], -1); expand_fanout *= dim_con; expand_count += expand_fanout; // count the level-J sub-arrays if (dim_con <= 0 diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/phaseX.cpp --- a/src/hotspot/share/opto/phaseX.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/phaseX.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -723,7 +723,7 @@ //------------------------------intcon----------------------------------------- // Fast integer constant. Same as "transform(new ConINode(TypeInt::make(i)))" -ConINode* PhaseTransform::intcon(int i) { +ConINode* PhaseTransform::intcon(jint i) { // Small integer? Check cache! Check that cached node is not dead if (i >= _icon_min && i <= _icon_max) { ConINode* icon = _icons[i-_icon_min]; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/split_if.cpp --- a/src/hotspot/share/opto/split_if.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/split_if.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -116,9 +116,23 @@ assert( bol->is_Bool(), "" ); if (bol->outcnt() == 1) { Node* use = bol->unique_out(); - Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use); - if (use_c == blk1 || use_c == blk2) { - continue; + if (use->Opcode() == Op_Opaque4) { + if (use->outcnt() == 1) { + Node* iff = use->unique_out(); + assert(iff->is_If(), "unexpected node type"); + Node *use_c = iff->in(0); + if (use_c == blk1 || use_c == blk2) { + continue; + } + } + } else { + // We might see an Opaque1 from a loop limit check here + assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type"); + Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use); + if (use_c == blk1 || use_c == blk2) { + assert(use->is_CMove(), "unexpected node type"); + continue; + } } } if (get_ctrl(bol) == blk1 || get_ctrl(bol) == blk2) { @@ -129,17 +143,40 @@ bol->dump(); } #endif - for (DUIterator_Last jmin, j = bol->last_outs(jmin); j >= jmin; --j) { - // Uses are either IfNodes or CMoves - Node* iff = bol->last_out(j); - assert( iff->in(1) == bol, "" ); - // Get control block of either the CMove or the If input - Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff); - Node *x = bol->clone(); - register_new_node(x, iff_ctrl); - _igvn.replace_input_of(iff, 1, x); + for (DUIterator j = bol->outs(); bol->has_out(j); j++) { + Node* u = bol->out(j); + // Uses are either IfNodes, CMoves or Opaque4 + if (u->Opcode() == Op_Opaque4) { + assert(u->in(1) == bol, "bad input"); + for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) { + Node* iff = u->last_out(k); + assert(iff->is_If() || iff->is_CMove(), "unexpected node type"); + assert( iff->in(1) == u, "" ); + // Get control block of either the CMove or the If input + Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff); + Node *x1 = bol->clone(); + Node *x2 = u->clone(); + register_new_node(x1, iff_ctrl); + register_new_node(x2, iff_ctrl); + _igvn.replace_input_of(x2, 1, x1); + _igvn.replace_input_of(iff, 1, x2); + } + _igvn.remove_dead_node(u); + --j; + } else { + // We might see an Opaque1 from a loop limit check here + assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type"); + assert(u->in(1) == bol, ""); + // Get control block of either the CMove or the If input + Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u); + assert(u_ctrl != blk1 && u_ctrl != blk2, "won't converge"); + Node *x = bol->clone(); + register_new_node(x, u_ctrl); + _igvn.replace_input_of(u, 1, x); + --j; + } } - _igvn.remove_dead_node( bol ); + _igvn.remove_dead_node(bol); --i; } } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/superword.cpp --- a/src/hotspot/share/opto/superword.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/superword.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2168,10 +2168,12 @@ CountedLoopNode *cl = lpt()->_head->as_CountedLoop(); Compile* C = _phase->C; if (_packset.length() == 0) { - // Instigate more unrolling for optimization when vectorization fails. - C->set_major_progress(); - cl->set_notpassed_slp(); - cl->mark_do_unroll_only(); + if (cl->is_main_loop()) { + // Instigate more unrolling for optimization when vectorization fails. + C->set_major_progress(); + cl->set_notpassed_slp(); + cl->mark_do_unroll_only(); + } return; } @@ -2417,6 +2419,9 @@ }//for (int i = 0; i < _block.length(); i++) C->set_max_vector_size(max_vlen_in_bytes); + if (max_vlen_in_bytes > 0) { + cl->mark_loop_vectorized(); + } if (SuperWordLoopUnrollAnalysis) { if (cl->has_passed_slp()) { @@ -2439,7 +2444,6 @@ } if (do_reserve_copy()) { - cl->mark_loop_vectorized(); if (can_process_post_loop) { // Now create the difference of trip and limit and use it as our mask index. // Note: We limited the unroll of the vectorized loop so that diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/opto/type.cpp --- a/src/hotspot/share/opto/type.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/opto/type.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1503,7 +1503,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeInt::hash(void) const { - return java_add(java_add(_lo, _hi), java_add(_widen, (int)Type::Int)); + return java_add(java_add(_lo, _hi), java_add((jint)_widen, (jint)Type::Int)); } //------------------------------is_finite-------------------------------------- @@ -2505,7 +2505,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypePtr::hash(void) const { - return java_add(java_add(_ptr, _offset), java_add( hash_speculative(), _inline_depth)); + return java_add(java_add((jint)_ptr, (jint)_offset), java_add((jint)hash_speculative(), (jint)_inline_depth)); ; } @@ -3338,8 +3338,8 @@ // Type-specific hashing function. int TypeOopPtr::hash(void) const { return - java_add(java_add(const_oop() ? const_oop()->hash() : 0, _klass_is_exact), - java_add(_instance_id, TypePtr::hash())); + java_add(java_add((jint)(const_oop() ? const_oop()->hash() : 0), (jint)_klass_is_exact), + java_add((jint)_instance_id, (jint)TypePtr::hash())); } //------------------------------dump2------------------------------------------ @@ -3946,7 +3946,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeInstPtr::hash(void) const { - int hash = java_add(klass()->hash(), TypeOopPtr::hash()); + int hash = java_add((jint)klass()->hash(), (jint)TypeOopPtr::hash()); return hash; } @@ -4871,7 +4871,7 @@ //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeKlassPtr::hash(void) const { - return java_add(klass()->hash(), TypePtr::hash()); + return java_add((jint)klass()->hash(), (jint)TypePtr::hash()); } //------------------------------singleton-------------------------------------- diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/precompiled/precompiled.hpp --- a/src/hotspot/share/precompiled/precompiled.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/precompiled/precompiled.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -27,6 +27,7 @@ #ifndef DONT_USE_PRECOMPILED_HEADER # include "jni.h" +# include "jvm.h" # include "asm/assembler.hpp" # include "asm/assembler.inline.hpp" # include "asm/codeBuffer.hpp" @@ -160,7 +161,6 @@ # include "oops/symbol.hpp" # include "oops/typeArrayKlass.hpp" # include "oops/typeArrayOop.hpp" -# include "prims/jvm.h" # include "prims/jvmtiExport.hpp" # include "prims/methodHandles.hpp" # include "runtime/arguments.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jni.cpp --- a/src/hotspot/share/prims/jni.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/jni.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "jni.h" +#include "jvm.h" #include "ci/ciReplay.hpp" #include "classfile/altHashing.hpp" #include "classfile/classFileStream.hpp" @@ -55,7 +56,6 @@ #include "prims/jniCheck.hpp" #include "prims/jniExport.hpp" #include "prims/jniFastGetField.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" @@ -263,7 +263,7 @@ #ifdef ASSERT Histogram* JNIHistogram; - static volatile jint JNIHistogram_lock = 0; + static volatile int JNIHistogram_lock = 0; class JNIHistogramElement : public HistogramElement { public: @@ -3277,9 +3277,9 @@ // Initialization state for three routines below relating to // java.nio.DirectBuffers -static jint directBufferSupportInitializeStarted = 0; -static volatile jint directBufferSupportInitializeEnded = 0; -static volatile jint directBufferSupportInitializeFailed = 0; +static int directBufferSupportInitializeStarted = 0; +static volatile int directBufferSupportInitializeEnded = 0; +static volatile int directBufferSupportInitializeFailed = 0; static jclass bufferClass = NULL; static jclass directBufferClass = NULL; static jclass directByteBufferClass = NULL; @@ -3844,9 +3844,9 @@ extern const struct JNIInvokeInterface_ jni_InvokeInterface; // Global invocation API vars -volatile jint vm_created = 0; +volatile int vm_created = 0; // Indicate whether it is safe to recreate VM -volatile jint safe_to_recreate_vm = 1; +volatile int safe_to_recreate_vm = 1; struct JavaVM_ main_vm = {&jni_InvokeInterface}; @@ -3949,7 +3949,7 @@ // JVMCI is initialized on a CompilerThread if (BootstrapJVMCI) { JavaThread* THREAD = thread; - JVMCICompiler* compiler = JVMCICompiler::instance(CATCH); + JVMCICompiler* compiler = JVMCICompiler::instance(true, CATCH); compiler->bootstrap(THREAD); if (HAS_PENDING_EXCEPTION) { HandleMark hm; @@ -4045,7 +4045,7 @@ HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs); - if (vm_created) { + if (vm_created == 1) { if (numVMs != NULL) *numVMs = 1; if (bufLen > 0) *vm_buf = (JavaVM *)(&main_vm); } else { @@ -4065,7 +4065,7 @@ jint res = JNI_ERR; DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res); - if (!vm_created) { + if (vm_created == 0) { res = JNI_ERR; return res; } @@ -4086,7 +4086,7 @@ ThreadStateTransition::transition_from_native(thread, _thread_in_vm); if (Threads::destroy_vm()) { // Should not change thread state, VM is gone - vm_created = false; + vm_created = 0; res = JNI_OK; return res; } else { @@ -4226,7 +4226,7 @@ jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) { HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(vm, penv, _args); - if (!vm_created) { + if (vm_created == 0) { HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR); return JNI_ERR; } @@ -4285,7 +4285,7 @@ jint ret = JNI_ERR; DT_RETURN_MARK(GetEnv, jint, (const jint&)ret); - if (!vm_created) { + if (vm_created == 0) { *penv = NULL; ret = JNI_EDETACHED; return ret; @@ -4336,7 +4336,7 @@ jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) { HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(vm, penv, _args); - if (!vm_created) { + if (vm_created == 0) { HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN((uint32_t) JNI_ERR); return JNI_ERR; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jniCheck.cpp --- a/src/hotspot/share/prims/jniCheck.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/jniCheck.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "jni.h" +#include "jvm.h" #include "classfile/javaClasses.inline.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -32,7 +33,6 @@ #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "prims/jniCheck.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jni_md.h --- a/src/hotspot/share/prims/jni_md.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 1997, 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. - */ - -#include "utilities/macros.hpp" - -/* Switch to the correct jni_md.h file without reliance on -I options. */ -#include CPU_HEADER_H(jni) - -/* - The local copies of JNI header files may be refreshed - from a JDK distribution by means of these commands: - - cp ${JDK_DIST}/solaris/include/solaris/jni_md.h ./jni_sparc.h - cp ${JDK_DIST}/win32/include/win32/jni_md.h ./jni_i486.h - cp ${JDK_DIST}/win32/include/jni.h ./jni.h - -*/ diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jvm.cpp --- a/src/hotspot/share/prims/jvm.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/jvm.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" @@ -46,7 +47,6 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" @@ -215,7 +215,7 @@ #ifdef ASSERT Histogram* JVMHistogram; - volatile jint JVMHistogram_lock = 0; + volatile int JVMHistogram_lock = 0; class JVMHistogramElement : public HistogramElement { public: @@ -3766,7 +3766,7 @@ // when we add a new capability in the jvm_version_info struct, we should also // consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat // counter defined in runtimeService.cpp. - info->is_attachable = AttachListener::is_attach_supported(); + info->is_attach_supported = AttachListener::is_attach_supported(); } JVM_END diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jvm.h --- a/src/hotspot/share/prims/jvm.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1373 +0,0 @@ -/* - * Copyright (c) 1997, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_PRIMS_JVM_H -#define SHARE_VM_PRIMS_JVM_H - -#include "jni.h" -#include "utilities/macros.hpp" - -#include OS_HEADER_H(jvm) - -#ifndef _JAVASOFT_JVM_H_ -#define _JAVASOFT_JVM_H_ - -// HotSpot integration note: -// -// This file and jvm.h used with the JDK are identical, -// except for the three includes removed below - -// #include -// #include "jni.h" -// #include "jvm_md.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This file contains additional functions exported from the VM. - * These functions are complementary to the standard JNI support. - * There are three parts to this file: - * - * First, this file contains the VM-related functions needed by native - * libraries in the standard Java API. For example, the java.lang.Object - * class needs VM-level functions that wait for and notify monitors. - * - * Second, this file contains the functions and constant definitions - * needed by the byte code verifier and class file format checker. - * These functions allow the verifier and format checker to be written - * in a VM-independent way. - * - * Third, this file contains various I/O and nerwork operations needed - * by the standard Java I/O and network APIs. - */ - -/* - * Bump the version number when either of the following happens: - * - * 1. There is a change in JVM_* functions. - * - * 2. There is a change in the contract between VM and Java classes. - * For example, if the VM relies on a new private field in Thread - * class. - */ - -#define JVM_INTERFACE_VERSION 5 - -JNIEXPORT jobjectArray JNICALL -JVM_GetMethodParameters(JNIEnv *env, jobject method); - -JNIEXPORT jint JNICALL -JVM_GetInterfaceVersion(void); - -/************************************************************************* - PART 1: Functions for Native Libraries - ************************************************************************/ -/* - * java.lang.Object - */ -JNIEXPORT jint JNICALL -JVM_IHashCode(JNIEnv *env, jobject obj); - -JNIEXPORT void JNICALL -JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms); - -JNIEXPORT void JNICALL -JVM_MonitorNotify(JNIEnv *env, jobject obj); - -JNIEXPORT void JNICALL -JVM_MonitorNotifyAll(JNIEnv *env, jobject obj); - -JNIEXPORT jobject JNICALL -JVM_Clone(JNIEnv *env, jobject obj); - -/* - * java.lang.String - */ -JNIEXPORT jstring JNICALL -JVM_InternString(JNIEnv *env, jstring str); - -/* - * java.lang.System - */ -JNIEXPORT jlong JNICALL -JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored); - -JNIEXPORT jlong JNICALL -JVM_NanoTime(JNIEnv *env, jclass ignored); - -JNIEXPORT jlong JNICALL -JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs); - -JNIEXPORT void JNICALL -JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, - jobject dst, jint dst_pos, jint length); - -JNIEXPORT jobject JNICALL -JVM_InitProperties(JNIEnv *env, jobject p); - -/* - * java.lang.Runtime - */ - -JNIEXPORT void JNICALL -JVM_Halt(jint code); - -JNIEXPORT void JNICALL -JVM_GC(void); - -/* Returns the number of real-time milliseconds that have elapsed since the - * least-recently-inspected heap object was last inspected by the garbage - * collector. - * - * For simple stop-the-world collectors this value is just the time - * since the most recent collection. For generational collectors it is the - * time since the oldest generation was most recently collected. Other - * collectors are free to return a pessimistic estimate of the elapsed time, or - * simply the time since the last full collection was performed. - * - * Note that in the presence of reference objects, a given object that is no - * longer strongly reachable may have to be inspected multiple times before it - * can be reclaimed. - */ -JNIEXPORT jlong JNICALL -JVM_MaxObjectInspectionAge(void); - -JNIEXPORT jlong JNICALL -JVM_TotalMemory(void); - -JNIEXPORT jlong JNICALL -JVM_FreeMemory(void); - -JNIEXPORT jlong JNICALL -JVM_MaxMemory(void); - -JNIEXPORT jint JNICALL -JVM_ActiveProcessorCount(void); - -JNIEXPORT void * JNICALL -JVM_LoadLibrary(const char *name); - -JNIEXPORT void JNICALL -JVM_UnloadLibrary(void * handle); - -JNIEXPORT void * JNICALL -JVM_FindLibraryEntry(void *handle, const char *name); - -JNIEXPORT jboolean JNICALL -JVM_IsSupportedJNIVersion(jint version); - -JNIEXPORT jobjectArray JNICALL -JVM_GetVmArguments(JNIEnv *env); - -/* - * java.lang.Throwable - */ -JNIEXPORT void JNICALL -JVM_FillInStackTrace(JNIEnv *env, jobject throwable); - -/* - * java.lang.StackTraceElement - */ -JNIEXPORT void JNICALL -JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable); - -JNIEXPORT void JNICALL -JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo); - -/* - * java.lang.StackWalker - */ -enum { - JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x02, - JVM_STACKWALK_GET_CALLER_CLASS = 0x04, - JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20, - JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100 -}; - -JNIEXPORT jobject JNICALL -JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode, - jint skip_frames, jint frame_count, jint start_index, - jobjectArray frames); - -JNIEXPORT jint JNICALL -JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor, - jint frame_count, jint start_index, - jobjectArray frames); - -/* - * java.lang.Thread - */ -JNIEXPORT void JNICALL -JVM_StartThread(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_StopThread(JNIEnv *env, jobject thread, jobject exception); - -JNIEXPORT jboolean JNICALL -JVM_IsThreadAlive(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_SuspendThread(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_ResumeThread(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio); - -JNIEXPORT void JNICALL -JVM_Yield(JNIEnv *env, jclass threadClass); - -JNIEXPORT void JNICALL -JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis); - -JNIEXPORT jobject JNICALL -JVM_CurrentThread(JNIEnv *env, jclass threadClass); - -JNIEXPORT jint JNICALL -JVM_CountStackFrames(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_Interrupt(JNIEnv *env, jobject thread); - -JNIEXPORT jboolean JNICALL -JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted); - -JNIEXPORT jboolean JNICALL -JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj); - -JNIEXPORT void JNICALL -JVM_DumpAllStacks(JNIEnv *env, jclass unused); - -JNIEXPORT jobjectArray JNICALL -JVM_GetAllThreads(JNIEnv *env, jclass dummy); - -JNIEXPORT void JNICALL -JVM_SetNativeThreadName(JNIEnv *env, jobject jthread, jstring name); - -/* getStackTrace() and getAllStackTraces() method */ -JNIEXPORT jobjectArray JNICALL -JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads); - -/* - * java.lang.SecurityManager - */ -JNIEXPORT jclass JNICALL -JVM_CurrentLoadedClass(JNIEnv *env); - -JNIEXPORT jobject JNICALL -JVM_CurrentClassLoader(JNIEnv *env); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassContext(JNIEnv *env); - -JNIEXPORT jint JNICALL -JVM_ClassDepth(JNIEnv *env, jstring name); - -JNIEXPORT jint JNICALL -JVM_ClassLoaderDepth(JNIEnv *env); - -/* - * java.lang.Package - */ -JNIEXPORT jstring JNICALL -JVM_GetSystemPackage(JNIEnv *env, jstring name); - -JNIEXPORT jobjectArray JNICALL -JVM_GetSystemPackages(JNIEnv *env); - -/* - * java.lang.ref.Reference - */ -JNIEXPORT jobject JNICALL -JVM_GetAndClearReferencePendingList(JNIEnv *env); - -JNIEXPORT jboolean JNICALL -JVM_HasReferencePendingList(JNIEnv *env); - -JNIEXPORT void JNICALL -JVM_WaitForReferencePendingList(JNIEnv *env); - -/* - * java.io.ObjectInputStream - */ -JNIEXPORT jobject JNICALL -JVM_LatestUserDefinedLoader(JNIEnv *env); - -/* - * java.lang.reflect.Array - */ -JNIEXPORT jint JNICALL -JVM_GetArrayLength(JNIEnv *env, jobject arr); - -JNIEXPORT jobject JNICALL -JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index); - -JNIEXPORT jvalue JNICALL -JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode); - -JNIEXPORT void JNICALL -JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val); - -JNIEXPORT void JNICALL -JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, - unsigned char vCode); - -JNIEXPORT jobject JNICALL -JVM_NewArray(JNIEnv *env, jclass eltClass, jint length); - -JNIEXPORT jobject JNICALL -JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim); - -/* - * java.lang.Class and java.lang.ClassLoader - */ - -#define JVM_CALLER_DEPTH -1 - -/* - * Returns the class in which the code invoking the native method - * belongs. - * - * Note that in JDK 1.1, native methods did not create a frame. - * In 1.2, they do. Therefore native methods like Class.forName - * can no longer look at the current frame for the caller class. - */ -JNIEXPORT jclass JNICALL -JVM_GetCallerClass(JNIEnv *env, int n); - -/* - * Find primitive classes - * utf: class name - */ -JNIEXPORT jclass JNICALL -JVM_FindPrimitiveClass(JNIEnv *env, const char *utf); - -/* - * Find a class from a boot class loader. Returns NULL if class not found. - */ -JNIEXPORT jclass JNICALL -JVM_FindClassFromBootLoader(JNIEnv *env, const char *name); - -/* - * Find a class from a given class loader. Throws ClassNotFoundException. - * name: name of class - * init: whether initialization is done - * loader: class loader to look up the class. This may not be the same as the caller's - * class loader. - * caller: initiating class. The initiating class may be null when a security - * manager is not installed. - */ -JNIEXPORT jclass JNICALL -JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init, - jobject loader, jclass caller); - -/* - * Find a class from a given class. - */ -JNIEXPORT jclass JNICALL -JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, - jclass from); - -/* Find a loaded class cached by the VM */ -JNIEXPORT jclass JNICALL -JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name); - -/* Define a class */ -JNIEXPORT jclass JNICALL -JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, - jsize len, jobject pd); - -/* Define a class with a source (added in JDK1.5) */ -JNIEXPORT jclass JNICALL -JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, - const jbyte *buf, jsize len, jobject pd, - const char *source); - -/* - * Module support funcions - */ - -/* - * Define a module with the specified packages and bind the module to the - * given class loader. - * module: module to define - * is_open: specifies if module is open (currently ignored) - * version: the module version - * location: the module location - * packages: list of packages in the module - * num_packages: number of packages in the module - */ -JNIEXPORT void JNICALL -JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version, - jstring location, const char* const* packages, jsize num_packages); - -/* - * Set the boot loader's unnamed module. - * module: boot loader's unnamed module - */ -JNIEXPORT void JNICALL -JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module); - -/* - * Do a qualified export of a package. - * from_module: module containing the package to export - * package: name of the package to export - * to_module: module to export the package to - */ -JNIEXPORT void JNICALL -JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module); - -/* - * Do an export of a package to all unnamed modules. - * from_module: module containing the package to export - * package: name of the package to export to all unnamed modules - */ -JNIEXPORT void JNICALL -JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package); - -/* - * Do an unqualified export of a package. - * from_module: module containing the package to export - * package: name of the package to export - */ -JNIEXPORT void JNICALL -JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package); - -/* - * Add a module to the list of modules that a given module can read. - * from_module: module requesting read access - * source_module: module that from_module wants to read - */ -JNIEXPORT void JNICALL -JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module); - -/* - * Reflection support functions - */ - -JNIEXPORT jstring JNICALL -JVM_GetClassName(JNIEnv *env, jclass cls); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassInterfaces(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsInterface(JNIEnv *env, jclass cls); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassSigners(JNIEnv *env, jclass cls); - -JNIEXPORT void JNICALL -JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers); - -JNIEXPORT jobject JNICALL -JVM_GetProtectionDomain(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsArrayClass(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsPrimitiveClass(JNIEnv *env, jclass cls); - -JNIEXPORT jint JNICALL -JVM_GetClassModifiers(JNIEnv *env, jclass cls); - -JNIEXPORT jobjectArray JNICALL -JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass); - -JNIEXPORT jclass JNICALL -JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass); - -JNIEXPORT jstring JNICALL -JVM_GetSimpleBinaryName(JNIEnv *env, jclass ofClass); - -/* Generics support (JDK 1.5) */ -JNIEXPORT jstring JNICALL -JVM_GetClassSignature(JNIEnv *env, jclass cls); - -/* Annotations support (JDK 1.5) */ -JNIEXPORT jbyteArray JNICALL -JVM_GetClassAnnotations(JNIEnv *env, jclass cls); - -/* Annotations support (JDK 1.6) */ - -/* Type use annotations support (JDK 1.8) */ - -JNIEXPORT jbyteArray JNICALL -JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); - -// field is a handle to a java.lang.reflect.Field object -JNIEXPORT jbyteArray JNICALL -JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field); - -// method is a handle to a java.lang.reflect.Method object -JNIEXPORT jbyteArray JNICALL -JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method); - -/* - * New (JDK 1.4) reflection implementation - */ - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly); - -/* Differs from JVM_GetClassModifiers in treatment of inner classes. - This returns the access flags for the class as specified in the - class file rather than searching the InnerClasses attribute (if - present) to find the source-level access flags. Only the values of - the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be - valid. */ -JNIEXPORT jint JNICALL -JVM_GetClassAccessFlags(JNIEnv *env, jclass cls); - -/* - * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5) - */ - -JNIEXPORT jobject JNICALL -JVM_GetClassConstantPool(JNIEnv *env, jclass cls); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize -(JNIEnv *env, jobject obj, jobject unused); - -JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetNameAndTypeRefInfoAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetNameAndTypeRefIndexAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetClassRefIndexAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jbyte JNICALL JVM_ConstantPoolGetTagAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -/* - * java.security.* - */ - -JNIEXPORT jobject JNICALL -JVM_DoPrivileged(JNIEnv *env, jclass cls, - jobject action, jobject context, jboolean wrapException); - -JNIEXPORT jobject JNICALL -JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls); - -JNIEXPORT jobject JNICALL -JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls); - -/* - * Signal support, used to implement the shutdown sequence. Every VM must - * support JVM_SIGINT and JVM_SIGTERM, raising the former for user interrupts - * (^C) and the latter for external termination (kill, system shutdown, etc.). - * Other platform-dependent signal values may also be supported. - */ - -JNIEXPORT void * JNICALL -JVM_RegisterSignal(jint sig, void *handler); - -JNIEXPORT jboolean JNICALL -JVM_RaiseSignal(jint sig); - -JNIEXPORT jint JNICALL -JVM_FindSignal(const char *name); - -/* - * Retrieve the assertion directives for the specified class. - */ -JNIEXPORT jboolean JNICALL -JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls); - -/* - * Retrieve the assertion directives from the VM. - */ -JNIEXPORT jobject JNICALL -JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused); - -/* - * java.util.concurrent.atomic.AtomicLong - */ -JNIEXPORT jboolean JNICALL -JVM_SupportsCX8(void); - -/************************************************************************* - PART 2: Support for the Verifier and Class File Format Checker - ************************************************************************/ -/* - * Return the class name in UTF format. The result is valid - * until JVM_ReleaseUTf is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetClassNameUTF(JNIEnv *env, jclass cb); - -/* - * Returns the constant pool types in the buffer provided by "types." - */ -JNIEXPORT void JNICALL -JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types); - -/* - * Returns the number of Constant Pool entries. - */ -JNIEXPORT jint JNICALL -JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb); - -/* - * Returns the number of *declared* fields or methods. - */ -JNIEXPORT jint JNICALL -JVM_GetClassFieldsCount(JNIEnv *env, jclass cb); - -JNIEXPORT jint JNICALL -JVM_GetClassMethodsCount(JNIEnv *env, jclass cb); - -/* - * Returns the CP indexes of exceptions raised by a given method. - * Places the result in the given buffer. - * - * The method is identified by method_index. - */ -JNIEXPORT void JNICALL -JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index, - unsigned short *exceptions); -/* - * Returns the number of exceptions raised by a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index); - -/* - * Returns the byte code sequence of a given method. - * Places the result in the given buffer. - * - * The method is identified by method_index. - */ -JNIEXPORT void JNICALL -JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index, - unsigned char *code); - -/* - * Returns the length of the byte code sequence of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index); - -/* - * A structure used to a capture exception table entry in a Java method. - */ -typedef struct { - jint start_pc; - jint end_pc; - jint handler_pc; - jint catchType; -} JVM_ExceptionTableEntryType; - -/* - * Returns the exception table entry at entry_index of a given method. - * Places the result in the given buffer. - * - * The method is identified by method_index. - */ -JNIEXPORT void JNICALL -JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index, - jint entry_index, - JVM_ExceptionTableEntryType *entry); - -/* - * Returns the length of the exception table of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index); - -/* - * Returns the modifiers of a given field. - * The field is identified by field_index. - */ -JNIEXPORT jint JNICALL -JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index); - -/* - * Returns the modifiers of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index); - -/* - * Returns the number of local variables of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index); - -/* - * Returns the number of arguments (including this pointer) of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index); - -/* - * Returns the maximum amount of stack (in words) used by a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index); - -/* - * Is a given method a constructor. - * The method is identified by method_index. - */ -JNIEXPORT jboolean JNICALL -JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index); - -/* - * Is the given method generated by the VM. - * The method is identified by method_index. - */ -JNIEXPORT jboolean JNICALL -JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index); - -/* - * Returns the name of a given method in UTF format. - * The result remains valid until JVM_ReleaseUTF is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the signature of a given method in UTF format. - * The result remains valid until JVM_ReleaseUTF is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the name of the field refered to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the name of the method refered to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the signature of the method refered to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the signature of the field refered to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the class name refered to at a given constant pool index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the class name refered to at a given constant pool index. - * - * The constant pool entry must refer to a CONSTANT_Fieldref. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the class name refered to at a given constant pool index. - * - * The constant pool entry must refer to CONSTANT_Methodref or - * CONSTANT_InterfaceMethodref. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the modifiers of a field in calledClass. The field is - * referred to in class cb at constant pool entry index. - * - * The caller must treat the string as a constant and not modify it - * in any way. - * - * Returns -1 if the field does not exist in calledClass. - */ -JNIEXPORT jint JNICALL -JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass); - -/* - * Returns the modifiers of a method in calledClass. The method is - * referred to in class cb at constant pool entry index. - * - * Returns -1 if the method does not exist in calledClass. - */ -JNIEXPORT jint JNICALL -JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass); - -/* - * Releases the UTF string obtained from the VM. - */ -JNIEXPORT void JNICALL -JVM_ReleaseUTF(const char *utf); - -/* - * Compare if two classes are in the same package. - */ -JNIEXPORT jboolean JNICALL -JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2); - -/* Constants in class files */ - -#define JVM_ACC_PUBLIC 0x0001 /* visible to everyone */ -#define JVM_ACC_PRIVATE 0x0002 /* visible only to the defining class */ -#define JVM_ACC_PROTECTED 0x0004 /* visible to subclasses */ -#define JVM_ACC_STATIC 0x0008 /* instance variable is static */ -#define JVM_ACC_FINAL 0x0010 /* no further subclassing, overriding */ -#define JVM_ACC_SYNCHRONIZED 0x0020 /* wrap method call in monitor lock */ -#define JVM_ACC_SUPER 0x0020 /* funky handling of invokespecial */ -#define JVM_ACC_VOLATILE 0x0040 /* can not cache in registers */ -#define JVM_ACC_BRIDGE 0x0040 /* bridge method generated by compiler */ -#define JVM_ACC_TRANSIENT 0x0080 /* not persistent */ -#define JVM_ACC_VARARGS 0x0080 /* method declared with variable number of args */ -#define JVM_ACC_NATIVE 0x0100 /* implemented in C */ -#define JVM_ACC_INTERFACE 0x0200 /* class is an interface */ -#define JVM_ACC_ABSTRACT 0x0400 /* no definition provided */ -#define JVM_ACC_STRICT 0x0800 /* strict floating point */ -#define JVM_ACC_SYNTHETIC 0x1000 /* compiler-generated class, method or field */ -#define JVM_ACC_ANNOTATION 0x2000 /* annotation type */ -#define JVM_ACC_ENUM 0x4000 /* field is declared as element of enum */ -#define JVM_ACC_MODULE 0x8000 /* module-info class file */ - -#define JVM_ACC_PUBLIC_BIT 0 -#define JVM_ACC_PRIVATE_BIT 1 -#define JVM_ACC_PROTECTED_BIT 2 -#define JVM_ACC_STATIC_BIT 3 -#define JVM_ACC_FINAL_BIT 4 -#define JVM_ACC_SYNCHRONIZED_BIT 5 -#define JVM_ACC_SUPER_BIT 5 -#define JVM_ACC_VOLATILE_BIT 6 -#define JVM_ACC_BRIDGE_BIT 6 -#define JVM_ACC_TRANSIENT_BIT 7 -#define JVM_ACC_VARARGS_BIT 7 -#define JVM_ACC_NATIVE_BIT 8 -#define JVM_ACC_INTERFACE_BIT 9 -#define JVM_ACC_ABSTRACT_BIT 10 -#define JVM_ACC_STRICT_BIT 11 -#define JVM_ACC_SYNTHETIC_BIT 12 -#define JVM_ACC_ANNOTATION_BIT 13 -#define JVM_ACC_ENUM_BIT 14 - -// NOTE: replicated in SA in vm/agent/sun/jvm/hotspot/utilities/ConstantTag.java -enum { - JVM_CONSTANT_Utf8 = 1, - JVM_CONSTANT_Unicode, /* unused */ - JVM_CONSTANT_Integer, - JVM_CONSTANT_Float, - JVM_CONSTANT_Long, - JVM_CONSTANT_Double, - JVM_CONSTANT_Class, - JVM_CONSTANT_String, - JVM_CONSTANT_Fieldref, - JVM_CONSTANT_Methodref, - JVM_CONSTANT_InterfaceMethodref, - JVM_CONSTANT_NameAndType, - JVM_CONSTANT_MethodHandle = 15, // JSR 292 - JVM_CONSTANT_MethodType = 16, // JSR 292 - //JVM_CONSTANT_(unused) = 17, // JSR 292 early drafts only - JVM_CONSTANT_InvokeDynamic = 18, // JSR 292 - JVM_CONSTANT_ExternalMax = 18 // Last tag found in classfiles -}; - -/* JVM_CONSTANT_MethodHandle subtypes */ -enum { - JVM_REF_getField = 1, - JVM_REF_getStatic = 2, - JVM_REF_putField = 3, - JVM_REF_putStatic = 4, - JVM_REF_invokeVirtual = 5, - JVM_REF_invokeStatic = 6, - JVM_REF_invokeSpecial = 7, - JVM_REF_newInvokeSpecial = 8, - JVM_REF_invokeInterface = 9 -}; - -/* Used in the newarray instruction. */ - -#define JVM_T_BOOLEAN 4 -#define JVM_T_CHAR 5 -#define JVM_T_FLOAT 6 -#define JVM_T_DOUBLE 7 -#define JVM_T_BYTE 8 -#define JVM_T_SHORT 9 -#define JVM_T_INT 10 -#define JVM_T_LONG 11 - -/* JVM method signatures */ - -#define JVM_SIGNATURE_ARRAY '[' -#define JVM_SIGNATURE_BYTE 'B' -#define JVM_SIGNATURE_CHAR 'C' -#define JVM_SIGNATURE_CLASS 'L' -#define JVM_SIGNATURE_ENDCLASS ';' -#define JVM_SIGNATURE_ENUM 'E' -#define JVM_SIGNATURE_FLOAT 'F' -#define JVM_SIGNATURE_DOUBLE 'D' -#define JVM_SIGNATURE_FUNC '(' -#define JVM_SIGNATURE_ENDFUNC ')' -#define JVM_SIGNATURE_INT 'I' -#define JVM_SIGNATURE_LONG 'J' -#define JVM_SIGNATURE_SHORT 'S' -#define JVM_SIGNATURE_VOID 'V' -#define JVM_SIGNATURE_BOOLEAN 'Z' - -/* - * A function defined by the byte-code verifier and called by the VM. - * This is not a function implemented in the VM. - * - * Returns JNI_FALSE if verification fails. A detailed error message - * will be places in msg_buf, whose length is specified by buf_len. - */ -typedef jboolean (*verifier_fn_t)(JNIEnv *env, - jclass cb, - char * msg_buf, - jint buf_len); - - -/* - * Support for a VM-independent class format checker. - */ -typedef struct { - unsigned long code; /* byte code */ - unsigned long excs; /* exceptions */ - unsigned long etab; /* catch table */ - unsigned long lnum; /* line number */ - unsigned long lvar; /* local vars */ -} method_size_info; - -typedef struct { - unsigned int constants; /* constant pool */ - unsigned int fields; - unsigned int methods; - unsigned int interfaces; - unsigned int fields2; /* number of static 2-word fields */ - unsigned int innerclasses; /* # of records in InnerClasses attr */ - - method_size_info clinit; /* memory used in clinit */ - method_size_info main; /* used everywhere else */ -} class_size_info; - -/* - * Functions defined in libjava.so to perform string conversions. - * - */ - -typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str); - -typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b); - -/* This is the function defined in libjava.so that performs class - * format checks. This functions fills in size information about - * the class file and returns: - * - * 0: good - * -1: out of memory - * -2: bad format - * -3: unsupported version - * -4: bad class name - */ - -typedef jint (*check_format_fn_t)(char *class_name, - unsigned char *data, - unsigned int data_size, - class_size_info *class_size, - char *message_buffer, - jint buffer_length, - jboolean measure_only, - jboolean check_relaxed); - -#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \ - JVM_ACC_FINAL | \ - JVM_ACC_SUPER | \ - JVM_ACC_INTERFACE | \ - JVM_ACC_ABSTRACT | \ - JVM_ACC_ANNOTATION | \ - JVM_ACC_ENUM | \ - JVM_ACC_SYNTHETIC) - -#define JVM_RECOGNIZED_FIELD_MODIFIERS (JVM_ACC_PUBLIC | \ - JVM_ACC_PRIVATE | \ - JVM_ACC_PROTECTED | \ - JVM_ACC_STATIC | \ - JVM_ACC_FINAL | \ - JVM_ACC_VOLATILE | \ - JVM_ACC_TRANSIENT | \ - JVM_ACC_ENUM | \ - JVM_ACC_SYNTHETIC) - -#define JVM_RECOGNIZED_METHOD_MODIFIERS (JVM_ACC_PUBLIC | \ - JVM_ACC_PRIVATE | \ - JVM_ACC_PROTECTED | \ - JVM_ACC_STATIC | \ - JVM_ACC_FINAL | \ - JVM_ACC_SYNCHRONIZED | \ - JVM_ACC_BRIDGE | \ - JVM_ACC_VARARGS | \ - JVM_ACC_NATIVE | \ - JVM_ACC_ABSTRACT | \ - JVM_ACC_STRICT | \ - JVM_ACC_SYNTHETIC) - -/* - * This is the function defined in libjava.so to perform path - * canonicalization. VM call this function before opening jar files - * to load system classes. - * - */ - -typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len); - -/************************************************************************* - PART 3: I/O and Network Support - ************************************************************************/ - -/* - * Convert a pathname into native format. This function does syntactic - * cleanup, such as removing redundant separator characters. It modifies - * the given pathname string in place. - */ -JNIEXPORT char * JNICALL -JVM_NativePath(char *); - -/* - * The standard printing functions supported by the Java VM. (Should they - * be renamed to JVM_* in the future? - */ - -/* jio_snprintf() and jio_vsnprintf() behave like snprintf(3) and vsnprintf(3), - * respectively, with the following differences: - * - The string written to str is always zero-terminated, also in case of - * truncation (count is too small to hold the result string), unless count - * is 0. In case of truncation count-1 characters are written and '\0' - * appendend. - * - If count is too small to hold the whole string, -1 is returned across - * all platforms. */ -JNIEXPORT int -jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args); - -JNIEXPORT int -jio_snprintf(char *str, size_t count, const char *fmt, ...); - -JNIEXPORT int -jio_fprintf(FILE *, const char *fmt, ...); - -JNIEXPORT int -jio_vfprintf(FILE *, const char *fmt, va_list args); - - -JNIEXPORT void * JNICALL -JVM_RawMonitorCreate(void); - -JNIEXPORT void JNICALL -JVM_RawMonitorDestroy(void *mon); - -JNIEXPORT jint JNICALL -JVM_RawMonitorEnter(void *mon); - -JNIEXPORT void JNICALL -JVM_RawMonitorExit(void *mon); - -/* - * java.lang.reflect.Method - */ -JNIEXPORT jobject JNICALL -JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0); - -/* - * java.lang.reflect.Constructor - */ -JNIEXPORT jobject JNICALL -JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0); - -/* - * java.lang.management support - */ -JNIEXPORT void* JNICALL -JVM_GetManagement(jint version); - -/* - * com.sun.tools.attach.VirtualMachine support - * - * Initialize the agent properties with the properties maintained in the VM. - */ -JNIEXPORT jobject JNICALL -JVM_InitAgentProperties(JNIEnv *env, jobject agent_props); - -JNIEXPORT jstring JNICALL -JVM_GetTemporaryDirectory(JNIEnv *env); - -/* Generics reflection support. - * - * Returns information about the given class's EnclosingMethod - * attribute, if present, or null if the class had no enclosing - * method. - * - * If non-null, the returned array contains three elements. Element 0 - * is the java.lang.Class of which the enclosing method is a member, - * and elements 1 and 2 are the java.lang.Strings for the enclosing - * method's name and descriptor, respectively. - */ -JNIEXPORT jobjectArray JNICALL -JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass); - -/* ========================================================================= - * The following defines a private JVM interface that the JDK can query - * for the JVM version and capabilities. sun.misc.Version defines - * the methods for getting the VM version and its capabilities. - * - * When a new bit is added, the following should be updated to provide - * access to the new capability: - * HS: JVM_GetVersionInfo and Abstract_VM_Version class - * SDK: Version class - * - * Similary, a private JDK interface JDK_GetVersionInfo0 is defined for - * JVM to query for the JDK version and capabilities. - * - * When a new bit is added, the following should be updated to provide - * access to the new capability: - * HS: JDK_Version class - * SDK: JDK_GetVersionInfo0 - * - * ========================================================================== - */ -typedef struct { - unsigned int jvm_version; /* Encoded $VNUM as defined by JEP-223 */ - unsigned int patch_version : 8; /* JEP-223 patch version */ - unsigned int reserved3 : 8; - unsigned int reserved1 : 16; - unsigned int reserved2; - - /* The following bits represents JVM supports that JDK has dependency on. - * JDK can use these bits to determine which JVM version - * and support it has to maintain runtime compatibility. - * - * When a new bit is added in a minor or update release, make sure - * the new bit is also added in the main/baseline. - */ - unsigned int is_attachable : 1; - unsigned int : 31; - unsigned int : 32; - unsigned int : 32; -} jvm_version_info; - -#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24) -#define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16) -#define JVM_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8) -#define JVM_VERSION_BUILD(version) ((version & 0x000000FF)) - -JNIEXPORT void JNICALL -JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size); - -typedef struct { - unsigned int jdk_version; /* Encoded $VNUM as defined by JEP-223 */ - unsigned int patch_version : 8; /* JEP-223 patch version */ - unsigned int reserved3 : 8; - unsigned int reserved1 : 16; - unsigned int reserved2; - - /* The following bits represents new JDK supports that VM has dependency on. - * VM implementation can use these bits to determine which JDK version - * and support it has to maintain runtime compatibility. - * - * When a new bit is added in a minor or update release, make sure - * the new bit is also added in the main/baseline. - */ - unsigned int thread_park_blocker : 1; - unsigned int post_vm_init_hook_enabled : 1; - unsigned int pending_list_uses_discovered_field : 1; - unsigned int : 29; - unsigned int : 32; - unsigned int : 32; -} jdk_version_info; - -#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24) -#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16) -#define JDK_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8) -#define JDK_VERSION_BUILD(version) ((version & 0x000000FF)) - -/* - * This is the function JDK_GetVersionInfo0 defined in libjava.so - * that is dynamically looked up by JVM. - */ -typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size); - -/* - * This structure is used by the launcher to get the default thread - * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a - * version of 1.1. As it is not supported otherwise, it has been removed - * from jni.h - */ -typedef struct JDK1_1InitArgs { - jint version; - - char **properties; - jint checkSource; - jint nativeStackSize; - jint javaStackSize; - jint minHeapSize; - jint maxHeapSize; - jint verifyMode; - char *classpath; - - jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args); - void (JNICALL *exit)(jint code); - void (JNICALL *abort)(void); - - jint enableClassGC; - jint enableVerboseGC; - jint disableAsyncGC; - jint verbose; - jboolean debugging; - jint debugPort; -} JDK1_1InitArgs; - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* !_JAVASOFT_JVM_H_ */ - -#endif // SHARE_VM_PRIMS_JVM_H diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jvmtiEnvBase.cpp --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -741,7 +741,7 @@ // Save JNI local handles for any objects that this frame owns. jvmtiError JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread, - javaVFrame *jvf, GrowableArray* owned_monitors_list, int stack_depth) { + javaVFrame *jvf, GrowableArray* owned_monitors_list, jint stack_depth) { jvmtiError err = JVMTI_ERROR_NONE; ResourceMark rm; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jvmtiImpl.cpp --- a/src/hotspot/share/prims/jvmtiImpl.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/jvmtiImpl.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -523,7 +523,7 @@ // // Constructor for non-object getter -VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type) +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type) : _thread(thread) , _calling_thread(NULL) , _depth(depth) @@ -536,7 +536,7 @@ } // Constructor for object or non-object setter -VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value) +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value) : _thread(thread) , _calling_thread(NULL) , _depth(depth) diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/jvmtiTagMap.cpp --- a/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -2006,7 +2006,7 @@ jlong thread_tag, jint depth, jmethodID method, - jint slot, + int slot, oop obj) { assert(ServiceUtil::visible_oop(obj), "checking"); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/methodHandles.hpp --- a/src/hotspot/share/prims/methodHandles.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/methodHandles.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -27,7 +27,6 @@ #include "classfile/javaClasses.hpp" #include "classfile/vmSymbols.hpp" -#include "prims/jvm.h" #include "runtime/frame.inline.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/nativeLookup.cpp --- a/src/hotspot/share/prims/nativeLookup.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/nativeLookup.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -293,10 +293,12 @@ char* critical_name = critical_jni_name(method); // Compute argument size - int args_size = 1 // JNIEnv - + (method->is_static() ? 1 : 0) // class for static methods - + method->size_of_parameters(); // actual parameters - + int args_size = method->size_of_parameters(); + for (SignatureStream ss(signature); !ss.at_return_type(); ss.next()) { + if (ss.is_array()) { + args_size += T_INT_size; // array length parameter + } + } // 1) Try JNI short style entry = lookup_critical_style(method, critical_name, "", args_size, true); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/perf.cpp --- a/src/hotspot/share/prims/perf.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/perf.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,11 +24,11 @@ #include "precompiled.hpp" #include "jni.h" +#include "jvm.h" #include "classfile/vmSymbols.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/interfaceSupport.hpp" #include "runtime/perfData.hpp" #include "runtime/perfMemory.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/stackwalk.cpp --- a/src/hotspot/share/prims/stackwalk.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/stackwalk.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -272,9 +272,8 @@ return array_h; } -// Fill StackFrameInfo with declaringClass and bci and initialize memberName +// Fill StackFrameInfo with bci and initialize memberName void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) { - java_lang_StackFrameInfo::set_declaringClass(stackFrame(), method->method_holder()->java_mirror()); java_lang_StackFrameInfo::set_method_and_bci(stackFrame, method, bci(), THREAD); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/unsafe.cpp --- a/src/hotspot/share/prims/unsafe.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/unsafe.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "jni.h" +#include "jvm.h" #include "classfile/classFileStream.hpp" #include "classfile/vmSymbols.hpp" #include "memory/allocation.inline.hpp" @@ -31,7 +32,6 @@ #include "oops/fieldStreams.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/unsafe.hpp" #include "runtime/atomic.hpp" #include "runtime/globals.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/prims/whitebox.cpp --- a/src/hotspot/share/prims/whitebox.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/prims/whitebox.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1715,6 +1715,10 @@ } WB_END +WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env)) + return MetaspaceShared::open_archive_heap_region_mapped(); +WB_END + WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env)) #if INCLUDE_CDS return true; @@ -2031,6 +2035,7 @@ {CC"isSharedClass", CC"(Ljava/lang/Class;)Z", (void*)&WB_IsSharedClass }, {CC"areSharedStringsIgnored", CC"()Z", (void*)&WB_AreSharedStringsIgnored }, {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences}, + {CC"areOpenArchiveHeapObjectsMapped", CC"()Z", (void*)&WB_AreOpenArchiveHeapObjectsMapped}, {CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild }, {CC"clearInlineCaches0", CC"(Z)V", (void*)&WB_ClearInlineCaches }, {CC"addCompilerDirective", CC"(Ljava/lang/String;)I", diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/arguments.cpp --- a/src/hotspot/share/runtime/arguments.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/arguments.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/moduleEntry.hpp" @@ -39,7 +40,6 @@ #include "memory/allocation.inline.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/arguments_ext.hpp" @@ -382,6 +382,8 @@ { "MaxRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() }, { "MinRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() }, { "InitialRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() }, + { "UseMembar", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) }, + { "IgnoreUnverifiableClassesDuringDump", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() }, // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in: { "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() }, @@ -395,6 +397,10 @@ { "MinSleepInterval", JDK_Version::jdk(9), JDK_Version::jdk(10), JDK_Version::jdk(11) }, { "PermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() }, { "MaxPermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() }, + { "SharedReadWriteSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() }, + { "SharedReadOnlySize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() }, + { "SharedMiscDataSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() }, + { "SharedMiscCodeSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() }, #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS { "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() }, @@ -1859,7 +1865,7 @@ #endif select_gc(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // Shared spaces work fine with other GCs but causes bytecode rewriting // to be disabled, which hurts interpreter performance and decreases // server performance. When -server is specified, keep the default off @@ -2088,9 +2094,10 @@ // respecting the maximum and minimum sizes of the heap. if (FLAG_IS_DEFAULT(MaxHeapSize)) { julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100); - if (phys_mem <= (julong)((MaxHeapSize * MinRAMPercentage) / 100)) { + const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100); + if (reasonable_min < MaxHeapSize) { // Small physical memory, so use a minimum fraction of it for the heap - reasonable_max = (julong)((phys_mem * MinRAMPercentage) / 100); + reasonable_max = reasonable_min; } else { // Not-small physical memory, so require a heap at least // as large as MaxHeapSize diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/biasedLocking.cpp --- a/src/hotspot/share/runtime/biasedLocking.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/biasedLocking.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -145,7 +145,9 @@ return info; } -static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) { +// After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL, +// AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization). +static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) { markOop mark = obj->mark(); if (!mark->has_bias_pattern()) { if (log_is_enabled(Info, biasedlocking)) { @@ -298,6 +300,11 @@ } } + // If requested, return information on which thread held the bias + if (biased_locker != NULL) { + *biased_locker = biased_thread; + } + return BiasedLocking::BIAS_REVOKED; } @@ -418,7 +425,7 @@ // At this point we're done. All we have to do is potentially // adjust the header of the given object to revoke its bias. - revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread); + revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL); } else { if (log_is_enabled(Info, biasedlocking)) { ResourceMark rm; @@ -440,14 +447,14 @@ oop owner = mon_info->owner(); markOop mark = owner->mark(); if ((owner->klass() == k_o) && mark->has_bias_pattern()) { - revoke_bias(owner, false, true, requesting_thread); + revoke_bias(owner, false, true, requesting_thread, NULL); } } } // Must force the bias of the passed object to be forcibly revoked // as well to ensure guarantees to callers - revoke_bias(o, false, true, requesting_thread); + revoke_bias(o, false, true, requesting_thread, NULL); } log_info(biasedlocking)("* Ending bulk revocation"); @@ -486,19 +493,22 @@ GrowableArray* _objs; JavaThread* _requesting_thread; BiasedLocking::Condition _status_code; + traceid _biased_locker_id; public: VM_RevokeBias(Handle* obj, JavaThread* requesting_thread) : _obj(obj) , _objs(NULL) , _requesting_thread(requesting_thread) - , _status_code(BiasedLocking::NOT_BIASED) {} + , _status_code(BiasedLocking::NOT_BIASED) + , _biased_locker_id(0) {} VM_RevokeBias(GrowableArray* objs, JavaThread* requesting_thread) : _obj(NULL) , _objs(objs) , _requesting_thread(requesting_thread) - , _status_code(BiasedLocking::NOT_BIASED) {} + , _status_code(BiasedLocking::NOT_BIASED) + , _biased_locker_id(0) {} virtual VMOp_Type type() const { return VMOp_RevokeBias; } @@ -525,7 +535,11 @@ virtual void doit() { if (_obj != NULL) { log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:"); - _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread); + JavaThread* biased_locker = NULL; + _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker); + if (biased_locker != NULL) { + _biased_locker_id = THREAD_TRACE_ID(biased_locker); + } clean_up_cached_monitor_info(); return; } else { @@ -537,6 +551,10 @@ BiasedLocking::Condition status_code() const { return _status_code; } + + traceid biased_locker() const { + return _biased_locker_id; + } }; @@ -645,7 +663,7 @@ ResourceMark rm; log_info(biasedlocking)("Revoking bias by walking my own stack:"); EventBiasedLockSelfRevocation event; - BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD); + BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL); ((JavaThread*) THREAD)->set_cached_monitor_info(NULL); assert(cond == BIAS_REVOKED, "why not?"); if (event.should_commit()) { @@ -661,6 +679,7 @@ event.set_lockClass(k); // Subtract 1 to match the id of events committed inside the safepoint event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1); + event.set_previousOwner(revoke.biased_locker()); event.commit(); } return revoke.status_code(); @@ -700,7 +719,7 @@ oop obj = h_obj(); HeuristicsResult heuristics = update_heuristics(obj, false); if (heuristics == HR_SINGLE_REVOKE) { - revoke_bias(obj, false, false, NULL); + revoke_bias(obj, false, false, NULL, NULL); } else if ((heuristics == HR_BULK_REBIAS) || (heuristics == HR_BULK_REVOKE)) { bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); @@ -716,7 +735,7 @@ oop obj = (objs->at(i))(); HeuristicsResult heuristics = update_heuristics(obj, false); if (heuristics == HR_SINGLE_REVOKE) { - revoke_bias(obj, false, false, NULL); + revoke_bias(obj, false, false, NULL, NULL); } else if ((heuristics == HR_BULK_REBIAS) || (heuristics == HR_BULK_REVOKE)) { bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/commandLineFlagRangeList.cpp --- a/src/hotspot/share/runtime/commandLineFlagRangeList.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/commandLineFlagRangeList.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,10 +23,10 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "gc/shared/referenceProcessor.hpp" -#include "prims/jvm.h" #include "oops/markOop.hpp" #include "runtime/arguments.hpp" #include "runtime/commandLineFlagConstraintList.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/deoptimization.cpp --- a/src/hotspot/share/runtime/deoptimization.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/deoptimization.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "code/debugInfoRec.hpp" @@ -40,7 +41,6 @@ #include "oops/oop.inline.hpp" #include "oops/fieldStreams.hpp" #include "oops/verifyOopClosure.hpp" -#include "prims/jvm.h" #include "prims/jvmtiThreadState.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" @@ -192,7 +192,7 @@ bool realloc_failures = false; -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // Reallocate the non-escaping objects and restore their fields. Then // relock objects if synchronization on them was eliminated. #ifndef INCLUDE_JVMCI @@ -282,7 +282,7 @@ } } #endif // INCLUDE_JVMCI -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI ScopeDesc* trap_scope = chunk->at(0)->scope(); Handle exceptionObject; @@ -303,7 +303,7 @@ NoSafepointVerifier no_safepoint; vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI if (realloc_failures) { pop_frames_failed_reallocs(thread, array); } @@ -792,7 +792,7 @@ Deoptimization::DeoptAction Deoptimization::_unloaded_action = Deoptimization::Action_reinterpret; -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS) { Handle pending_exception(THREAD, thread->pending_exception()); const char* exception_file = thread->exception_file(); @@ -1151,7 +1151,7 @@ } } #endif -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk, bool realloc_failures) { Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, p2i(fr.pc()), p2i(fr.sp())); @@ -1211,7 +1211,7 @@ return array; } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) { // Reallocation of some scalar replaced objects failed. Record // that we need to pop all the interpreter frames for the @@ -1443,7 +1443,7 @@ return mdo; } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS) { // in case of an unresolved klass entry, load the class. if (constant_pool->tag_at(index).is_unresolved_klass()) { @@ -1674,19 +1674,9 @@ tty->print(" compiler=%s compile_id=%d", nm->compiler_name(), nm->compile_id()); #if INCLUDE_JVMCI if (nm->is_nmethod()) { - oop installedCode = nm->as_nmethod()->jvmci_installed_code(); - if (installedCode != NULL) { - oop installedCodeName = NULL; - if (installedCode->is_a(InstalledCode::klass())) { - installedCodeName = InstalledCode::name(installedCode); - } - if (installedCodeName != NULL) { - tty->print(" (JVMCI: installedCodeName=%s) ", java_lang_String::as_utf8_string(installedCodeName)); - } else { - tty->print(" (JVMCI: installed code has no name) "); - } - } else if (nm->is_compiled_by_jvmci()) { - tty->print(" (JVMCI: no installed code) "); + char* installed_code_name = nm->as_nmethod()->jvmci_installed_code_name(buf, sizeof(buf)); + if (installed_code_name != NULL) { + tty->print(" (JVMCI: installed code name=%s) ", installed_code_name); } } #endif @@ -2360,7 +2350,7 @@ if (xtty != NULL) xtty->tail("statistics"); } } -#else // COMPILER2 || INCLUDE_JVMCI +#else // COMPILER2_OR_JVMCI // Stubs for C1 only system. @@ -2396,4 +2386,4 @@ return buf; } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/deoptimization.hpp --- a/src/hotspot/share/runtime/deoptimization.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/deoptimization.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -151,7 +151,7 @@ // executing in a particular CodeBlob if UseBiasedLocking is enabled static void revoke_biases_of_monitors(CodeBlob* cb); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI JVMCI_ONLY(public:) // Support for restoring non-escaping objects @@ -162,7 +162,7 @@ static void relock_objects(GrowableArray* monitors, JavaThread* thread, bool realloc_failures); static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array); NOT_PRODUCT(static void print_objects(GrowableArray* objects, bool realloc_failures);) -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI public: static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk, bool realloc_failures); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/frame.cpp --- a/src/hotspot/share/runtime/frame.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/frame.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1148,7 +1148,7 @@ // make sure we have the right receiver type } } -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_empty(), "must be empty before verify"); #endif oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/globals.cpp --- a/src/hotspot/share/runtime/globals.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/globals.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/arguments.hpp" #include "runtime/globals.hpp" #include "runtime/globals_extension.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/globals.hpp --- a/src/hotspot/share/runtime/globals.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/globals.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -99,11 +99,11 @@ #define CI_COMPILER_COUNT 0 #else -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI #define CI_COMPILER_COUNT 2 #else #define CI_COMPILER_COUNT 1 -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI #endif // no compilers @@ -1144,8 +1144,8 @@ notproduct(bool, PrintSystemDictionaryAtExit, false, \ "Print the system dictionary at exit") \ \ - experimental(intx, PredictedLoadedClassCount, 0, \ - "Experimental: Tune loaded class cache starting size") \ + diagnostic(bool, DynamicallyResizeSystemDictionaries, true, \ + "Dynamically resize system dictionaries as needed") \ \ diagnostic(bool, UnsyncloadClass, false, \ "Unstable: VM calls loadClass unsynchronized. Custom " \ @@ -3901,18 +3901,6 @@ "If PrintSharedArchiveAndExit is true, also print the shared " \ "dictionary") \ \ - product(size_t, SharedReadWriteSize, 0, \ - "Deprecated") \ - \ - product(size_t, SharedReadOnlySize, 0, \ - "Deprecated") \ - \ - product(size_t, SharedMiscDataSize, 0, \ - "Deprecated") \ - \ - product(size_t, SharedMiscCodeSize, 0, \ - "Deprecated") \ - \ product(size_t, SharedBaseAddress, LP64_ONLY(32*G) \ NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)), \ "Address to allocate shared memory region for class data") \ @@ -3922,7 +3910,7 @@ "Average number of symbols per bucket in shared table") \ range(2, 246) \ \ - diagnostic(bool, IgnoreUnverifiableClassesDuringDump, false, \ + diagnostic(bool, IgnoreUnverifiableClassesDuringDump, true, \ "Do not quit -Xshare:dump even if we encounter unverifiable " \ "classes. Just exclude them from the shared dictionary.") \ \ diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/handles.cpp --- a/src/hotspot/share/runtime/handles.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/handles.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -99,7 +99,7 @@ while (bottom < top) { // This test can be moved up but for now check every oop. - assert(oopDesc::is_oop(*bottom), "handle should point to oop"); + assert(oopDesc::is_oop(*bottom, true), "handle should point to oop"); f->do_oop(bottom++); } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/init.cpp --- a/src/hotspot/share/runtime/init.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/init.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -60,7 +60,11 @@ jint universe_init(); // depends on codeCache_init and stubRoutines_init #if INCLUDE_ALL_GCS // depends on universe_init, must be before interpreter_init (currently only on SPARC) +#ifndef ZERO void g1_barrier_stubs_init() NOT_SPARC({}); +#else +void g1_barrier_stubs_init() {}; +#endif #endif void interpreter_init(); // before any methods loaded void invocationCounter_init(); // before any methods loaded diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/interfaceSupport.cpp --- a/src/hotspot/share/runtime/interfaceSupport.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/interfaceSupport.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -47,7 +47,7 @@ Histogram* RuntimeHistogram; RuntimeHistogramElement::RuntimeHistogramElement(const char* elementName) { - static volatile jint RuntimeHistogram_lock = 0; + static volatile int RuntimeHistogram_lock = 0; _name = elementName; uintx count = 0; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/java.cpp --- a/src/hotspot/share/runtime/java.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/java.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "aot/aotLoader.hpp" #include "classfile/classLoader.hpp" #include "classfile/stringTable.hpp" @@ -49,7 +50,6 @@ #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/biasedLocking.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/jniHandles.cpp --- a/src/hotspot/share/runtime/jniHandles.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/jniHandles.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -30,6 +30,7 @@ #include "runtime/jniHandles.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/thread.inline.hpp" +#include "trace/traceMacros.hpp" #include "utilities/align.hpp" #if INCLUDE_ALL_GCS #include "gc/g1/g1SATBCardTableModRefBS.hpp" @@ -126,6 +127,11 @@ template oop JNIHandles::resolve_jweak(jweak); template oop JNIHandles::resolve_jweak(jweak); +bool JNIHandles::is_global_weak_cleared(jweak handle) { + assert(is_jweak(handle), "not a weak handle"); + return guard_value(jweak_ref(handle)) == NULL; +} + void JNIHandles::destroy_global(jobject handle) { if (handle != NULL) { assert(is_global_handle(handle), "Invalid delete of global JNI handle"); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/jniHandles.hpp --- a/src/hotspot/share/runtime/jniHandles.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/jniHandles.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -82,6 +82,7 @@ // Weak global handles static jobject make_weak_global(Handle obj); static void destroy_weak_global(jobject handle); + static bool is_global_weak_cleared(jweak handle); // Test jweak without resolution // Sentinel marking deleted handles in block. Note that we cannot store NULL as // the sentinel, since clearing weak global JNI refs are done by storing NULL in diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/mutexLocker.cpp --- a/src/hotspot/share/runtime/mutexLocker.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/mutexLocker.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -116,7 +116,6 @@ Monitor* SecondaryFreeList_lock = NULL; Mutex* OldSets_lock = NULL; Monitor* RootRegionScan_lock = NULL; -Mutex* MMUTracker_lock = NULL; Monitor* GCTaskManager_lock = NULL; @@ -130,7 +129,6 @@ Monitor* JfrMsg_lock = NULL; Mutex* JfrBuffer_lock = NULL; Mutex* JfrStream_lock = NULL; -Mutex* JfrThreadGroups_lock = NULL; #endif #ifndef SUPPORTS_NATIVE_CX8 @@ -193,7 +191,6 @@ def(SecondaryFreeList_lock , PaddedMonitor, leaf , true, Monitor::_safepoint_check_never); def(OldSets_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never); def(RootRegionScan_lock , PaddedMonitor, leaf , true, Monitor::_safepoint_check_never); - def(MMUTracker_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never); def(StringDedupQueue_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); def(StringDedupTable_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); @@ -282,7 +279,6 @@ #if INCLUDE_TRACE def(JfrMsg_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always); def(JfrBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); - def(JfrThreadGroups_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); def(JfrStream_lock , PaddedMutex , leaf+1, true, Monitor::_safepoint_check_never); // ensure to rank lower than 'safepoint' def(JfrStacktrace_lock , PaddedMutex , special, true, Monitor::_safepoint_check_sometimes); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/mutexLocker.hpp --- a/src/hotspot/share/runtime/mutexLocker.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/mutexLocker.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -117,8 +117,6 @@ extern Monitor* SecondaryFreeList_lock; // protects the secondary free region list extern Mutex* OldSets_lock; // protects the old region sets extern Monitor* RootRegionScan_lock; // used to notify that the CM threads have finished scanning the IM snapshot regions -extern Mutex* MMUTracker_lock; // protects the MMU - // tracker data structures extern Mutex* Management_lock; // a lock used to serialize JVM management extern Monitor* Service_lock; // a lock used for service thread operation @@ -130,7 +128,6 @@ extern Monitor* JfrMsg_lock; // protects JFR messaging extern Mutex* JfrBuffer_lock; // protects JFR buffer operations extern Mutex* JfrStream_lock; // protects JFR stream access -extern Mutex* JfrThreadGroups_lock; // protects JFR access to Thread Groups #endif #ifndef SUPPORTS_NATIVE_CX8 diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/os.cpp --- a/src/hotspot/share/runtime/os.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/os.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" #include "classfile/moduleEntry.hpp" @@ -41,7 +42,6 @@ #endif #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/os.hpp --- a/src/hotspot/share/runtime/os.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/os.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -25,8 +25,8 @@ #ifndef SHARE_VM_RUNTIME_OS_HPP #define SHARE_VM_RUNTIME_OS_HPP +#include "jvm.h" #include "jvmtifiles/jvmti.h" -#include "prims/jvm.h" #include "runtime/extendedPC.hpp" #include "runtime/handles.hpp" #include "utilities/macros.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/perfData.cpp --- a/src/hotspot/share/runtime/perfData.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/perfData.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,10 +23,10 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/vmSymbols.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/mutex.hpp" @@ -420,11 +420,11 @@ PerfStringVariable* PerfDataManager::create_string_variable(CounterNS ns, const char* name, - jint max_length, + int max_length, const char* s, TRAPS) { - if (max_length == 0 && s != NULL) max_length = (jint)strlen(s); + if (max_length == 0 && s != NULL) max_length = (int)strlen(s); assert(max_length != 0, "PerfStringVariable with length 0"); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/perfMemory.cpp --- a/src/hotspot/share/runtime/perfMemory.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/perfMemory.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" -#include "prims/jvm.h" #include "runtime/arguments.hpp" #include "runtime/java.hpp" #include "runtime/mutex.hpp" @@ -51,7 +51,7 @@ char* PerfMemory::_end = NULL; char* PerfMemory::_top = NULL; size_t PerfMemory::_capacity = 0; -jint PerfMemory::_initialized = false; +int PerfMemory::_initialized = false; PerfDataPrologue* PerfMemory::_prologue = NULL; bool PerfMemory::_destroyed = false; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/perfMemory.hpp --- a/src/hotspot/share/runtime/perfMemory.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/perfMemory.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -120,7 +120,7 @@ static char* _top; static size_t _capacity; static PerfDataPrologue* _prologue; - static jint _initialized; + static int _initialized; static bool _destroyed; static void create_memory_region(size_t sizep); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/reflection.cpp --- a/src/hotspot/share/runtime/reflection.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/reflection.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/javaClasses.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" @@ -38,7 +39,6 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/handles.inline.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/rframe.cpp --- a/src/hotspot/share/runtime/rframe.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/rframe.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -155,7 +155,7 @@ void RFrame::print(const char* kind) { #ifndef PRODUCT -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI int cnt = top_method()->interpreter_invocation_count(); #else int cnt = top_method()->invocation_count(); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/safepoint.cpp --- a/src/hotspot/share/runtime/safepoint.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/safepoint.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -618,6 +619,14 @@ ClassLoaderDataGraph::purge_if_needed(); event_safepoint_cleanup_task_commit(event, name); } + + if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE)) { + const char* name = "resizing system dictionaries"; + EventSafepointCleanupTask event; + TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup)); + ClassLoaderDataGraph::resize_if_needed(); + event_safepoint_cleanup_task_commit(event, name); + } _subtasks.all_tasks_completed(_num_workers); } }; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/safepoint.hpp --- a/src/hotspot/share/runtime/safepoint.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/safepoint.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -83,6 +83,7 @@ SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH, SAFEPOINT_CLEANUP_STRING_TABLE_REHASH, SAFEPOINT_CLEANUP_CLD_PURGE, + SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE, // Leave this one last. SAFEPOINT_CLEANUP_NUM_TASKS }; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/sharedRuntime.cpp --- a/src/hotspot/share/runtime/sharedRuntime.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/sharedRuntime.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "aot/aotLoader.hpp" #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" @@ -45,7 +46,6 @@ #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "prims/forte.hpp" -#include "prims/jvm.h" #include "prims/jvmtiExport.hpp" #include "prims/methodHandles.hpp" #include "prims/nativeLookup.hpp" @@ -102,13 +102,13 @@ _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), "resolve_static_call"); _resolve_static_call_entry = _resolve_static_call_blob->entry_point(); -#if defined(COMPILER2) || INCLUDE_JVMCI +#if COMPILER2_OR_JVMCI // Vectors are generated only by C2 and JVMCI. bool support_wide = is_wide_vector(MaxVectorSize); if (support_wide) { _polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP); } -#endif // COMPILER2 || INCLUDE_JVMCI +#endif // COMPILER2_OR_JVMCI _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP); _polling_page_return_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/stackValue.cpp --- a/src/hotspot/share/runtime/stackValue.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/stackValue.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -191,12 +191,12 @@ void StackValue::print_on(outputStream* st) const { switch(_type) { case T_INT: - st->print("%d (int) %f (float) %x (hex)", *(int *)&_i, *(float *)&_i, *(int *)&_i); + st->print("%d (int) %f (float) %x (hex)", *(int *)&_integer_value, *(float *)&_integer_value, *(int *)&_integer_value); break; case T_OBJECT: - _o()->print_value_on(st); - st->print(" <" INTPTR_FORMAT ">", p2i((address)_o())); + _handle_value()->print_value_on(st); + st->print(" <" INTPTR_FORMAT ">", p2i((address)_handle_value())); break; case T_CONFLICT: diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/stackValue.hpp --- a/src/hotspot/share/runtime/stackValue.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/stackValue.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -31,63 +31,63 @@ class StackValue : public ResourceObj { private: BasicType _type; - intptr_t _i; // Blank java stack slot value - Handle _o; // Java stack slot value interpreted as a Handle + intptr_t _integer_value; // Blank java stack slot value + Handle _handle_value; // Java stack slot value interpreted as a Handle public: StackValue(intptr_t value) { - _type = T_INT; - _i = value; + _type = T_INT; + _integer_value = value; } StackValue(Handle value, intptr_t scalar_replaced = 0) { - _type = T_OBJECT; - _i = scalar_replaced; - _o = value; - assert(_i == 0 || _o.is_null(), "not null object should not be marked as scalar replaced"); + _type = T_OBJECT; + _integer_value = scalar_replaced; + _handle_value = value; + assert(_integer_value == 0 || _handle_value.is_null(), "not null object should not be marked as scalar replaced"); } StackValue() { - _type = T_CONFLICT; - _i = 0; + _type = T_CONFLICT; + _integer_value = 0; } // Only used during deopt- preserve object type. StackValue(intptr_t o, BasicType t) { assert(t == T_OBJECT, "should not be used"); - _type = t; - _i = o; + _type = t; + _integer_value = o; } Handle get_obj() const { assert(type() == T_OBJECT, "type check"); - return _o; + return _handle_value; } bool obj_is_scalar_replaced() const { assert(type() == T_OBJECT, "type check"); - return _i != 0; + return _integer_value != 0; } void set_obj(Handle value) { assert(type() == T_OBJECT, "type check"); - _o = value; + _handle_value = value; } intptr_t get_int() const { assert(type() == T_INT, "type check"); - return _i; + return _integer_value; } // For special case in deopt. intptr_t get_int(BasicType t) const { assert(t == T_OBJECT && type() == T_OBJECT, "type check"); - return _i; + return _integer_value; } void set_int(intptr_t value) { assert(type() == T_INT, "type check"); - _i = value; + _integer_value = value; } BasicType type() const { return _type; } @@ -95,11 +95,11 @@ bool equal(StackValue *value) { if (_type != value->_type) return false; if (_type == T_OBJECT) - return (_o == value->_o); + return (_handle_value == value->_handle_value); else { assert(_type == T_INT, "sanity check"); // [phh] compare only low addressed portions of intptr_t slots - return (*(int *)&_i == *(int *)&value->_i); + return (*(int *)&_integer_value == *(int *)&value->_integer_value); } } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/thread.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" #include "classfile/moduleEntry.hpp" @@ -51,7 +52,6 @@ #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "oops/verifyOopClosure.hpp" -#include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" @@ -762,7 +762,7 @@ // GC Support bool Thread::claim_oops_do_par_case(int strong_roots_parity) { - jint thread_parity = _oops_do_parity; + int thread_parity = _oops_do_parity; if (thread_parity != strong_roots_parity) { jint res = Atomic::cmpxchg(strong_roots_parity, &_oops_do_parity, thread_parity); if (res == thread_parity) { @@ -3724,7 +3724,7 @@ } // initialize compiler(s) -#if defined(COMPILER1) || defined(COMPILER2) || INCLUDE_JVMCI +#if defined(COMPILER1) || COMPILER2_OR_JVMCI CompileBroker::compilation_init(CHECK_JNI_ERR); #endif diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/thread.hpp --- a/src/hotspot/share/runtime/thread.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/thread.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -244,7 +244,7 @@ // The parity of the last strong_roots iteration in which this thread was // claimed as a task. - jint _oops_do_parity; + int _oops_do_parity; public: void set_last_handle_mark(HandleMark* mark) { _last_handle_mark = mark; } diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/vmStructs.cpp --- a/src/hotspot/share/runtime/vmStructs.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/vmStructs.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -47,6 +47,7 @@ #include "gc/parallel/immutableSpace.hpp" #include "gc/parallel/mutableSpace.hpp" #include "gc/serial/defNewGeneration.hpp" +#include "gc/serial/serialHeap.hpp" #include "gc/serial/tenuredGeneration.hpp" #include "gc/cms/cmsHeap.hpp" #include "gc/shared/cardTableRS.hpp" @@ -356,7 +357,7 @@ nonstatic_field(Symbol, _length, unsigned short) \ unchecked_nonstatic_field(Symbol, _body, sizeof(jbyte)) /* NOTE: no type */ \ nonstatic_field(Symbol, _body[0], jbyte) \ - nonstatic_field(TypeArrayKlass, _max_length, int) \ + nonstatic_field(TypeArrayKlass, _max_length, jint) \ \ /***********************/ \ /* Constant Pool Cache */ \ @@ -579,7 +580,7 @@ static_field(PerfMemory, _top, char*) \ static_field(PerfMemory, _capacity, size_t) \ static_field(PerfMemory, _prologue, PerfDataPrologue*) \ - static_field(PerfMemory, _initialized, jint) \ + static_field(PerfMemory, _initialized, int) \ \ /***************/ \ /* SymbolTable */ \ @@ -1465,6 +1466,7 @@ declare_toplevel_type(CollectedHeap) \ declare_type(GenCollectedHeap, CollectedHeap) \ declare_type(CMSHeap, GenCollectedHeap) \ + declare_type(SerialHeap, GenCollectedHeap) \ declare_toplevel_type(Generation) \ declare_type(DefNewGeneration, Generation) \ declare_type(CardGeneration, Generation) \ @@ -2175,6 +2177,7 @@ declare_toplevel_type(vframeArray) \ declare_toplevel_type(vframeArrayElement) \ declare_toplevel_type(Annotations*) \ + declare_type(OopMapValue, StackObj) \ \ /***************/ \ /* Miscellaneous types */ \ @@ -2257,7 +2260,8 @@ \ declare_constant(G1SATBCardTableModRefBS::g1_young_gen) \ \ - declare_constant(CollectedHeap::GenCollectedHeap) \ + declare_constant(CollectedHeap::SerialHeap) \ + declare_constant(CollectedHeap::CMSHeap) \ declare_constant(CollectedHeap::ParallelScavengeHeap) \ declare_constant(CollectedHeap::G1CollectedHeap) \ \ diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/vm_operations.cpp --- a/src/hotspot/share/runtime/vm_operations.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/vm_operations.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -230,6 +230,10 @@ JNIHandles::print_on(_out); } +void VM_PrintMetadata::doit() { + MetaspaceAux::print_metadata_for_nmt(_out, _scale); +} + VM_FindDeadlocks::~VM_FindDeadlocks() { if (_deadlocks != NULL) { DeadlockCycle* cycle = _deadlocks; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/runtime/vm_operations.hpp --- a/src/hotspot/share/runtime/vm_operations.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/runtime/vm_operations.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -111,6 +111,7 @@ template(ThreadsSuspendJVMTI) \ template(ICBufferFull) \ template(ScavengeMonitors) \ + template(PrintMetadata) \ class VM_Operation: public CHeapObj { public: @@ -374,6 +375,17 @@ void doit(); }; +class VM_PrintMetadata : public VM_Operation { + private: + outputStream* _out; + size_t _scale; + public: + VM_PrintMetadata(outputStream* out, size_t scale) : _out(out), _scale(scale) {}; + + VMOp_Type type() const { return VMOp_PrintMetadata; } + void doit(); +}; + class DeadlockCycle; class VM_FindDeadlocks: public VM_Operation { private: diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/diagnosticArgument.cpp --- a/src/hotspot/share/services/diagnosticArgument.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/diagnosticArgument.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvm.h" #include "runtime/thread.hpp" #include "services/diagnosticArgument.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/diagnosticCommand.cpp --- a/src/hotspot/share/services/diagnosticCommand.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/diagnosticCommand.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/classLoaderStats.hpp" #include "classfile/compactHashtable.hpp" #include "compiler/compileBroker.hpp" @@ -30,7 +31,6 @@ #include "gc/shared/vmGCOperations.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/globals.hpp" #include "runtime/javaCalls.hpp" #include "runtime/os.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/diagnosticFramework.cpp --- a/src/hotspot/share/services/diagnosticFramework.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/diagnosticFramework.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,10 +23,10 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "services/diagnosticArgument.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/heapDumper.cpp --- a/src/hotspot/share/services/heapDumper.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/heapDumper.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -34,7 +35,6 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/javaCalls.hpp" #include "runtime/jniHandles.hpp" #include "runtime/os.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/mallocSiteTable.cpp --- a/src/hotspot/share/services/mallocSiteTable.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/mallocSiteTable.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -235,8 +235,8 @@ void MallocSiteTable::AccessLock::exclusiveLock() { - jint target; - jint val; + int target; + int val; assert(_lock_state != ExclusiveLock, "Can only call once"); assert(*_lock >= 0, "Can not content exclusive lock"); diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/memTracker.cpp --- a/src/hotspot/share/services/memTracker.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/memTracker.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -22,8 +22,8 @@ * */ #include "precompiled.hpp" +#include "jvm.h" -#include "prims/jvm.h" #include "runtime/mutex.hpp" #include "services/memBaseline.hpp" #include "services/memReporter.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/memoryService.cpp --- a/src/hotspot/share/services/memoryService.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/memoryService.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -86,7 +86,7 @@ void MemoryService::set_universe_heap(CollectedHeap* heap) { CollectedHeap::Name kind = heap->kind(); switch (kind) { - case CollectedHeap::GenCollectedHeap : + case CollectedHeap::SerialHeap : case CollectedHeap::CMSHeap : { add_gen_collected_heap_info(GenCollectedHeap::heap()); break; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/nmtDCmd.cpp --- a/src/hotspot/share/services/nmtDCmd.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/nmtDCmd.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -24,6 +24,8 @@ #include "precompiled.hpp" #include "memory/resourceArea.hpp" #include "runtime/mutexLocker.hpp" +#include "runtime/vmThread.hpp" +#include "runtime/vm_operations.hpp" #include "services/nmtDCmd.hpp" #include "services/memReporter.hpp" #include "services/memTracker.hpp" @@ -38,6 +40,8 @@ _detail("detail", "request runtime to report memory allocation >= " "1K by each callsite.", "BOOLEAN", false, "false"), + _metadata("metadata", "request runtime to report metadata information", + "BOOLEAN", false, "false"), _baseline("baseline", "request runtime to baseline current memory usage, " \ "so it can be compared against in later time.", "BOOLEAN", false, "false"), @@ -57,6 +61,7 @@ "STRING", false, "KB") { _dcmdparser.add_dcmd_option(&_summary); _dcmdparser.add_dcmd_option(&_detail); + _dcmdparser.add_dcmd_option(&_metadata); _dcmdparser.add_dcmd_option(&_baseline); _dcmdparser.add_dcmd_option(&_summary_diff); _dcmdparser.add_dcmd_option(&_detail_diff); @@ -92,6 +97,7 @@ int nopt = 0; if (_summary.is_set() && _summary.value()) { ++nopt; } if (_detail.is_set() && _detail.value()) { ++nopt; } + if (_metadata.is_set() && _metadata.value()) { ++nopt; } if (_baseline.is_set() && _baseline.value()) { ++nopt; } if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; } if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; } @@ -100,7 +106,7 @@ if (nopt > 1) { output()->print_cr("At most one of the following option can be specified: " \ - "summary, detail, baseline, summary.diff, detail.diff, shutdown"); + "summary, detail, metadata, baseline, summary.diff, detail.diff, shutdown"); return; } else if (nopt == 0) { if (_summary.is_set()) { @@ -118,9 +124,13 @@ report(true, scale_unit); } else if (_detail.value()) { if (!check_detail_tracking_level(output())) { - return; - } + return; + } report(false, scale_unit); + } else if (_metadata.value()) { + size_t scale = get_scale(_scale.value()); + VM_PrintMetadata op(output(), scale); + VMThread::execute(&op); } else if (_baseline.value()) { MemBaseline& baseline = MemTracker::get_baseline(); if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/services/nmtDCmd.hpp --- a/src/hotspot/share/services/nmtDCmd.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/services/nmtDCmd.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -39,6 +39,7 @@ protected: DCmdArgument _summary; DCmdArgument _detail; + DCmdArgument _metadata; DCmdArgument _baseline; DCmdArgument _summary_diff; DCmdArgument _detail_diff; diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/trace/traceMacros.hpp --- a/src/hotspot/share/trace/traceMacros.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/trace/traceMacros.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -41,6 +41,8 @@ #define TRACE_REGISTER_NATIVES ((void*)((address_word)(&trace_register_natives))) #define TRACE_START() JNI_OK #define TRACE_INITIALIZE() JNI_OK +#define TRACE_ALLOCATION(obj, size, thread) +#define TRACE_WEAK_OOPS_DO(is_alive, f) #define TRACE_VM_EXIT() #define TRACE_VM_ERROR() #define TRACE_SUSPEND_THREAD(t) diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/trace/traceevents.xml --- a/src/hotspot/share/trace/traceevents.xml Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/trace/traceevents.xml Thu Nov 16 12:15:55 2017 +0000 @@ -108,6 +108,7 @@ description="Revoked bias of object" has_thread="true" has_stacktrace="true" is_instant="false"> + diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/formatBuffer.hpp --- a/src/hotspot/share/utilities/formatBuffer.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/formatBuffer.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -25,8 +25,8 @@ #ifndef SHARE_VM_UTILITIES_FORMATBUFFER_HPP #define SHARE_VM_UTILITIES_FORMATBUFFER_HPP +#include "jvm.h" #include "utilities/globalDefinitions.hpp" -#include "prims/jvm.h" #include // Simple class to format the ctor arguments into a fixed-sized buffer. diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/globalDefinitions_xlc.hpp --- a/src/hotspot/share/utilities/globalDefinitions_xlc.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/globalDefinitions_xlc.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -86,6 +86,7 @@ // In this case you need to copy the following defines to a position after #include // (see jmv_aix.h). #ifdef AIX + #include #ifdef _LP64 #undef NULL #define NULL 0L diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/growableArray.hpp --- a/src/hotspot/share/utilities/growableArray.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/growableArray.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -402,7 +402,7 @@ // matching key according to the static compare function. Insert // that element is not already in the list. Assumes the list is // already sorted according to compare function. - template E insert_sorted(E& key) { + template E insert_sorted(const E& key) { bool found; int location = find_sorted(key, found); if (!found) { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/hashtable.cpp --- a/src/hotspot/share/utilities/hashtable.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/hashtable.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -264,6 +264,49 @@ } } +template bool BasicHashtable::resize(int new_size) { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + + // Allocate new buckets + HashtableBucket* buckets_new = NEW_C_HEAP_ARRAY2_RETURN_NULL(HashtableBucket, new_size, F, CURRENT_PC); + if (buckets_new == NULL) { + return false; + } + + // Clear the new buckets + for (int i = 0; i < new_size; i++) { + buckets_new[i].clear(); + } + + int table_size_old = _table_size; + // hash_to_index() uses _table_size, so switch the sizes now + _table_size = new_size; + + // Move entries from the old table to a new table + for (int index_old = 0; index_old < table_size_old; index_old++) { + for (BasicHashtableEntry* p = _buckets[index_old].get_entry(); p != NULL; ) { + BasicHashtableEntry* next = p->next(); + bool keep_shared = p->is_shared(); + int index_new = hash_to_index(p->hash()); + + p->set_next(buckets_new[index_new].get_entry()); + buckets_new[index_new].set_entry(p); + + if (keep_shared) { + p->set_shared(); + } + p = next; + } + } + + // The old backets now can be released + BasicHashtable::free_buckets(); + + // Switch to the new storage + _buckets = buckets_new; + + return true; +} // Dump footprint and bucket length statistics // diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/hashtable.hpp --- a/src/hotspot/share/utilities/hashtable.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/hashtable.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -237,6 +237,8 @@ int number_of_entries() const { return _number_of_entries; } + bool resize(int new_size); + template void verify_table(const char* table_name) PRODUCT_RETURN; }; @@ -281,7 +283,6 @@ HashtableEntry** bucket_addr(int i) { return (HashtableEntry**)BasicHashtable::bucket_addr(i); } - }; template class RehashableHashtable : public Hashtable { diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/macros.hpp --- a/src/hotspot/share/utilities/macros.hpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/macros.hpp Thu Nov 16 12:15:55 2017 +0000 @@ -322,7 +322,9 @@ #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +#ifndef BSD #define BSD +#endif // BSD defined in #define BSD_ONLY(code) code #define NOT_BSD(code) #else diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/ostream.cpp --- a/src/hotspot/share/utilities/ostream.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/ostream.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "compiler/compileLog.hpp" #include "oops/oop.inline.hpp" -#include "prims/jvm.h" #include "runtime/arguments.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff -r 18e431209168 -r 76d033c9908f src/hotspot/share/utilities/vmError.cpp --- a/src/hotspot/share/utilities/vmError.cpp Thu Nov 16 10:29:18 2017 +0000 +++ b/src/hotspot/share/utilities/vmError.cpp Thu Nov 16 12:15:55 2017 +0000 @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" +#include "jvm.h" #include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/collectedHeap.hpp" #include "logging/logConfiguration.hpp" -#include "prims/jvm.h" #include "prims/whitebox.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" diff -r 18e431209168 -r 76d033c9908f src/java.base/macosx/native/include/jni_md.h --- a/src/java.base/macosx/native/include/jni_md.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 1996, 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 _JAVASOFT_JNI_MD_H_ -#define _JAVASOFT_JNI_MD_H_ - -#define JNIEXPORT __attribute__((visibility("default"))) -#define JNIIMPORT __attribute__((visibility("default"))) -#define JNICALL - -typedef int jint; -#ifdef _LP64 /* 64-bit */ -typedef long jlong; -#else -typedef long long jlong; -#endif - -typedef signed char jbyte; - -#endif /* !_JAVASOFT_JNI_MD_H_ */ diff -r 18e431209168 -r 76d033c9908f src/java.base/macosx/native/include/jvm_md.h --- a/src/java.base/macosx/native/include/jvm_md.h Thu Nov 16 10:29:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 1997, 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 _JAVASOFT_JVM_MD_H_ -#define _JAVASOFT_JVM_MD_H_ - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -#include /* For DIR */ -#include /* For MAXPATHLEN */ -#include /* For F_OK, R_OK, W_OK */ -#include /* For ptrdiff_t */ -#include /* For uintptr_t */ - -#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} - -#define JNI_LIB_PREFIX "lib" -#define JNI_LIB_SUFFIX ".dylib" -#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME "." VERSION JNI_LIB_SUFFIX -#define JNI_LIB_NAME(NAME) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX - -#define JVM_MAXPATHLEN MAXPATHLEN - -#define JVM_R_OK R_OK -#define JVM_W_OK W_OK -#define JVM_X_OK X_OK -#define JVM_F_OK F_OK - -/* - * File I/O - */ - -#include -#include -#include -#include -#include - -/* O Flags */ - -#define JVM_O_RDONLY O_RDONLY -#define JVM_O_WRONLY O_WRONLY -#define JVM_O_RDWR O_RDWR -#define JVM_O_O_APPEND O_APPEND -#define JVM_O_EXCL O_EXCL -#define JVM_O_CREAT O_CREAT - -/* Signals */ - -#define JVM_SIGINT SIGINT -#define JVM_SIGTERM SIGTERM - - -#endif /* !_JAVASOFT_JVM_MD_H_ */ diff -r 18e431209168 -r 76d033c9908f src/java.base/share/classes/java/lang/StackFrameInfo.java --- a/src/java.base/share/classes/java/lang/StackFrameInfo.java Thu Nov 16 10:29:18 2017 +0000 +++ b/src/java.base/share/classes/java/lang/StackFrameInfo.java Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,14 +32,12 @@ import java.lang.invoke.MethodType; class StackFrameInfo implements StackFrame { + private final byte RETAIN_CLASS_REF = 0x01; + private final static JavaLangInvokeAccess JLIA = SharedSecrets.getJavaLangInvokeAccess(); - // Footprint improvement: MemberName::clazz can replace - // StackFrameInfo::declaringClass. - - private final StackWalker walker; - private final Class declaringClass; + private final byte flags; private final Object memberName; private final short bci; private volatile StackTraceElement ste; @@ -49,8 +47,7 @@ * to use */ StackFrameInfo(StackWalker walker) { - this.walker = walker; - this.declaringClass = null; + this.flags = walker.retainClassRef ? RETAIN_CLASS_REF : 0; this.bci = -1; this.memberName = JLIA.newMemberName(); } @@ -58,20 +55,20 @@ // package-private called by StackStreamFactory to skip // the capability check Class declaringClass() { - return declaringClass; + return JLIA.getDeclaringClass(memberName); } // ----- implementation of StackFrame methods @Override public String getClassName() { - return declaringClass.getName(); + return declaringClass().getName(); } @Override public Class getDeclaringClass() { - walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE); - return declaringClass; + ensureRetainClassRefEnabled(); + return declaringClass(); } @Override @@ -81,7 +78,7 @@ @Override public MethodType getMethodType() { - walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE); + ensureRetainClassRefEnabled(); return JLIA.getMethodType(memberName); } @@ -137,4 +134,10 @@ } return s; } + + private void ensureRetainClassRefEnabled() { + if ((flags & RETAIN_CLASS_REF) == 0) { + throw new UnsupportedOperationException("No access to RETAIN_CLASS_REFERENCE"); + } + } } diff -r 18e431209168 -r 76d033c9908f src/java.base/share/classes/java/lang/StackWalker.java --- a/src/java.base/share/classes/java/lang/StackWalker.java Thu Nov 16 10:29:18 2017 +0000 +++ b/src/java.base/share/classes/java/lang/StackWalker.java Thu Nov 16 12:15:55 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -296,6 +296,7 @@ private final Set