diff --git a/jdk/make/CompileDemos.gmk b/jdk/make/CompileDemos.gmk index 5982ea02592..336a2538e83 100644 --- a/jdk/make/CompileDemos.gmk +++ b/jdk/make/CompileDemos.gmk @@ -263,239 +263,13 @@ $(eval $(call SetupBuildDemo, TransparentRuler, \ MAIN_CLASS := transparentruler.Ruler, \ )) -$(eval $(call SetupBuildDemo, jconsole-plugin, \ - DEMO_SUBDIR := scripting, \ - SRC_SUB_DIR := src, \ - MAIN_CLASS := NONE, \ -)) - -$(eval $(call SetupBuildDemo, FullThreadDump, \ - DEMO_SUBDIR := management, \ -)) - -$(eval $(call SetupBuildDemo, JTop, \ - DEMO_SUBDIR := management, \ -)) - -$(eval $(call SetupBuildDemo, MemoryMonitor, \ - DEMO_SUBDIR := management, \ -)) - -$(eval $(call SetupBuildDemo, VerboseGC, \ - DEMO_SUBDIR := management, \ -)) - -################################################################################ -# Build JVMTI demos. - -# Setup make rules for building a JVMTI demo. -# -# Parameter 1 is the name of the rule. This name is used as variable prefix, -# and the targets generated are listed in a variable by that name. -# -# Remaining parameters are named arguments. These include: -# EXTRA_SRC_SUBDIR Also include these subdirectories -# TOOLCHAIN Optionally specify toolchain to use -SetupBuildJvmtiDemo = $(NamedParamsMacroTemplate) -define SetupBuildJvmtiDemoBody - $1_SRC := \ - $(DEMO_SHARE_SRC)/jvmti/$1 \ - $$(wildcard $$(addprefix $(DEMO_SHARE_SRC)/jvmti/, \ - agent_util $$($1_EXTRA_SRC_SUBDIR))) - - ### Build the native lib - $1_CFLAGS_INCLUDE := $$(addprefix -I, $$($1_SRC)) - - $1_CXXFLAGS := $$($1_CFLAGS_INCLUDE) $(CXXFLAGS_JDKLIB) $(CXXFLAGS_DEBUG_SYMBOLS) - - ifeq ($$($1_TOOLCHAIN), TOOLCHAIN_LINK_CXX) - # For C++, we also need some special treatment. - $1_LDFLAGS := $$(LDFLAGS_CXX_JDK) - $1_LIBS := $(LIBCXX) - - ifeq ($(OPENJDK_TARGET_CPU_ARCH), sparc) - $1_CXXFLAGS := $$(filter-out -xregs=no%appl, $$($1_CXXFLAGS)) - endif - endif - - # Remove the -incremental:no setting to get .ilk-files like in the old build. - $$(eval $$(call SetupNativeCompilation, BUILD_DEMO_JVMTI_NATIVE_$1, \ - SRC := $$($1_SRC), \ - TOOLCHAIN := $$($1_TOOLCHAIN), \ - OPTIMIZATION := LOW, \ - CFLAGS := $$($1_CFLAGS_INCLUDE) $$(CFLAGS_JDKLIB) $$(CFLAGS_DEBUG_SYMBOLS), \ - CXXFLAGS := $$($1_CXXFLAGS), \ - LDFLAGS := $(filter-out -incremental:no -opt:ref, $$(LDFLAGS_JDKLIB)) \ - $$($1_LDFLAGS), \ - LDFLAGS_macosx := $$(call SET_EXECUTABLE_ORIGIN), \ - LIBS := $$($1_LIBS), \ - LIBS_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ - RC_FLAGS := $$(RC_FLAGS) \ - -D "JDK_FNAME=$1.dll" \ - -D "JDK_INTERNAL_NAME=$1" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jvmti/$1, \ - OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/lib, \ - LIBRARY := $1, \ - STRIP_SYMBOLS := false, \ - )) - - $1 += $$(BUILD_DEMO_JVMTI_NATIVE_$1) - - ### Build the jar, if we have java sources - ifneq ($$(wildcard $(DEMO_SHARE_SRC)/jvmti/$1/*.java), ) - $$(eval $$(call SetupJavaCompilation, BUILD_DEMO_JVMTI_JAVA_$1, \ - SETUP := GENERATE_USINGJDKBYTECODE, \ - SRC := $(DEMO_SHARE_SRC)/jvmti/$1, \ - BIN := $(SUPPORT_OUTPUTDIR)/demos/classes/jvmti/$1, \ - COPY := $(COPY_TO_JAR), \ - JAR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/$1.jar, \ - EXTRA_MANIFEST_ATTR := Main-Class: \n, \ - MANIFEST := $(DEMO_MANIFEST), \ - )) - - $1 += $$(BUILD_DEMO_JVMTI_JAVA_$1_JAR) - endif - - ### Build the source zip - $1_EXCLUDE_FILES := \ - $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/README.txt, \ - agent_util $$($1_EXTRA_SRC_SUBDIR))) \ - $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/sample.makefile.txt, \ - agent_util $$($1_EXTRA_SRC_SUBDIR))) - - $$(eval $$(call SetupZipArchive, BUILD_DEMO_JVMTI_SRC_$1, \ - SRC := $$($1_SRC), \ - EXCLUDE_FILES := $$($1_EXCLUDE_FILES), \ - ZIP := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/src.zip, \ - )) - - $1 += $$(BUILD_DEMO_JVMTI_SRC_$1) - - # Copy files to image - $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/README.txt: $(DEMO_SHARE_SRC)/jvmti/$1/README.txt - $$(call install-file) - $(CHMOD) -f ug+w $$@ - - $1 += $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/README.txt - - ifeq ($(OPENJDK_TARGET_OS), windows) - # These lib and exp files normally end up in OBJECT_DIR but for demos they - # are supposed to be included in the distro. Since they are created as - # a side-effect of the library compilation, make does not know about them. - $1_SUPPORT_OUTPUTDIR := $(SUPPORT_OUTPUTDIR)/demos/native/jvmti/$1 - $1_IMAGE_OUTPUTDIR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/lib - - $$($1_SUPPORT_OUTPUTDIR)/$1.lib: $$(BUILD_DEMO_JVMTI_NATIVE_$1) - - $$($1_SUPPORT_OUTPUTDIR)/$1.exp: $$(BUILD_DEMO_JVMTI_NATIVE_$1) - - $$($1_IMAGE_OUTPUTDIR)/$1.lib: $$($1_SUPPORT_OUTPUTDIR)/$1.lib - $$(call install-file) - - $$($1_IMAGE_OUTPUTDIR)/$1.exp: $$($1_SUPPORT_OUTPUTDIR)/$1.exp - $$(call install-file) - - $1 += $$($1_IMAGE_OUTPUTDIR)/$1.lib $$($1_IMAGE_OUTPUTDIR)/$1.exp - endif - - TARGETS += $$($1) -endef - -$(eval $(call SetupBuildJvmtiDemo, compiledMethodLoad)) -$(eval $(call SetupBuildJvmtiDemo, gctest)) -$(eval $(call SetupBuildJvmtiDemo, heapViewer)) -$(eval $(call SetupBuildJvmtiDemo, versionCheck)) - -$(eval $(call SetupBuildJvmtiDemo, heapTracker, \ - EXTRA_SRC_SUBDIR := java_crw_demo, \ -)) - -$(eval $(call SetupBuildJvmtiDemo, minst, \ - EXTRA_SRC_SUBDIR := java_crw_demo, \ -)) - -$(eval $(call SetupBuildJvmtiDemo, mtrace, \ - EXTRA_SRC_SUBDIR := java_crw_demo, \ -)) - -$(eval $(call SetupBuildJvmtiDemo, waiters, \ - TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ -)) - -################################################################################ -# Build the Poller demo (on Solaris only). - -ifeq ($(OPENJDK_TARGET_OS), solaris) - DEMO_SOLARIS_SRC := $(JDK_TOPDIR)/src/demo/solaris - - $(eval $(call SetupJavaCompilation, BUILD_DEMO_JAVA_Poller, \ - SETUP := GENERATE_USINGJDKBYTECODE, \ - SRC := $(DEMO_SOLARIS_SRC)/jni/Poller, \ - BIN := $(SUPPORT_OUTPUTDIR)/demos/classes/jni/Poller, \ - HEADERS := $(SUPPORT_OUTPUTDIR)/demos/classes/jni/Poller, \ - JAR := $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/Poller.jar, \ - MANIFEST := $(SUPPORT_OUTPUTDIR)/demos/java-main-manifest.mf, \ - SRCZIP := $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/src.zip, \ - COPY := README.txt Poller.c, \ - JARMAIN := Client, \ - )) - - TARGETS += $(BUILD_DEMO_JAVA_Poller) - - $(eval $(call SetupNativeCompilation, BUILD_DEMO_NATIVE_Poller, \ - SRC := $(DEMO_SOLARIS_SRC)/jni/Poller, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(SUPPORT_OUTPUTDIR)/demos/classes/jni/Poller, \ - LDFLAGS := $(LDFLAGS_JDKLIB), \ - LIBS_solaris := -lc, \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller, \ - OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native, \ - LIBRARY := Poller, \ - STRIP_SYMBOLS := false, \ - )) - - TARGETS += $(BUILD_DEMO_NATIVE_Poller) - - # We can only compile native code after java has been compiled (since we - # depend on generated .h files) - $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller/Poller.o: \ - $(BUILD_DEMO_JAVA_Poller) - - # Copy to image - $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/README.txt: \ - $(DEMO_SOLARIS_SRC)/jni/Poller/README.txt - $(call install-file) - $(CHMOD) -f ug+w $@ - - TARGETS += $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/README.txt - - $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/lib/libPoller.so: \ - $(SUPPORT_OUTPUTDIR)/demos/native/libPoller.so - $(call install-file) - - TARGETS += $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/lib/libPoller.so -endif - ################################################################################ # Copy html and README files. -$(SUPPORT_OUTPUTDIR)/demos/image/management/index.html: $(DEMO_SHARE_SRC)/management/index.html - $(call install-file) - $(CHMOD) -f ug+w $@ - -$(SUPPORT_OUTPUTDIR)/demos/image/jvmti/index.html: $(DEMO_SHARE_SRC)/jvmti/index.html - $(call install-file) - $(CHMOD) -f ug+w $@ - $(SUPPORT_OUTPUTDIR)/demos/image/README: $(DEMO_SHARE_SRC)/README $(call install-file) -TARGETS += $(SUPPORT_OUTPUTDIR)/demos/image/management/index.html \ - $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/index.html \ - $(SUPPORT_OUTPUTDIR)/demos/image/README +TARGETS += $(SUPPORT_OUTPUTDIR)/demos/image/README ################################################################################ # Copy netbeans project files. diff --git a/jdk/make/CompileTools.gmk b/jdk/make/CompileTools.gmk index 9d76d660e2d..7670d694323 100644 --- a/jdk/make/CompileTools.gmk +++ b/jdk/make/CompileTools.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -30,11 +30,19 @@ include MakeBase.gmk include JavaCompilation.gmk include SetupJavaCompilers.gmk +$(eval $(call IncludeCustomExtension, jdk, CompileTools.gmk)) + ################################################################################ +# Use += to be able to add to this from a custom extension +BUILD_TOOLS_SRC_DIRS += \ + $(JDK_TOPDIR)/make/src/classes \ + $(BUILDTOOLS_OUTPUTDIR)/interim_cldrconverter_classes \ + # + $(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \ SETUP := GENERATE_OLDBYTECODE, \ - SRC := $(JDK_TOPDIR)/make/src/classes $(BUILDTOOLS_OUTPUTDIR)/interim_cldrconverter_classes, \ + SRC := $(BUILD_TOOLS_SRC_DIRS), \ EXCLUDES := build/tools/deps \ build/tools/jigsaw, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes)) diff --git a/jdk/make/CopySamples.gmk b/jdk/make/CopySamples.gmk deleted file mode 100644 index 09d0bf7ba44..00000000000 --- a/jdk/make/CopySamples.gmk +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# 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. -# - -default: all - -include $(SPEC) -include MakeBase.gmk - -################################################################################ - -SAMPLE_TARGET_DIR := $(SUPPORT_OUTPUTDIR)/sample/image -SAMPLE_SOURCE_DIR := $(JDK_TOPDIR)/src/sample/share -SAMPLE_SOLARIS_SOURCE_DIR := $(JDK_TOPDIR)/src/sample/solaris - -# Exclude the vm directory -$(eval $(call SetupCopyFiles, COPY_SHARE_SAMPLES, \ - SRC := $(SAMPLE_SOURCE_DIR), \ - DEST := $(SAMPLE_TARGET_DIR), \ - FILES := $(filter-out $(SAMPLE_SOURCE_DIR)/vm/%, \ - $(call CacheFind, $(SAMPLE_SOURCE_DIR))), \ -)) - -TARGETS += $(COPY_SHARE_SAMPLES) - -ifneq (, $(filter $(OPENJDK_TARGET_OS), solaris macosx)) - $(eval $(call SetupCopyFiles, COPY_SOLARIS_SAMPLES, \ - SRC := $(SAMPLE_SOLARIS_SOURCE_DIR), \ - DEST := $(SAMPLE_TARGET_DIR), \ - FILES := $(call CacheFind, $(SAMPLE_SOLARIS_SOURCE_DIR)), \ - )) - - TARGETS += $(COPY_SOLARIS_SAMPLES) -endif - -################################################################################ - -$(eval $(call IncludeCustomExtension, jdk, CopySamples.gmk)) - -################################################################################ - -all: $(TARGETS) - -.PHONY: all default diff --git a/jdk/make/Tools.gmk b/jdk/make/Tools.gmk index 92af1ee102f..153da84124d 100644 --- a/jdk/make/Tools.gmk +++ b/jdk/make/Tools.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -28,6 +28,9 @@ _TOOLS_GMK := 1 include JavaCompilation.gmk +# Hook to include the corresponding custom file, if present. +$(eval $(call IncludeCustomExtension, jdk, Tools.gmk)) + ################################################################################ # To avoid reevaluating the compilation setup for the tools each time this file # is included, the actual compilation is handled by CompileTools.gmk. The diff --git a/jdk/make/data/charsetmapping/stdcs-linux b/jdk/make/data/charsetmapping/stdcs-linux index 3bb08875a9d..0a870b754e1 100644 --- a/jdk/make/data/charsetmapping/stdcs-linux +++ b/jdk/make/data/charsetmapping/stdcs-linux @@ -24,3 +24,5 @@ JIS_X_0208 JIS_X_0212 JIS_X_0208_Solaris JIS_X_0212_Solaris +MS932 +SJIS # SJIS must go together with MS932 to support sun.nio.cs.map diff --git a/jdk/src/demo/share/README b/jdk/src/demo/share/README index e70be01a0a2..7936fb3893e 100644 --- a/jdk/src/demo/share/README +++ b/jdk/src/demo/share/README @@ -1,4 +1,4 @@ -The source code provided with samples and demos for the JDK is meant +The source code provided with demos for the JDK is meant to illustrate the usage of a given feature or technique and has been deliberately simplified. Additional steps required for a production-quality application, such as security checks, input diff --git a/jdk/src/demo/share/jvmti/agent_util/README.txt b/jdk/src/demo/share/jvmti/agent_util/README.txt deleted file mode 100644 index 88638b01e9a..00000000000 --- a/jdk/src/demo/share/jvmti/agent_util/README.txt +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -agent_util sources - -Just some shared generic source used by several of the demos. - diff --git a/jdk/src/demo/share/jvmti/agent_util/agent_util.c b/jdk/src/demo/share/jvmti/agent_util/agent_util.c deleted file mode 100644 index 6678ef7d966..00000000000 --- a/jdk/src/demo/share/jvmti/agent_util/agent_util.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include - -/* ------------------------------------------------------------------- */ -/* Generic C utility functions */ - -/* Send message to stdout or whatever the data output location is */ -void -stdout_message(const char * format, ...) -{ - va_list ap; - - va_start(ap, format); - (void)vfprintf(stdout, format, ap); - va_end(ap); -} - -/* Send message to stderr or whatever the error output location is and exit */ -void -fatal_error(const char * format, ...) -{ - va_list ap; - - va_start(ap, format); - (void)vfprintf(stderr, format, ap); - (void)fflush(stderr); - va_end(ap); - exit(3); -} - -/* Get a token from a string (strtok is not MT-safe) - * str String to scan - * seps Separation characters - * buf Place to put results - * max Size of buf - * Returns NULL if no token available or can't do the scan. - */ -char * -get_token(char *str, char *seps, char *buf, int max) -{ - int len; - - buf[0] = 0; - if ( str==NULL || str[0]==0 ) { - return NULL; - } - str += strspn(str, seps); - if ( str[0]==0 ) { - return NULL; - } - len = (int)strcspn(str, seps); - if ( len >= max ) { - return NULL; - } - (void)strncpy(buf, str, len); - buf[len] = 0; - return str+len; -} - -/* Determines if a class/method is specified by a list item - * item String that represents a pattern to match - * If it starts with a '*', then any class is allowed - * If it ends with a '*', then any method is allowed - * cname Class name, e.g. "java.lang.Object" - * mname Method name, e.g. "" - * Returns 1(true) or 0(false). - */ -static int -covered_by_list_item(char *item, char *cname, char *mname) -{ - int len; - - len = (int)strlen(item); - if ( item[0]=='*' ) { - if ( strncmp(mname, item+1, len-1)==0 ) { - return 1; - } - } else if ( item[len-1]=='*' ) { - if ( strncmp(cname, item, len-1)==0 ) { - return 1; - } - } else { - int cname_len; - - cname_len = (int)strlen(cname); - if ( strncmp(cname, item, (len>cname_len?cname_len:len))==0 ) { - if ( cname_len >= len ) { - /* No method name supplied in item, we must have matched */ - return 1; - } else { - int mname_len; - - mname_len = (int)strlen(mname); - item += cname_len+1; - len -= cname_len+1; - if ( strncmp(mname, item, (len>mname_len?mname_len:len))==0 ) { - return 1; - } - } - } - } - return 0; -} - -/* Determines if a class/method is specified by this list - * list String of comma separated pattern items - * cname Class name, e.g. "java.lang.Object" - * mname Method name, e.g. "" - * Returns 1(true) or 0(false). - */ -static int -covered_by_list(char *list, char *cname, char *mname) -{ - char token[1024]; - char *next; - - if ( list[0] == 0 ) { - return 0; - } - - next = get_token(list, ",", token, sizeof(token)); - while ( next != NULL ) { - if ( covered_by_list_item(token, cname, mname) ) { - return 1; - } - next = get_token(next, ",", token, sizeof(token)); - } - return 0; -} - -/* Determines which class and methods we are interested in - * cname Class name, e.g. "java.lang.Object" - * mname Method name, e.g. "" - * include_list Empty or an explicit list for inclusion - * exclude_list Empty or an explicit list for exclusion - * Returns 1(true) or 0(false). - */ -int -interested(char *cname, char *mname, char *include_list, char *exclude_list) -{ - if ( exclude_list!=NULL && exclude_list[0]!=0 && - covered_by_list(exclude_list, cname, mname) ) { - return 0; - } - if ( include_list!=NULL && include_list[0]!=0 && - !covered_by_list(include_list, cname, mname) ) { - return 0; - } - return 1; -} - -/* ------------------------------------------------------------------- */ -/* Generic JVMTI utility functions */ - -/* Every JVMTI interface returns an error code, which should be checked - * to avoid any cascading errors down the line. - * The interface GetErrorName() returns the actual enumeration constant - * name, making the error messages much easier to understand. - */ -void -check_jvmti_error(jvmtiEnv *jvmti, jvmtiError errnum, const char *str) -{ - if ( errnum != JVMTI_ERROR_NONE ) { - char *errnum_str; - - errnum_str = NULL; - (void)(*jvmti)->GetErrorName(jvmti, errnum, &errnum_str); - - fatal_error("ERROR: JVMTI: %d(%s): %s\n", errnum, - (errnum_str==NULL?"Unknown":errnum_str), - (str==NULL?"":str)); - } -} - -/* All memory allocated by JVMTI must be freed by the JVMTI Deallocate - * interface. - */ -void -deallocate(jvmtiEnv *jvmti, void *ptr) -{ - jvmtiError error; - - error = (*jvmti)->Deallocate(jvmti, ptr); - check_jvmti_error(jvmti, error, "Cannot deallocate memory"); -} - -/* Allocation of JVMTI managed memory */ -void * -allocate(jvmtiEnv *jvmti, jint len) -{ - jvmtiError error; - void *ptr; - - error = (*jvmti)->Allocate(jvmti, len, (unsigned char **)&ptr); - check_jvmti_error(jvmti, error, "Cannot allocate memory"); - return ptr; -} - -/* Add demo jar file to boot class path (the BCI Tracker class must be - * in the boot classpath) - * - * WARNING: This code assumes that the jar file can be found at one of: - * ${JAVA_HOME}/demo/jvmti/${DEMO_NAME}/${DEMO_NAME}.jar - * ${JAVA_HOME}/../demo/jvmti/${DEMO_NAME}/${DEMO_NAME}.jar - * where JAVA_HOME may refer to the jre directory. - * Both these values are added to the boot classpath. - * These locations are only true for these demos, installed - * in the JDK area. Platform specific code could be used to - * find the location of the DLL or .so library, and construct a - * path name to the jar file, relative to the library location. - */ -void -add_demo_jar_to_bootclasspath(jvmtiEnv *jvmti, char *demo_name) -{ - jvmtiError error; - char *file_sep; - int max_len; - char *java_home; - char jar_path[FILENAME_MAX+1]; - - java_home = NULL; - error = (*jvmti)->GetSystemProperty(jvmti, "java.home", &java_home); - check_jvmti_error(jvmti, error, "Cannot get java.home property value"); - if ( java_home == NULL || java_home[0] == 0 ) { - fatal_error("ERROR: Java home not found\n"); - } - -#ifdef WIN32 - file_sep = "\\"; -#else - file_sep = "/"; -#endif - - max_len = (int)(strlen(java_home) + strlen(demo_name)*2 + - strlen(file_sep)*5 + - 16 /* ".." "demo" "jvmti" ".jar" NULL */ ); - if ( max_len > (int)sizeof(jar_path) ) { - fatal_error("ERROR: Path to jar file too long\n"); - } - (void)strcpy(jar_path, java_home); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, "demo"); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, "jvmti"); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, demo_name); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, demo_name); - (void)strcat(jar_path, ".jar"); - error = (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, (const char*)jar_path); - check_jvmti_error(jvmti, error, "Cannot add to boot classpath"); - - (void)strcpy(jar_path, java_home); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, ".."); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, "demo"); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, "jvmti"); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, demo_name); - (void)strcat(jar_path, file_sep); - (void)strcat(jar_path, demo_name); - (void)strcat(jar_path, ".jar"); - - error = (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, (const char*)jar_path); - check_jvmti_error(jvmti, error, "Cannot add to boot classpath"); -} - -/* ------------------------------------------------------------------- */ diff --git a/jdk/src/demo/share/jvmti/agent_util/agent_util.h b/jdk/src/demo/share/jvmti/agent_util/agent_util.h deleted file mode 100644 index 2237097ab30..00000000000 --- a/jdk/src/demo/share/jvmti/agent_util/agent_util.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef AGENT_UTIL_H -#define AGENT_UTIL_H - -#include -#include -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void stdout_message(const char * format, ...); -void fatal_error(const char * format, ...); -char *get_token(char *str, char *seps, char *buf, int max); -int interested(char *cname, char *mname, - char *include_list, char *exclude_list); - -void check_jvmti_error(jvmtiEnv *jvmti, jvmtiError errnum, const char *str); -void deallocate(jvmtiEnv *jvmti, void *ptr); -void *allocate(jvmtiEnv *jvmti, jint len); -void add_demo_jar_to_bootclasspath(jvmtiEnv *jvmti, char *demo_name); - -#ifdef STATIC_BUILD -/* Macros for handling declaration of static/dynamic - * Agent library Load/Attach/Unload functions - * - * DEF_Agent_OnLoad, DEF_Agent_OnAttach or DEF_Agent_OnUnload - * generate the appropriate entrypoint names based on static - * versus dynamic builds. - * - * STATIC_BUILD must be defined to build static versions of these libraries. - * LIBRARY_NAME must be set to the name of the library for static builds. - */ -#define ADD_LIB_NAME3(name, lib) name ## lib -#define ADD_LIB_NAME2(name, lib) ADD_LIB_NAME3(name, lib) -#define ADD_LIB_NAME(entry) ADD_LIB_NAME2(entry, LIBRARY_NAME) - -#define DEF_Agent_OnLoad \ -ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) \ -{ \ - jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)(JavaVM *vm, char *options, void *reserved); \ - return ADD_LIB_NAME(Agent_OnLoad_dynamic_)(vm, options, reserved); \ -} \ -jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_) - -#define DEF_Agent_OnAttach \ -ADD_LIB_NAME(Agent_OnAttach_)(JavaVM *vm, char *options, void *reserved) \ -{ \ - jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)(JavaVM *vm, char *options, void *reserved); \ - return ADD_LIB_NAME(Agent_OnAttach_dynamic_)(vm, options, reserved); \ -} \ -jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_) - -#define DEF_Agent_OnUnload \ -ADD_LIB_NAME(Agent_OnUnload_)(JavaVM *vm) \ -{ \ - void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)(JavaVM *vm); \ - ADD_LIB_NAME(Agent_OnUnload_dynamic_)(vm); \ -} \ -void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_) - -#else -#define DEF_Agent_OnLoad Agent_OnLoad -#define DEF_Agent_OnAttach Agent_OnAttach -#define DEF_Agent_OnUnload Agent_OnUnload -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif diff --git a/jdk/src/demo/share/jvmti/compiledMethodLoad/README.txt b/jdk/src/demo/share/jvmti/compiledMethodLoad/README.txt deleted file mode 100644 index 3898d29afbc..00000000000 --- a/jdk/src/demo/share/jvmti/compiledMethodLoad/README.txt +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -compiledMethodLoad - -This agent library traces CompiledMethodLoad events along -with the HotSpot specific compile_info parameter. - -You can use this agent library as follows: - - java -agentlib:compiledMethodLoad ... - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - diff --git a/jdk/src/demo/share/jvmti/compiledMethodLoad/compiledMethodLoad.c b/jdk/src/demo/share/jvmti/compiledMethodLoad/compiledMethodLoad.c deleted file mode 100644 index 92d123ea3ce..00000000000 --- a/jdk/src/demo/share/jvmti/compiledMethodLoad/compiledMethodLoad.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" -#include "jvmticmlr.h" - -#include "agent_util.h" - -/* Global static data */ -static char OUTPUT_FILE[] = "compiledMethodLoad.txt"; -static FILE *fp; -static jvmtiEnv *jvmti; -static jrawMonitorID lock; - -/* print a jvmtiCompiledMethodLoadDummyRecord */ -void -print_dummy_record(jvmtiCompiledMethodLoadDummyRecord* record, - jvmtiEnv* jvmti, FILE* fp) { - - if (record != NULL) { - fprintf(fp, "Dummy record detected containing message: %s\n", - (char *)record->message); - } -} - -/* print the specified stack frames */ -void -print_stack_frames(PCStackInfo* record, jvmtiEnv *jvmti, FILE* fp) { - if (record != NULL && record->methods != NULL) { - int i; - - for (i = 0; i < record->numstackframes; i++) { - jvmtiError err; - char* method_name = NULL; - char* class_name = NULL; - char* method_signature = NULL; - char* class_signature = NULL; - char* generic_ptr_method = NULL; - char* generic_ptr_class = NULL; - jmethodID id; - jclass declaringclassptr; - id = record->methods[i]; - - err = (*jvmti)->GetMethodDeclaringClass(jvmti, id, - &declaringclassptr); - check_jvmti_error(jvmti, err, "get method declaring class"); - - err = (*jvmti)->GetClassSignature(jvmti, declaringclassptr, - &class_signature, &generic_ptr_class); - check_jvmti_error(jvmti, err, "get class signature"); - - err = (*jvmti)->GetMethodName(jvmti, id, &method_name, - &method_signature, &generic_ptr_method); - check_jvmti_error(jvmti, err, "get method name"); - - fprintf(fp, "%s::%s %s %s @%d\n", class_signature, method_name, - method_signature, - generic_ptr_method == NULL ? "" : generic_ptr_method, - record->bcis[i]); - - if (method_name != NULL) { - err = (*jvmti)->Deallocate(jvmti, (unsigned char*)method_name); - check_jvmti_error(jvmti, err, "deallocate method_name"); - } - if (method_signature != NULL) { - err = (*jvmti)->Deallocate(jvmti, - (unsigned char*)method_signature); - check_jvmti_error(jvmti, err, "deallocate method_signature"); - } - if (generic_ptr_method != NULL) { - err = (*jvmti)->Deallocate(jvmti, - (unsigned char*)generic_ptr_method); - check_jvmti_error(jvmti, err, "deallocate generic_ptr_method"); - } - if (class_name != NULL) { - err = (*jvmti)->Deallocate(jvmti, (unsigned char*)class_name); - check_jvmti_error(jvmti, err, "deallocate class_name"); - } - if (class_signature != NULL) { - err = (*jvmti)->Deallocate(jvmti, - (unsigned char*)class_signature); - check_jvmti_error(jvmti, err, "deallocate class_signature"); - } - if (generic_ptr_class != NULL) { - err = (*jvmti)->Deallocate(jvmti, - (unsigned char*)generic_ptr_class); - check_jvmti_error(jvmti, err, "deallocate generic_ptr_class"); - } - } - } -} - -/* print a jvmtiCompiledMethodLoadInlineRecord */ -void -print_inline_info_record(jvmtiCompiledMethodLoadInlineRecord* record, - jvmtiEnv *jvmti, FILE* fp) { - - if (record != NULL && record->pcinfo != NULL) { - int numpcs = record->numpcs; - int i; - - for (i = 0; i < numpcs; i++) { - PCStackInfo pcrecord = (record->pcinfo[i]); - fprintf(fp, "PcDescriptor(pc=%p):\n", pcrecord.pc); - print_stack_frames(&pcrecord, jvmti, fp); - } - } -} - -/* decode kind of CompiledMethodLoadRecord and print */ -void -print_records(jvmtiCompiledMethodLoadRecordHeader* list, jvmtiEnv *jvmti, - FILE* fp) -{ - jvmtiCompiledMethodLoadRecordHeader* curr = list; - fprintf(fp, "\nPrinting PC Descriptors\n\n"); - while (curr != NULL) { - switch (curr->kind) { - case JVMTI_CMLR_DUMMY: - print_dummy_record((jvmtiCompiledMethodLoadDummyRecord *)curr, - jvmti, fp); - break; - - case JVMTI_CMLR_INLINE_INFO: - print_inline_info_record( - (jvmtiCompiledMethodLoadInlineRecord *)curr, jvmti, fp); - break; - - default: - fprintf(fp, "Warning: unrecognized record: kind=%d\n", curr->kind); - break; - } - - curr = (jvmtiCompiledMethodLoadRecordHeader *)curr->next; - } -} - -/* Callback for JVMTI_EVENT_COMPILED_METHOD_LOAD */ -void JNICALL -compiled_method_load(jvmtiEnv *jvmti, jmethodID method, jint code_size, - const void* code_addr, jint map_length, const jvmtiAddrLocationMap* map, - const void* compile_info) -{ - jvmtiError err; - char* name = NULL; - char* signature = NULL; - char* generic_ptr = NULL; - jvmtiCompiledMethodLoadRecordHeader* pcs; - - err = (*jvmti)->RawMonitorEnter(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor enter"); - - err = (*jvmti)->GetMethodName(jvmti, method, &name, &signature, - &generic_ptr); - check_jvmti_error(jvmti, err, "get method name"); - - fprintf(fp, "\nCompiled method load event\n"); - fprintf(fp, "Method name %s %s %s\n\n", name, signature, - generic_ptr == NULL ? "" : generic_ptr); - pcs = (jvmtiCompiledMethodLoadRecordHeader *)compile_info; - if (pcs != NULL) { - print_records(pcs, jvmti, fp); - } - - if (name != NULL) { - err = (*jvmti)->Deallocate(jvmti, (unsigned char*)name); - check_jvmti_error(jvmti, err, "deallocate name"); - } - if (signature != NULL) { - err = (*jvmti)->Deallocate(jvmti, (unsigned char*)signature); - check_jvmti_error(jvmti, err, "deallocate signature"); - } - if (generic_ptr != NULL) { - err = (*jvmti)->Deallocate(jvmti, (unsigned char*)generic_ptr); - check_jvmti_error(jvmti, err, "deallocate generic_ptr"); - } - - err = (*jvmti)->RawMonitorExit(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor exit"); -} - -/* Agent_OnLoad() is called first, we prepare for a COMPILED_METHOD_LOAD - * event here. - */ -JNIEXPORT jint JNICALL -DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - jint rc; - jvmtiError err; - jvmtiCapabilities capabilities; - jvmtiEventCallbacks callbacks; - - fp = fopen(OUTPUT_FILE, "w"); - if (fp == NULL) { - fatal_error("ERROR: %s: Unable to create output file\n", OUTPUT_FILE); - return -1; - } - - /* Get JVMTI environment */ - rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION); - if (rc != JNI_OK) { - fatal_error( - "ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc); - return -1; - } - - /* add JVMTI capabilities */ - memset(&capabilities,0, sizeof(capabilities)); - capabilities.can_generate_compiled_method_load_events = 1; - err = (*jvmti)->AddCapabilities(jvmti, &capabilities); - check_jvmti_error(jvmti, err, "add capabilities"); - - /* set JVMTI callbacks for events */ - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.CompiledMethodLoad = &compiled_method_load; - err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); - check_jvmti_error(jvmti, err, "set event callbacks"); - - /* enable JVMTI events */ - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - - /* create coordination monitor */ - err = (*jvmti)->CreateRawMonitor(jvmti, "agent lock", &lock); - check_jvmti_error(jvmti, err, "create raw monitor"); - - return 0; -} - -/* Agent_OnUnload() is called last */ -JNIEXPORT void JNICALL -DEF_Agent_OnUnload(JavaVM *vm) -{ -} diff --git a/jdk/src/demo/share/jvmti/compiledMethodLoad/sample.makefile.txt b/jdk/src/demo/share/jvmti/compiledMethodLoad/sample.makefile.txt deleted file mode 100644 index 3da8383d912..00000000000 --- a/jdk/src/demo/share/jvmti/compiledMethodLoad/sample.makefile.txt +++ /dev/null @@ -1,148 +0,0 @@ -# -# Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo compiledMethodLoad -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=compiledMethodLoad -SOURCES=compiledMethodLoad.c ../agent_util/agent_util.c - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES= -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES= - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I../agent_util -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule -all: $(LIBRARY) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Cleanup the built bits -clean: - rm -f $(LIBRARY) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=`pwd` $(JDK)/bin/java -agentlib:$(LIBNAME) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/gctest/README.txt b/jdk/src/demo/share/jvmti/gctest/README.txt deleted file mode 100644 index 1d23b8fa339..00000000000 --- a/jdk/src/demo/share/jvmti/gctest/README.txt +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -gctest - -This agent library can be used to track garbage collection events. - -You can use this agent library as follows: - - java -agentlib:gctest ... - -To get help on the available options try: - - java -agentlib:gctest=help - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - -The Events JVMTI_EVENT_GARBAGE_COLLECTION_START, -JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, and JVMTI_EVENT_OBJECT_FREE -all have limitations as to what can be called directly inside the -agent callback functions (e.g. no JNI calls are allowed, and limited -interface calls can be made). However, by using raw monitors and a separate -watcher thread, this agent demonstrates how these limitations can be -easily avoided, allowing the watcher thread to do just about anything -after the JVMTI_EVENT_GARBAGE_COLLECTION_FINISH event. - diff --git a/jdk/src/demo/share/jvmti/gctest/gctest.c b/jdk/src/demo/share/jvmti/gctest/gctest.c deleted file mode 100644 index 848e7e07c1a..00000000000 --- a/jdk/src/demo/share/jvmti/gctest/gctest.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Example of using JVMTI_EVENT_GARBAGE_COLLECTION_START and - * JVMTI_EVENT_GARBAGE_COLLECTION_FINISH events. - */ - -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -/* For stdout_message(), fatal_error(), and check_jvmti_error() */ -#include "agent_util.h" - -/* Global static data */ -static jvmtiEnv *jvmti; -static int gc_count; -static jrawMonitorID lock; - -/* Worker thread that waits for garbage collections */ -static void JNICALL -worker(jvmtiEnv* jvmti, JNIEnv* jni, void *p) -{ - jvmtiError err; - - stdout_message("GC worker started...\n"); - - for (;;) { - err = (*jvmti)->RawMonitorEnter(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor enter"); - while (gc_count == 0) { - err = (*jvmti)->RawMonitorWait(jvmti, lock, 0); - if (err != JVMTI_ERROR_NONE) { - err = (*jvmti)->RawMonitorExit(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor wait"); - return; - } - } - gc_count = 0; - - err = (*jvmti)->RawMonitorExit(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor exit"); - - /* Perform arbitrary JVMTI/JNI work here to do post-GC cleanup */ - stdout_message("post-GarbageCollectionFinish actions...\n"); - } -} - -/* Creates a new jthread */ -static jthread -alloc_thread(JNIEnv *env) -{ - jclass thrClass; - jmethodID cid; - jthread res; - - thrClass = (*env)->FindClass(env, "java/lang/Thread"); - if ( thrClass == NULL ) { - fatal_error("Cannot find Thread class\n"); - } - cid = (*env)->GetMethodID(env, thrClass, "", "()V"); - if ( cid == NULL ) { - fatal_error("Cannot find Thread constructor method\n"); - } - res = (*env)->NewObject(env, thrClass, cid); - if ( res == NULL ) { - fatal_error("Cannot create new Thread object\n"); - } - return res; -} - -/* Callback for JVMTI_EVENT_VM_INIT */ -static void JNICALL -vm_init(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - jvmtiError err; - - stdout_message("VMInit...\n"); - - err = (*jvmti)->RunAgentThread(jvmti, alloc_thread(env), &worker, NULL, - JVMTI_THREAD_MAX_PRIORITY); - check_jvmti_error(jvmti, err, "running agent thread"); -} - -/* Callback for JVMTI_EVENT_GARBAGE_COLLECTION_START */ -static void JNICALL -gc_start(jvmtiEnv* jvmti_env) -{ - stdout_message("GarbageCollectionStart...\n"); -} - -/* Callback for JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */ -static void JNICALL -gc_finish(jvmtiEnv* jvmti_env) -{ - jvmtiError err; - - stdout_message("GarbageCollectionFinish...\n"); - - err = (*jvmti)->RawMonitorEnter(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor enter"); - gc_count++; - err = (*jvmti)->RawMonitorNotify(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor notify"); - err = (*jvmti)->RawMonitorExit(jvmti, lock); - check_jvmti_error(jvmti, err, "raw monitor exit"); -} - -/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */ -JNIEXPORT jint JNICALL -DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - jint rc; - jvmtiError err; - jvmtiCapabilities capabilities; - jvmtiEventCallbacks callbacks; - - /* Get JVMTI environment */ - rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION); - if (rc != JNI_OK) { - fatal_error("ERROR: Unable to create jvmtiEnv, rc=%d\n", rc); - return -1; - } - - /* Get/Add JVMTI capabilities */ - (void)memset(&capabilities, 0, sizeof(capabilities)); - capabilities.can_generate_garbage_collection_events = 1; - err = (*jvmti)->AddCapabilities(jvmti, &capabilities); - check_jvmti_error(jvmti, err, "add capabilities"); - - /* Set callbacks and enable event notifications */ - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.VMInit = &vm_init; - callbacks.GarbageCollectionStart = &gc_start; - callbacks.GarbageCollectionFinish = &gc_finish; - err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); - check_jvmti_error(jvmti, err, "set event callbacks"); - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, NULL); - check_jvmti_error(jvmti, err, "set event notification"); - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL); - check_jvmti_error(jvmti, err, "set event notification"); - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL); - check_jvmti_error(jvmti, err, "set event notification"); - - /* Create the necessary raw monitor */ - err = (*jvmti)->CreateRawMonitor(jvmti, "lock", &lock); - check_jvmti_error(jvmti, err, "create raw monitor"); - return 0; -} - -/* Agent_OnUnload() is called last */ -JNIEXPORT void JNICALL -DEF_Agent_OnUnload(JavaVM *vm) -{ -} diff --git a/jdk/src/demo/share/jvmti/gctest/sample.makefile.txt b/jdk/src/demo/share/jvmti/gctest/sample.makefile.txt deleted file mode 100644 index 46afeb498ce..00000000000 --- a/jdk/src/demo/share/jvmti/gctest/sample.makefile.txt +++ /dev/null @@ -1,148 +0,0 @@ -# -# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo gctest -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=gctest -SOURCES=gctest.c ../agent_util/agent_util.c - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES= -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES= - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I../agent_util -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule -all: $(LIBRARY) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Cleanup the built bits -clean: - rm -f $(LIBRARY) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=`pwd` $(JDK)/bin/java -agentlib:$(LIBNAME) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/heapTracker/HeapTracker.java b/jdk/src/demo/share/jvmti/heapTracker/HeapTracker.java deleted file mode 100644 index a7eb362cd20..00000000000 --- a/jdk/src/demo/share/jvmti/heapTracker/HeapTracker.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - - -/* Java class to hold static methods which will be called in byte code - * injections of all class files. - */ - -public class HeapTracker { - - private static int engaged = 0; - - private static native void _newobj(Object thread, Object o); - public static void newobj(Object o) - { - if ( engaged != 0 ) { - _newobj(Thread.currentThread(), o); - } - } - - private static native void _newarr(Object thread, Object a); - public static void newarr(Object a) - { - if ( engaged != 0 ) { - _newarr(Thread.currentThread(), a); - } - } - -} diff --git a/jdk/src/demo/share/jvmti/heapTracker/README.txt b/jdk/src/demo/share/jvmti/heapTracker/README.txt deleted file mode 100644 index cb7aac359b9..00000000000 --- a/jdk/src/demo/share/jvmti/heapTracker/README.txt +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -heapTracker - -This agent library can be used to track object allocations. -It uses the same java_crw_demo library used by HPROF to do BCI -on all classfiles loaded into the Virtual Machine. - -You can use this agent library as follows: - - java -agentlib:heapTracker ... - -To get help on the available options try: - - java -agentlib:heapTracker=help - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - diff --git a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.c b/jdk/src/demo/share/jvmti/heapTracker/heapTracker.c deleted file mode 100644 index 3af21846245..00000000000 --- a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include "stdlib.h" - -#include "heapTracker.h" -#include "java_crw_demo.h" - -#include "jni.h" -#include "jvmti.h" - -#include "agent_util.h" - -/* ------------------------------------------------------------------- - * Some constant names that tie to Java class/method names. - * We assume the Java class whose static methods we will be calling - * looks like: - * - * public class HeapTracker { - * private static int engaged; - * private static native void _newobj(Object thr, Object o); - * public static void newobj(Object o) - * { - * if ( engaged != 0 ) { - * _newobj(Thread.currentThread(), o); - * } - * } - * private static native void _newarr(Object thr, Object a); - * public static void newarr(Object a) - * { - * if ( engaged != 0 ) { - * _newarr(Thread.currentThread(), a); - * } - * } - * } - * - * The engaged field allows us to inject all classes (even system classes) - * and delay the actual calls to the native code until the VM has reached - * a safe time to call native methods (Past the JVMTI VM_START event). - * - */ - -#define HEAP_TRACKER_class HeapTracker /* Name of class we are using */ -#define HEAP_TRACKER_newobj newobj /* Name of java init method */ -#define HEAP_TRACKER_newarr newarr /* Name of java newarray method */ -#define HEAP_TRACKER_native_newobj _newobj /* Name of java newobj native */ -#define HEAP_TRACKER_native_newarr _newarr /* Name of java newarray native */ -#define HEAP_TRACKER_engaged engaged /* Name of static field switch */ - -/* C macros to create strings from tokens */ -#define _STRING(s) #s -#define STRING(s) _STRING(s) - -/* ------------------------------------------------------------------- */ - -/* Flavors of traces (to separate out stack traces) */ - -typedef enum { - TRACE_FIRST = 0, - TRACE_USER = 0, - TRACE_BEFORE_VM_START = 1, - TRACE_BEFORE_VM_INIT = 2, - TRACE_VM_OBJECT = 3, - TRACE_MYSTERY = 4, - TRACE_LAST = 4 -} TraceFlavor; - -static char * flavorDesc[] = { - "", - "before VM_START", - "before VM_INIT", - "VM_OBJECT", - "unknown" -}; - -/* Trace (Stack Trace) */ - -#define MAX_FRAMES 6 -typedef struct Trace { - /* Number of frames (includes HEAP_TRACKER methods) */ - jint nframes; - /* Frames from GetStackTrace() (2 extra for HEAP_TRACKER methods) */ - jvmtiFrameInfo frames[MAX_FRAMES+2]; - /* Used to make some traces unique */ - TraceFlavor flavor; -} Trace; - -/* Trace information (more than one object will have this as a tag) */ - -typedef struct TraceInfo { - /* Trace where this object was allocated from */ - Trace trace; - /* 64 bit hash code that attempts to identify this specific trace */ - jlong hashCode; - /* Total space taken up by objects allocated from this trace */ - jlong totalSpace; - /* Total count of objects ever allocated from this trace */ - int totalCount; - /* Total live objects that were allocated from this trace */ - int useCount; - /* The next TraceInfo in the hash bucket chain */ - struct TraceInfo *next; -} TraceInfo; - -/* Global agent data structure */ - -typedef struct { - /* JVMTI Environment */ - jvmtiEnv *jvmti; - /* State of the VM flags */ - jboolean vmStarted; - jboolean vmInitialized; - jboolean vmDead; - /* Options */ - int maxDump; - /* Data access Lock */ - jrawMonitorID lock; - /* Counter on classes where BCI has been applied */ - jint ccount; - /* Hash table to lookup TraceInfo's via Trace's */ - #define HASH_INDEX_BIT_WIDTH 12 /* 4096 */ - #define HASH_BUCKET_COUNT (1<RawMonitorEnter(jvmti, gdata->lock); - check_jvmti_error(jvmti, error, "Cannot enter with raw monitor"); -} - -/* Exit a critical section by doing a JVMTI Raw Monitor Exit */ -static void -exitCriticalSection(jvmtiEnv *jvmti) -{ - jvmtiError error; - - error = (*jvmti)->RawMonitorExit(jvmti, gdata->lock); - check_jvmti_error(jvmti, error, "Cannot exit with raw monitor"); -} - -/* Update stats on a TraceInfo */ -static TraceInfo * -updateStats(TraceInfo *tinfo) -{ - tinfo->totalCount++; - tinfo->useCount++; - return tinfo; -} - -/* Get TraceInfo for empty stack */ -static TraceInfo * -emptyTrace(TraceFlavor flavor) -{ - return updateStats(gdata->emptyTrace[flavor]); -} - -/* Allocate new TraceInfo */ -static TraceInfo * -newTraceInfo(Trace *trace, jlong hashCode, TraceFlavor flavor) -{ - TraceInfo *tinfo; - - tinfo = (TraceInfo*)calloc(1, sizeof(TraceInfo)); - if ( tinfo == NULL ) { - fatal_error("ERROR: Ran out of malloc() space\n"); - } else { - int hashIndex; - - tinfo->trace = *trace; - tinfo->trace.flavor = flavor; - tinfo->hashCode = hashCode; - gdata->traceInfoCount++; - hashIndex = (int)(hashCode & HASH_INDEX_MASK); - tinfo->next = gdata->hashBuckets[hashIndex]; - gdata->hashBuckets[hashIndex] = tinfo; - } - return tinfo; -} - -/* Create hash code for a Trace */ -static jlong -hashTrace(Trace *trace) -{ - jlong hashCode; - int i; - - hashCode = 0; - for ( i = 0 ; i < trace->nframes ; i++ ) { - hashCode = (hashCode << 3) + - (jlong)(ptrdiff_t)(void*)(trace->frames[i].method); - hashCode = (hashCode << 2) + - (jlong)(trace->frames[i].location); - } - hashCode = (hashCode << 3) + trace->nframes; - hashCode += trace->flavor; - return hashCode; -} - -/* Lookup or create a new TraceInfo */ -static TraceInfo * -lookupOrEnter(jvmtiEnv *jvmti, Trace *trace, TraceFlavor flavor) -{ - TraceInfo *tinfo; - jlong hashCode; - - /* Calculate hash code (outside critical section to lessen contention) */ - hashCode = hashTrace(trace); - - /* Do a lookup in the hash table */ - enterCriticalSection(jvmti); { - TraceInfo *prev; - int hashIndex; - - /* Start with first item in hash buck chain */ - prev = NULL; - hashIndex = (int)(hashCode & HASH_INDEX_MASK); - tinfo = gdata->hashBuckets[hashIndex]; - while ( tinfo != NULL ) { - if ( tinfo->hashCode == hashCode && - memcmp(trace, &(tinfo->trace), sizeof(Trace))==0 ) { - /* We found one that matches, move to head of bucket chain */ - if ( prev != NULL ) { - /* Remove from list and add to head of list */ - prev->next = tinfo->next; - tinfo->next = gdata->hashBuckets[hashIndex]; - gdata->hashBuckets[hashIndex] = tinfo; - } - /* Break out */ - break; - } - prev = tinfo; - tinfo = tinfo->next; - } - - /* If we didn't find anything we need to enter a new entry */ - if ( tinfo == NULL ) { - /* Create new hash table element */ - tinfo = newTraceInfo(trace, hashCode, flavor); - } - - /* Update stats */ - (void)updateStats(tinfo); - - } exitCriticalSection(jvmti); - - return tinfo; -} - -/* Get TraceInfo for this allocation */ -static TraceInfo * -findTraceInfo(jvmtiEnv *jvmti, jthread thread, TraceFlavor flavor) -{ - TraceInfo *tinfo; - jvmtiError error; - - tinfo = NULL; - if ( thread != NULL ) { - static Trace empty; - Trace trace; - - /* Before VM_INIT thread could be NULL, watch out */ - trace = empty; - error = (*jvmti)->GetStackTrace(jvmti, thread, 0, MAX_FRAMES+2, - trace.frames, &(trace.nframes)); - /* If we get a PHASE error, the VM isn't ready, or it died */ - if ( error == JVMTI_ERROR_WRONG_PHASE ) { - /* It is assumed this is before VM_INIT */ - if ( flavor == TRACE_USER ) { - tinfo = emptyTrace(TRACE_BEFORE_VM_INIT); - } else { - tinfo = emptyTrace(flavor); - } - } else { - check_jvmti_error(jvmti, error, "Cannot get stack trace"); - /* Lookup this entry */ - tinfo = lookupOrEnter(jvmti, &trace, flavor); - } - } else { - /* If thread==NULL, it's assumed this is before VM_START */ - if ( flavor == TRACE_USER ) { - tinfo = emptyTrace(TRACE_BEFORE_VM_START); - } else { - tinfo = emptyTrace(flavor); - } - } - return tinfo; -} - -/* Tag an object with a TraceInfo pointer. */ -static void -tagObjectWithTraceInfo(jvmtiEnv *jvmti, jobject object, TraceInfo *tinfo) -{ - jvmtiError error; - jlong tag; - - /* Tag this object with this TraceInfo pointer */ - tag = (jlong)(ptrdiff_t)(void*)tinfo; - error = (*jvmti)->SetTag(jvmti, object, tag); - check_jvmti_error(jvmti, error, "Cannot tag object"); -} - -/* Java Native Method for Object. */ -static void JNICALL -HEAP_TRACKER_native_newobj(JNIEnv *env, jclass klass, jthread thread, jobject o) -{ - TraceInfo *tinfo; - - if ( gdata->vmDead ) { - return; - } - tinfo = findTraceInfo(gdata->jvmti, thread, TRACE_USER); - tagObjectWithTraceInfo(gdata->jvmti, o, tinfo); -} - -/* Java Native Method for newarray */ -static void JNICALL -HEAP_TRACKER_native_newarr(JNIEnv *env, jclass klass, jthread thread, jobject a) -{ - TraceInfo *tinfo; - - if ( gdata->vmDead ) { - return; - } - tinfo = findTraceInfo(gdata->jvmti, thread, TRACE_USER); - tagObjectWithTraceInfo(gdata->jvmti, a, tinfo); -} - -/* Callback for JVMTI_EVENT_VM_START */ -static void JNICALL -cbVMStart(jvmtiEnv *jvmti, JNIEnv *env) -{ - enterCriticalSection(jvmti); { - jclass klass; - jfieldID field; - jint rc; - - /* Java Native Methods for class */ - static JNINativeMethod registry[2] = { - {STRING(HEAP_TRACKER_native_newobj), "(Ljava/lang/Object;Ljava/lang/Object;)V", - (void*)&HEAP_TRACKER_native_newobj}, - {STRING(HEAP_TRACKER_native_newarr), "(Ljava/lang/Object;Ljava/lang/Object;)V", - (void*)&HEAP_TRACKER_native_newarr} - }; - - /* Register Natives for class whose methods we use */ - klass = (*env)->FindClass(env, STRING(HEAP_TRACKER_class)); - if ( klass == NULL ) { - fatal_error("ERROR: JNI: Cannot find %s with FindClass\n", - STRING(HEAP_TRACKER_class)); - } - rc = (*env)->RegisterNatives(env, klass, registry, 2); - if ( rc != 0 ) { - fatal_error("ERROR: JNI: Cannot register natives for class %s\n", - STRING(HEAP_TRACKER_class)); - } - - /* Engage calls. */ - field = (*env)->GetStaticFieldID(env, klass, STRING(HEAP_TRACKER_engaged), "I"); - if ( field == NULL ) { - fatal_error("ERROR: JNI: Cannot get field from %s\n", - STRING(HEAP_TRACKER_class)); - } - (*env)->SetStaticIntField(env, klass, field, 1); - - /* Indicate VM has started */ - gdata->vmStarted = JNI_TRUE; - - } exitCriticalSection(jvmti); -} - -/* Iterate Through Heap callback */ -static jint JNICALL -cbObjectTagger(jlong class_tag, jlong size, jlong* tag_ptr, jint length, - void *user_data) -{ - TraceInfo *tinfo; - - tinfo = emptyTrace(TRACE_BEFORE_VM_INIT); - *tag_ptr = (jlong)(ptrdiff_t)(void*)tinfo; - return JVMTI_VISIT_OBJECTS; -} - -/* Callback for JVMTI_EVENT_VM_INIT */ -static void JNICALL -cbVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - jvmtiHeapCallbacks heapCallbacks; - jvmtiError error; - - /* Iterate through heap, find all untagged objects allocated before this */ - (void)memset(&heapCallbacks, 0, sizeof(heapCallbacks)); - heapCallbacks.heap_iteration_callback = &cbObjectTagger; - error = (*jvmti)->IterateThroughHeap(jvmti, JVMTI_HEAP_FILTER_TAGGED, - NULL, &heapCallbacks, NULL); - check_jvmti_error(jvmti, error, "Cannot iterate through heap"); - - enterCriticalSection(jvmti); { - - /* Indicate VM is initialized */ - gdata->vmInitialized = JNI_TRUE; - - } exitCriticalSection(jvmti); -} - -/* Iterate Through Heap callback */ -static jint JNICALL -cbObjectSpaceCounter(jlong class_tag, jlong size, jlong* tag_ptr, jint length, - void *user_data) -{ - TraceInfo *tinfo; - - tinfo = (TraceInfo*)(ptrdiff_t)(*tag_ptr); - if ( tinfo == NULL ) { - tinfo = emptyTrace(TRACE_MYSTERY); - *tag_ptr = (jlong)(ptrdiff_t)(void*)tinfo; - } - tinfo->totalSpace += size; - return JVMTI_VISIT_OBJECTS; -} - -/* Qsort compare function */ -static int -compareInfo(const void *p1, const void *p2) -{ - TraceInfo *tinfo1, *tinfo2; - - tinfo1 = *((TraceInfo**)p1); - tinfo2 = *((TraceInfo**)p2); - return (int)(tinfo2->totalSpace - tinfo1->totalSpace); -} - -/* Frame to text */ -static void -frameToString(jvmtiEnv *jvmti, char *buf, int buflen, jvmtiFrameInfo *finfo) -{ - jvmtiError error; - jclass klass; - char *signature; - char *methodname; - char *methodsig; - jboolean isNative; - char *filename; - int lineCount; - jvmtiLineNumberEntry*lineTable; - int lineNumber; - - /* Initialize defaults */ - buf[0] = 0; - klass = NULL; - signature = NULL; - methodname = NULL; - methodsig = NULL; - isNative = JNI_FALSE; - filename = NULL; - lineCount = 0; - lineTable = NULL; - lineNumber = 0; - - /* Get jclass object for the jmethodID */ - error = (*jvmti)->GetMethodDeclaringClass(jvmti, finfo->method, &klass); - check_jvmti_error(jvmti, error, "Cannot get method's class"); - - /* Get the class signature */ - error = (*jvmti)->GetClassSignature(jvmti, klass, &signature, NULL); - check_jvmti_error(jvmti, error, "Cannot get class signature"); - - /* Skip all this if it's our own Tracker method */ - if ( strcmp(signature, "L" STRING(HEAP_TRACKER_class) ";" ) == 0 ) { - deallocate(jvmti, signature); - return; - } - - /* Get the name and signature for the method */ - error = (*jvmti)->GetMethodName(jvmti, finfo->method, - &methodname, &methodsig, NULL); - check_jvmti_error(jvmti, error, "Cannot method name"); - - /* Check to see if it's a native method, which means no lineNumber */ - error = (*jvmti)->IsMethodNative(jvmti, finfo->method, &isNative); - check_jvmti_error(jvmti, error, "Cannot get method native status"); - - /* Get source file name */ - error = (*jvmti)->GetSourceFileName(jvmti, klass, &filename); - if ( error != JVMTI_ERROR_NONE && error != JVMTI_ERROR_ABSENT_INFORMATION ) { - check_jvmti_error(jvmti, error, "Cannot get source filename"); - } - - /* Get lineNumber if we can */ - if ( !isNative ) { - int i; - - /* Get method line table */ - error = (*jvmti)->GetLineNumberTable(jvmti, finfo->method, &lineCount, &lineTable); - if ( error == JVMTI_ERROR_NONE ) { - /* Search for line */ - lineNumber = lineTable[0].line_number; - for ( i = 1 ; i < lineCount ; i++ ) { - if ( finfo->location < lineTable[i].start_location ) { - break; - } - lineNumber = lineTable[i].line_number; - } - } else if ( error != JVMTI_ERROR_ABSENT_INFORMATION ) { - check_jvmti_error(jvmti, error, "Cannot get method line table"); - } - } - - /* Create string for this frame location. - * NOTE: These char* quantities are mUTF (Modified UTF-8) bytes - * and should actually be converted to the default system - * character encoding. Sending them to things like - * printf() without converting them is actually an I18n - * (Internationalization) error. - */ - (void)sprintf(buf, "%s.%s@%d[%s:%d]", - (signature==NULL?"UnknownClass":signature), - (methodname==NULL?"UnknownMethod":methodname), - (int)finfo->location, - (filename==NULL?"UnknownFile":filename), - lineNumber); - - /* Free up JVMTI space allocated by the above calls */ - deallocate(jvmti, signature); - deallocate(jvmti, methodname); - deallocate(jvmti, methodsig); - deallocate(jvmti, filename); - deallocate(jvmti, lineTable); -} - -/* Print the information */ -static void -printTraceInfo(jvmtiEnv *jvmti, int index, TraceInfo* tinfo) -{ - if ( tinfo == NULL ) { - fatal_error("%d: NULL ENTRY ERROR\n", index); - return; - } - - stdout_message("%2d: %7d bytes %5d objects %5d live %s", - index, (int)tinfo->totalSpace, tinfo->totalCount, - tinfo->useCount, flavorDesc[tinfo->trace.flavor]); - - if ( tinfo->trace.nframes > 0 ) { - int i; - int fcount; - - fcount = 0; - stdout_message(" stack=("); - for ( i = 0 ; i < tinfo->trace.nframes ; i++ ) { - char buf[4096]; - - frameToString(jvmti, buf, (int)sizeof(buf), tinfo->trace.frames+i); - if ( buf[0] == 0 ) { - continue; /* Skip the ones that are from Tracker class */ - } - fcount++; - stdout_message("%s", buf); - if ( i < (tinfo->trace.nframes-1) ) { - stdout_message(","); - } - } - stdout_message(") nframes=%d\n", fcount); - } else { - stdout_message(" stack=\n"); - } -} - -/* Callback for JVMTI_EVENT_VM_DEATH */ -static void JNICALL -cbVMDeath(jvmtiEnv *jvmti, JNIEnv *env) -{ - jvmtiHeapCallbacks heapCallbacks; - jvmtiError error; - - /* These are purposely done outside the critical section */ - - /* Force garbage collection now so we get our ObjectFree calls */ - error = (*jvmti)->ForceGarbageCollection(jvmti); - check_jvmti_error(jvmti, error, "Cannot force garbage collection"); - - /* Iterate through heap and find all objects */ - (void)memset(&heapCallbacks, 0, sizeof(heapCallbacks)); - heapCallbacks.heap_iteration_callback = &cbObjectSpaceCounter; - error = (*jvmti)->IterateThroughHeap(jvmti, 0, NULL, &heapCallbacks, NULL); - check_jvmti_error(jvmti, error, "Cannot iterate through heap"); - - /* Process VM Death */ - enterCriticalSection(jvmti); { - jclass klass; - jfieldID field; - jvmtiEventCallbacks callbacks; - - /* Disengage calls in HEAP_TRACKER_class. */ - klass = (*env)->FindClass(env, STRING(HEAP_TRACKER_class)); - if ( klass == NULL ) { - fatal_error("ERROR: JNI: Cannot find %s with FindClass\n", - STRING(HEAP_TRACKER_class)); - } - field = (*env)->GetStaticFieldID(env, klass, STRING(HEAP_TRACKER_engaged), "I"); - if ( field == NULL ) { - fatal_error("ERROR: JNI: Cannot get field from %s\n", - STRING(HEAP_TRACKER_class)); - } - (*env)->SetStaticIntField(env, klass, field, 0); - - /* The critical section here is important to hold back the VM death - * until all other callbacks have completed. - */ - - /* Clear out all callbacks. */ - (void)memset(&callbacks,0, sizeof(callbacks)); - error = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, - (jint)sizeof(callbacks)); - check_jvmti_error(jvmti, error, "Cannot set jvmti callbacks"); - - /* Since this critical section could be holding up other threads - * in other event callbacks, we need to indicate that the VM is - * dead so that the other callbacks can short circuit their work. - * We don't expect an further events after VmDeath but we do need - * to be careful that existing threads might be in our own agent - * callback code. - */ - gdata->vmDead = JNI_TRUE; - - /* Dump all objects */ - if ( gdata->traceInfoCount > 0 ) { - TraceInfo **list; - int count; - int i; - - stdout_message("Dumping heap trace information\n"); - - /* Create single array of pointers to TraceInfo's, sort, and - * print top gdata->maxDump top space users. - */ - list = (TraceInfo**)calloc(gdata->traceInfoCount, - sizeof(TraceInfo*)); - if ( list == NULL ) { - fatal_error("ERROR: Ran out of malloc() space\n"); - } - count = 0; - for ( i = 0 ; i < HASH_BUCKET_COUNT ; i++ ) { - TraceInfo *tinfo; - - tinfo = gdata->hashBuckets[i]; - while ( tinfo != NULL ) { - if ( count < gdata->traceInfoCount ) { - list[count++] = tinfo; - } - tinfo = tinfo->next; - } - } - if ( count != gdata->traceInfoCount ) { - fatal_error("ERROR: Count found by iterate doesn't match ours:" - " count=%d != traceInfoCount==%d\n", - count, gdata->traceInfoCount); - } - qsort(list, count, sizeof(TraceInfo*), &compareInfo); - for ( i = 0 ; i < count ; i++ ) { - if ( i >= gdata->maxDump ) { - break; - } - printTraceInfo(jvmti, i+1, list[i]); - } - (void)free(list); - } - - } exitCriticalSection(jvmti); - -} - -/* Callback for JVMTI_EVENT_VM_OBJECT_ALLOC */ -static void JNICALL -cbVMObjectAlloc(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, - jobject object, jclass object_klass, jlong size) -{ - TraceInfo *tinfo; - - if ( gdata->vmDead ) { - return; - } - tinfo = findTraceInfo(jvmti, thread, TRACE_VM_OBJECT); - tagObjectWithTraceInfo(jvmti, object, tinfo); -} - -/* Callback for JVMTI_EVENT_OBJECT_FREE */ -static void JNICALL -cbObjectFree(jvmtiEnv *jvmti, jlong tag) -{ - TraceInfo *tinfo; - - if ( gdata->vmDead ) { - return; - } - - /* The object tag is actually a pointer to a TraceInfo structure */ - tinfo = (TraceInfo*)(void*)(ptrdiff_t)tag; - - /* Decrement the use count */ - tinfo->useCount--; -} - -/* Callback for JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */ -static void JNICALL -cbClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv* env, - jclass class_being_redefined, jobject loader, - const char* name, jobject protection_domain, - jint class_data_len, const unsigned char* class_data, - jint* new_class_data_len, unsigned char** new_class_data) -{ - enterCriticalSection(jvmti); { - /* It's possible we get here right after VmDeath event, be careful */ - if ( !gdata->vmDead ) { - - const char * classname; - - /* Name can be NULL, make sure we avoid SEGV's */ - if ( name == NULL ) { - classname = java_crw_demo_classname(class_data, class_data_len, - NULL); - if ( classname == NULL ) { - fatal_error("ERROR: No classname in classfile\n"); - } - } else { - classname = strdup(name); - if ( classname == NULL ) { - fatal_error("ERROR: Ran out of malloc() space\n"); - } - } - - *new_class_data_len = 0; - *new_class_data = NULL; - - /* The tracker class itself? */ - if ( strcmp(classname, STRING(HEAP_TRACKER_class)) != 0 ) { - jint cnum; - int systemClass; - unsigned char *newImage; - long newLength; - - /* Get number for every class file image loaded */ - cnum = gdata->ccount++; - - /* Is it a system class? If the class load is before VmStart - * then we will consider it a system class that should - * be treated carefully. (See java_crw_demo) - */ - systemClass = 0; - if ( !gdata->vmStarted ) { - systemClass = 1; - } - - newImage = NULL; - newLength = 0; - - /* Call the class file reader/write demo code */ - java_crw_demo(cnum, - classname, - class_data, - class_data_len, - systemClass, - STRING(HEAP_TRACKER_class), - "L" STRING(HEAP_TRACKER_class) ";", - NULL, NULL, - NULL, NULL, - STRING(HEAP_TRACKER_newobj), "(Ljava/lang/Object;)V", - STRING(HEAP_TRACKER_newarr), "(Ljava/lang/Object;)V", - &newImage, - &newLength, - NULL, - NULL); - - /* If we got back a new class image, return it back as "the" - * new class image. This must be JVMTI Allocate space. - */ - if ( newLength > 0 ) { - unsigned char *jvmti_space; - - jvmti_space = (unsigned char *)allocate(jvmti, (jint)newLength); - (void)memcpy((void*)jvmti_space, (void*)newImage, (int)newLength); - *new_class_data_len = (jint)newLength; - *new_class_data = jvmti_space; /* VM will deallocate */ - } - - /* Always free up the space we get from java_crw_demo() */ - if ( newImage != NULL ) { - (void)free((void*)newImage); /* Free malloc() space with free() */ - } - } - - (void)free((void*)classname); - } - } exitCriticalSection(jvmti); -} - -/* Parse the options for this heapTracker agent */ -static void -parse_agent_options(char *options) -{ - #define MAX_TOKEN_LENGTH 16 - char token[MAX_TOKEN_LENGTH]; - char *next; - - /* Defaults */ - gdata->maxDump = 20; - - /* Parse options and set flags in gdata */ - if ( options==NULL ) { - return; - } - - /* Get the first token from the options string. */ - next = get_token(options, ",=", token, (int)sizeof(token)); - - /* While not at the end of the options string, process this option. */ - while ( next != NULL ) { - if ( strcmp(token,"help")==0 ) { - stdout_message("The heapTracker JVMTI demo agent\n"); - stdout_message("\n"); - stdout_message(" java -agent:heapTracker[=options] ...\n"); - stdout_message("\n"); - stdout_message("The options are comma separated:\n"); - stdout_message("\t help\t\t\t Print help information\n"); - stdout_message("\t maxDump=n\t\t\t How many TraceInfo's to dump\n"); - stdout_message("\n"); - exit(0); - } else if ( strcmp(token,"maxDump")==0 ) { - char number[MAX_TOKEN_LENGTH]; - - next = get_token(next, ",=", number, (int)sizeof(number)); - if ( next == NULL ) { - fatal_error("ERROR: Cannot parse maxDump=number: %s\n", options); - } - gdata->maxDump = atoi(number); - } else if ( token[0]!=0 ) { - /* We got a non-empty token and we don't know what it is. */ - fatal_error("ERROR: Unknown option: %s\n", token); - } - /* Get the next token (returns NULL if there are no more) */ - next = get_token(next, ",=", token, (int)sizeof(token)); - } -} - -/* Agent_OnLoad: This is called immediately after the shared library is - * loaded. This is the first code executed. - */ -JNIEXPORT jint JNICALL -DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - static GlobalAgentData data; - jvmtiEnv *jvmti; - jvmtiError error; - jint res; - TraceFlavor flavor; - jvmtiCapabilities capabilities; - jvmtiEventCallbacks callbacks; - static Trace empty; - - /* Setup initial global agent data area - * Use of static/extern data should be handled carefully here. - * We need to make sure that we are able to cleanup after ourselves - * so anything allocated in this library needs to be freed in - * the Agent_OnUnload() function. - */ - (void)memset((void*)&data, 0, sizeof(data)); - gdata = &data; - - /* First thing we need to do is get the jvmtiEnv* or JVMTI environment */ - res = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1); - if (res != JNI_OK) { - /* This means that the VM was unable to obtain this version of the - * JVMTI interface, this is a fatal error. - */ - fatal_error("ERROR: Unable to access JVMTI Version 1 (0x%x)," - " is your JDK a 5.0 or newer version?" - " JNIEnv's GetEnv() returned %d\n", - JVMTI_VERSION_1, res); - } - - /* Here we save the jvmtiEnv* for Agent_OnUnload(). */ - gdata->jvmti = jvmti; - - /* Parse any options supplied on java command line */ - parse_agent_options(options); - - /* Immediately after getting the jvmtiEnv* we need to ask for the - * capabilities this agent will need. - */ - (void)memset(&capabilities,0, sizeof(capabilities)); - capabilities.can_generate_all_class_hook_events = 1; - capabilities.can_tag_objects = 1; - capabilities.can_generate_object_free_events = 1; - capabilities.can_get_source_file_name = 1; - capabilities.can_get_line_numbers = 1; - capabilities.can_generate_vm_object_alloc_events = 1; - error = (*jvmti)->AddCapabilities(jvmti, &capabilities); - check_jvmti_error(jvmti, error, "Unable to get necessary JVMTI capabilities."); - - /* Next we need to provide the pointers to the callback functions to - * to this jvmtiEnv* - */ - (void)memset(&callbacks,0, sizeof(callbacks)); - /* JVMTI_EVENT_VM_START */ - callbacks.VMStart = &cbVMStart; - /* JVMTI_EVENT_VM_INIT */ - callbacks.VMInit = &cbVMInit; - /* JVMTI_EVENT_VM_DEATH */ - callbacks.VMDeath = &cbVMDeath; - /* JVMTI_EVENT_OBJECT_FREE */ - callbacks.ObjectFree = &cbObjectFree; - /* JVMTI_EVENT_VM_OBJECT_ALLOC */ - callbacks.VMObjectAlloc = &cbVMObjectAlloc; - /* JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */ - callbacks.ClassFileLoadHook = &cbClassFileLoadHook; - error = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, (jint)sizeof(callbacks)); - check_jvmti_error(jvmti, error, "Cannot set jvmti callbacks"); - - /* At first the only initial events we are interested in are VM - * initialization, VM death, and Class File Loads. - * Once the VM is initialized we will request more events. - */ - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_START, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_DEATH, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_OBJECT_FREE, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_OBJECT_ALLOC, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - - /* Here we create a raw monitor for our use in this agent to - * protect critical sections of code. - */ - error = (*jvmti)->CreateRawMonitor(jvmti, "agent data", &(gdata->lock)); - check_jvmti_error(jvmti, error, "Cannot create raw monitor"); - - /* Create the TraceInfo for various flavors of empty traces */ - for ( flavor = TRACE_FIRST ; flavor <= TRACE_LAST ; flavor++ ) { - gdata->emptyTrace[flavor] = - newTraceInfo(&empty, hashTrace(&empty), flavor); - } - - /* Add jar file to boot classpath */ - add_demo_jar_to_bootclasspath(jvmti, "heapTracker"); - - /* We return JNI_OK to signify success */ - return JNI_OK; -} - -/* Agent_OnUnload: This is called immediately before the shared library is - * unloaded. This is the last code executed. - */ -JNIEXPORT void JNICALL -DEF_Agent_OnUnload(JavaVM *vm) -{ - /* Skip any cleanup, VM is about to die anyway */ -} diff --git a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.h b/jdk/src/demo/share/jvmti/heapTracker/heapTracker.h deleted file mode 100644 index 8d63f156b71..00000000000 --- a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Primary heapTracker #include file, should be included by most if not - * all heapTracker source files. Gives access to the global data structure - * and all global macros. - */ - -#ifndef HEAP_TRACKER_H -#define HEAP_TRACKER_H - -/* Standard C functions used throughout. */ - -#include -#include -#include -#include -#include - -/* General JVM/Java functions, types and macros. */ - -#include -#include "jni.h" -#include "jvmti.h" - -/* Utility functions */ - -#include "agent_util.h" - -#endif diff --git a/jdk/src/demo/share/jvmti/heapTracker/sample.makefile.txt b/jdk/src/demo/share/jvmti/heapTracker/sample.makefile.txt deleted file mode 100644 index e094bc8206f..00000000000 --- a/jdk/src/demo/share/jvmti/heapTracker/sample.makefile.txt +++ /dev/null @@ -1,163 +0,0 @@ -# -# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo heapTracker -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=heapTracker -SOURCES=heapTracker.c ../agent_util/agent_util.c -JAVA_SOURCES=HeapTracker.java - -# Name of jar file that needs to be created -JARFILE=heapTracker.jar - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Sources need java_crw_demo - SOURCES += ../java_crw_demo/java_crw_demo.c - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES=$(JDK)/ - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I../agent_util -CFLAGS += -I../java_crw_demo -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule (build both native library and jar file) -all: $(LIBRARY) $(JARFILE) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Build jar file -$(JARFILE): $(JAVA_SOURCES) - rm -f -r classes - mkdir -p classes - $(JDK)/bin/javac -d classes $(JAVA_SOURCES) - (cd classes; $(JDK)/bin/jar cf ../$@ *) - -# Cleanup the built bits -clean: - rm -f -r classes - rm -f $(LIBRARY) $(JARFILE) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=. $(JDK)/bin/java -agentlib:$(LIBNAME) -Xbootclasspath/a:./$(JARFILE) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/heapViewer/README.txt b/jdk/src/demo/share/jvmti/heapViewer/README.txt deleted file mode 100644 index 57c183819f3..00000000000 --- a/jdk/src/demo/share/jvmti/heapViewer/README.txt +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -heapViewer - -This agent library demonstrates how to get an easy view of the -heap in terms of total object count and space used. -It uses GetLoadedClasses(), SetTag(), and IterateThroughHeap() -to count up all the objects of all the current loaded classes. -The heap dump will happen at the event JVMTI_EVENT_VM_DEATH, or the -event JVMTI_EVENT_DATA_DUMP_REQUEST. - -It also demonstrates some more robust agent error handling using -GetErrorName(), - -Using the heap iterate functions, lots of statistics can be generated -without resorting to using Byte Code Instrumentation (BCI). - -You can use this agent library as follows: - - java -agentlib:heapViewer ... - -To get help on the available options try: - - java -agentlib:heapViewer=help - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - diff --git a/jdk/src/demo/share/jvmti/heapViewer/heapViewer.c b/jdk/src/demo/share/jvmti/heapViewer/heapViewer.c deleted file mode 100644 index 35ed907b84a..00000000000 --- a/jdk/src/demo/share/jvmti/heapViewer/heapViewer.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -#include "agent_util.h" - -/* Global static data */ -typedef struct { - jboolean vmDeathCalled; - jboolean dumpInProgress; - jrawMonitorID lock; -} GlobalData; -static GlobalData globalData, *gdata = &globalData; - -/* Typedef to hold class details */ -typedef struct { - char *signature; - int count; - int space; -} ClassDetails; - -/* Enter agent monitor protected section */ -static void -enterAgentMonitor(jvmtiEnv *jvmti) -{ - jvmtiError err; - - err = (*jvmti)->RawMonitorEnter(jvmti, gdata->lock); - check_jvmti_error(jvmti, err, "raw monitor enter"); -} - -/* Exit agent monitor protected section */ -static void -exitAgentMonitor(jvmtiEnv *jvmti) -{ - jvmtiError err; - - err = (*jvmti)->RawMonitorExit(jvmti, gdata->lock); - check_jvmti_error(jvmti, err, "raw monitor exit"); -} - -/* Heap object callback */ -static jint JNICALL -cbHeapObject(jlong class_tag, jlong size, jlong* tag_ptr, jint length, - void* user_data) -{ - if ( class_tag != (jlong)0 ) { - ClassDetails *d; - - d = (ClassDetails*)(void*)(ptrdiff_t)class_tag; - (*((jint*)(user_data)))++; - d->count++; - d->space += (int)size; - } - return JVMTI_VISIT_OBJECTS; -} - -/* Compare two ClassDetails */ -static int -compareDetails(const void *p1, const void *p2) -{ - return ((ClassDetails*)p2)->space - ((ClassDetails*)p1)->space; -} - -/* Callback for JVMTI_EVENT_DATA_DUMP_REQUEST (Ctrl-\ or at exit) */ -static void JNICALL -dataDumpRequest(jvmtiEnv *jvmti) -{ - enterAgentMonitor(jvmti); { - if ( !gdata->vmDeathCalled && !gdata->dumpInProgress ) { - jvmtiHeapCallbacks heapCallbacks; - ClassDetails *details; - jvmtiError err; - jclass *classes; - jint totalCount; - jint count; - jint i; - - gdata->dumpInProgress = JNI_TRUE; - - /* Get all the loaded classes */ - err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes); - check_jvmti_error(jvmti, err, "get loaded classes"); - - /* Setup an area to hold details about these classes */ - details = (ClassDetails*)calloc(sizeof(ClassDetails), count); - if ( details == NULL ) { - fatal_error("ERROR: Ran out of malloc space\n"); - } - for ( i = 0 ; i < count ; i++ ) { - char *sig; - - /* Get and save the class signature */ - err = (*jvmti)->GetClassSignature(jvmti, classes[i], &sig, NULL); - check_jvmti_error(jvmti, err, "get class signature"); - if ( sig == NULL ) { - fatal_error("ERROR: No class signature found\n"); - } - details[i].signature = strdup(sig); - deallocate(jvmti, sig); - - /* Tag this jclass */ - err = (*jvmti)->SetTag(jvmti, classes[i], - (jlong)(ptrdiff_t)(void*)(&details[i])); - check_jvmti_error(jvmti, err, "set object tag"); - } - - /* Iterate through the heap and count up uses of jclass */ - (void)memset(&heapCallbacks, 0, sizeof(heapCallbacks)); - heapCallbacks.heap_iteration_callback = &cbHeapObject; - totalCount = 0; - err = (*jvmti)->IterateThroughHeap(jvmti, - JVMTI_HEAP_FILTER_CLASS_UNTAGGED, NULL, - &heapCallbacks, (const void *)&totalCount); - check_jvmti_error(jvmti, err, "iterate through heap"); - - /* Remove tags */ - for ( i = 0 ; i < count ; i++ ) { - /* Un-Tag this jclass */ - err = (*jvmti)->SetTag(jvmti, classes[i], (jlong)0); - check_jvmti_error(jvmti, err, "set object tag"); - } - - /* Sort details by space used */ - qsort(details, count, sizeof(ClassDetails), &compareDetails); - - /* Print out sorted table */ - stdout_message("Heap View, Total of %d objects found.\n\n", - totalCount); - - stdout_message("Space Count Class Signature\n"); - stdout_message("---------- ---------- ----------------------\n"); - - for ( i = 0 ; i < count ; i++ ) { - if ( details[i].space == 0 || i > 20 ) { - break; - } - stdout_message("%10d %10d %s\n", - details[i].space, details[i].count, details[i].signature); - } - stdout_message("---------- ---------- ----------------------\n\n"); - - /* Free up all allocated space */ - deallocate(jvmti, classes); - for ( i = 0 ; i < count ; i++ ) { - if ( details[i].signature != NULL ) { - free(details[i].signature); - } - } - free(details); - - gdata->dumpInProgress = JNI_FALSE; - } - } exitAgentMonitor(jvmti); -} - -/* Callback for JVMTI_EVENT_VM_INIT */ -static void JNICALL -vmInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - enterAgentMonitor(jvmti); { - jvmtiError err; - - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_DATA_DUMP_REQUEST, NULL); - check_jvmti_error(jvmti, err, "set event notification"); - } exitAgentMonitor(jvmti); -} - -/* Callback for JVMTI_EVENT_VM_DEATH */ -static void JNICALL -vmDeath(jvmtiEnv *jvmti, JNIEnv *env) -{ - jvmtiError err; - - /* Make sure everything has been garbage collected */ - err = (*jvmti)->ForceGarbageCollection(jvmti); - check_jvmti_error(jvmti, err, "force garbage collection"); - - /* Disable events and dump the heap information */ - enterAgentMonitor(jvmti); { - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_DISABLE, - JVMTI_EVENT_DATA_DUMP_REQUEST, NULL); - check_jvmti_error(jvmti, err, "set event notification"); - - dataDumpRequest(jvmti); - - gdata->vmDeathCalled = JNI_TRUE; - } exitAgentMonitor(jvmti); -} - -/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */ -JNIEXPORT jint JNICALL -DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - jint rc; - jvmtiError err; - jvmtiCapabilities capabilities; - jvmtiEventCallbacks callbacks; - jvmtiEnv *jvmti; - - /* Get JVMTI environment */ - jvmti = NULL; - rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION); - if (rc != JNI_OK) { - fatal_error("ERROR: Unable to create jvmtiEnv, error=%d\n", rc); - return -1; - } - if ( jvmti == NULL ) { - fatal_error("ERROR: No jvmtiEnv* returned from GetEnv\n"); - } - - /* Get/Add JVMTI capabilities */ - (void)memset(&capabilities, 0, sizeof(capabilities)); - capabilities.can_tag_objects = 1; - capabilities.can_generate_garbage_collection_events = 1; - err = (*jvmti)->AddCapabilities(jvmti, &capabilities); - check_jvmti_error(jvmti, err, "add capabilities"); - - /* Create the raw monitor */ - err = (*jvmti)->CreateRawMonitor(jvmti, "agent lock", &(gdata->lock)); - check_jvmti_error(jvmti, err, "create raw monitor"); - - /* Set callbacks and enable event notifications */ - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.VMInit = &vmInit; - callbacks.VMDeath = &vmDeath; - callbacks.DataDumpRequest = &dataDumpRequest; - err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); - check_jvmti_error(jvmti, err, "set event callbacks"); - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, NULL); - check_jvmti_error(jvmti, err, "set event notifications"); - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_DEATH, NULL); - check_jvmti_error(jvmti, err, "set event notifications"); - return 0; -} - -/* Agent_OnUnload() is called last */ -JNIEXPORT void JNICALL -DEF_Agent_OnUnload(JavaVM *vm) -{ -} diff --git a/jdk/src/demo/share/jvmti/heapViewer/sample.makefile.txt b/jdk/src/demo/share/jvmti/heapViewer/sample.makefile.txt deleted file mode 100644 index 59693c298eb..00000000000 --- a/jdk/src/demo/share/jvmti/heapViewer/sample.makefile.txt +++ /dev/null @@ -1,147 +0,0 @@ -# -# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo heapViewer -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=heapViewer -SOURCES=heapViewer.c ../agent_util/agent_util.c - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES= -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES= - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule -all: $(LIBRARY) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Cleanup the built bits -clean: - rm -f $(LIBRARY) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=`pwd` $(JDK)/bin/java -agentlib:$(LIBNAME) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/index.html b/jdk/src/demo/share/jvmti/index.html deleted file mode 100644 index 5791b8b046f..00000000000 --- a/jdk/src/demo/share/jvmti/index.html +++ /dev/null @@ -1,430 +0,0 @@ - - JVM TI Demonstration Code - -

JVM TI Demonstration Code

- -

-The -Java™ Virtual Machine Tools Interface (JVM TI) -is a native tool interface provided in JDK 5.0 and newer. -Native libraries that use JVM TI and are loaded into the -Java Virtual Machine -via the -agentlib, -agentpath, or -Xrun (deprecated) interfaces, are -called Agents. -

-JVM TI -was designed to work with the -Java Native Interface -(JNI), -and eventually displace the -Java Virtual Machine Debugging Interface -(JVMDI) -and the -Java Virtual Machine Profiling Interface -(JVMPI). - -

-We have created a set of demonstration agents that should -help show many of the features and abilities of the -interface. This list of demonstration agents will change over time. -They are provided as educational tools and as starting -points for Java tool development. - -

-These agents are built with every JDK build and some basic testing is performed -on a regular basis, but no extensive testbases currently -exist for these agents. -Every JDK installation should include all the pre-built binaries and sources for -all these agents, just look in the demo/jvmti directory of your JDK. - - -

Using or Running These Agents

- -

-Using these agents will require the VM to locate the shared library file -before any actual Java code is run. -The JDK installation should contain all the agent libraries in -the ${JAVA_HOME}/demo/jvmti/agent-name/lib directories. -The Solaris 64bit version would be contained in the sparcv9 or amd64 -subdirectory. -If 'java' complains that it can't find the library, -you may need to add the directory containing the library into the -LD_LIBRARY_PATH environment variable (Unix), or the PATH environment -variable (Windows). -This is system and platform specific. -If you are using 64bit Solaris (e.g. 'java -d64'), -you should use LD_LIBRARY_PATH64. -Some agents such as the jdwp (debugger backend) -are located inside the primary JDK directories and will always be found -in those locations. - -

-The agents that instrument classfiles -(i.e. BCI, usually through the java_crw_demo library) -such as heapTracker, mtrace, and minst, -also need to have the Java classes they use available in the bootclasspath. -The agents will make attempts at automatically adding their jar file -(e.g. heapTracker.jar, mtrace.jar, or minst.jar) to the bootclasspath -with AddToBootstrapClassLoaderSearch from JVM TI at startup -(see the agent_util code). -This is done by locating this jar file at -${JAVA_HOME}/demo/jvmti/agent-name -where JAVA_HOME is obtained by calling GetSystemProperty from JVM TI -with "java.home". -We recognize that this is not ideal, but felt that as just demonstration -code it was acceptable. -Ideally the agent could find out the actual directory it came from and -locate the jar file relative to that location. -Our demonstration agents currently do not do this. - -

-If you choose to modify or change these agents, the above information -is important in making everything is found. -It is recommended that you change the name of the agent when you -modify it to avoid conflicts with the existing demo agents. -Or better yet, go to http://jdk.dev.java.net and submit your -changes to the agent as an RFE to the JDK. - - -

Demonstration Agents Available

- -
    - -
  • -versionCheck -
    -This is a extremely small agent that does nothing but check the -version string supplied in the jvmti.h file, with the version -number supplied by the VM at runtime. -
  • - -
  • -compiledMethodLoad -
    -This is a small agent that traces CompiledMethodLoad events along -with the HotSpot specific compile_info parameter. -
  • - -
  • -mtrace -
    -This is a small agent that does method tracing. -It uses Bytecode Instrumentation (BCI) via the java_crw_demo library. -
  • - -
  • -minst -
    -This is an even smaller agent that does just method entry tracing. -It also uses Bytecode Instrumentation (BCI) via the java_crw_demo library, -but the instrumentation code is pure Java (no Java native methods used). -NOTE: Be sure to check out java.lang.instrument for a way to avoid -native code agents completely. -
  • - -
  • -gctest -
    -This is a small agent that does garbage collection counting. -
  • - -
  • -heapViewer -
    -This is a small agent that does some basic heap inspections. -
  • - -
  • -heapTracker -
    -This is a small agent that does BCI to capture object creation -and track them. -It uses Bytecode Instrumentation (BCI) via the java_crw_demo library. -
  • - -
  • -waiters -
    -This is a small agent that gets information about threads -waiting on monitors. -
  • - -
- - - -

Agent Support

- -
    - -
  • -java_crw_demo -
    -This is a demo C library that does class file to class file -transformations or BCI (Bytecode Instrumentation). -It is used by several of the above agents. -
  • - - -
- - - -

Native Library Build Hints

- -

-All libraries loaded into java are assumed to be MT-safe (Multi-thread safe). -This means that multiple threads could be executing the code at the same -time, and static or global data may need to be placed in critical -sections. See the Raw Monitor interfaces for more information. - -

-All native libraries loaded into the -Java Virtual Machine, -including Agent libraries, -need to be compiled and built in a compatible way. -Certain native compilation options or optimizations should be avoided, -and some are required. -More information on this options is available in the man pages for -the various compilers. - -

-Some native compiler and linker options can create fatal or -erroneous behavior when native agent libraries are operating -inside the Java Virtual Machine. -It would take too many words to describe all the possible issues with all -the native compiler options, optimizations, and settings. -Here are some recommendations on the basic compiler and linker options -we recommend: - -

    - -

    Solaris

    - -
  • -On Solaris, using the Sun Studio 11 C compiler, -the typical compile and link command lines might look something like: -
    -For 32bit SPARC: -
    -
      -cc -xO2 -mt -xregs=no%appl -xmemalign=4s -xarch=v8 -KPIC -c *.c -
      -cc -mt -xarch=v8 -z defs -ztext -G -o libXXX.so *.o -lc -
    -
    -For 64bit SPARC: -
    -
      -cc -xO2 -mt -xregs=no%appl -xarch=v9 -KPIC -c *.c -
      -cc -mt -xarch=v9 -z defs -ztext -G -o libXXX.so *.o -lc -
    -
    -For X86: -
    -
      -cc -xO2 -mt -xregs=no%frameptr -KPIC -c *.c -
      -cc -mt -z defs -ztext -G -o libXXX.so *.o -lc -
    -
    -For AMD64: -
    -
      -cc -xO2 -mt -xregs=no%frameptr -xarch=amd64 -KPIC -c *.c -
      -cc -mt -xarch=amd64 -z defs -ztext -G -o libXXX.so *.o -lc -
    -
    -
  • - -
  • -Architecture/File Format: -For SPARC 32bit use -xarch=v8, -for SPARC 64bit use -xarch=v9, -for X86 (32-bit) - -leave the option off or use -xarch=generic -, -and for AMD64 (64bit) use -xarch=amd64 -with both C and C++. -
    -This is to be specific as to the architecture and the file format -of the .o files (and ultimately of the .so). -
  • - -
  • -MT-Safe, Position Independent: Use -KPIC -mt -with both C and C++. -
  • - -
  • -Register usage: For SPARC (both 32bit and 64bit) use --xregs=no%appl and for X86 and AMD64 use -xregs=no%frameptr -with both C and C++. -
  • - -
  • -Alignment: For SPARC 32bit use -xmemalign=4s and for SPARC 64bit do NOT use -xmemalign=4 -with both C and C++. -
  • - -
  • -Dependencies: Use ldd -r LibraryName. -
    -After the shared library has been built, the utility -ldd can be used to verify that all dependent libraries -have been satisfied, and all externs can be found. -If ldd says anything is missing, it is very likely that the JVM will also -be unable to load this library. -This usually means that you missed some -lname -options when building the library, or perhaps forgot a -R path -option that tells the library where to look for libraries at runtime. -
  • - -

    Linux

    - -
  • -On Linux, using the gcc version 3.2, -the typical compile and link command lines might look something like: -
    -For X86: -
    -
      -gcc -O2 -fPIC -pthread -DLINUX -c *.c -
      -gcc -z defs -static-libgcc -shared -o libXXX.so *.o -lc -
    -
    -For AMD64: -
    -
      -gcc -O2 -fPIC -pthread -DLINUX -D_LP64=1 -c *.c -
      -gcc -z defs -static-libgcc -shared -o libXXX.so *.o -lc -
    -
    -
  • - -
  • -MT-Safe, Position Independent: -Use -fPIC -pthread. -
  • - -
  • -Agent Demo Code: Needs -DLINUX -
  • - -
  • -Register Usage: Use -fno-omit-frame-pointer. -
    -It is important that these libraries have frame pointer register usage, see the above comments on the Solaris --xregs=no%frameptr -option. -
  • - -
  • -Library: Use -static-libgcc. -
    -When building the shared library (-shared option), this option -allows for maximum portability of the library between different -flavors of Linux. -The problem we have seen with Linux is that we cannot depend -on a compatible shared gcc library existing on all the versions of -Linux we can run on. -By doing this static link, the version script becomes more -important, making sure you don't expose any extern symbols -you didn't intend to. -
  • - -
  • -Dependencies: Use ldd -r LibraryName. -
    -Provides the same checking as Solaris (see above). -
  • - -

    Windows

    - -
  • -On Windows and using the Microsoft C++ Compiler Visual Studio .NET 2003, -the typical compile and link command lines might look something like: -
    -For X86: -
    -
      -cl /O1 /MD /D _STATIC_CPPLIB /c *.c -
      -link /dll /opt:REF /out:XXX.dll *.obj -
    -
    -For AMD64: -
    -
      -cl /O1 /MD /D _STATIC_CPPLIB /c *.c -
      -link /dll /opt:REF /out:XXX.dll *.obj -
    -
    -
  • - -
  • -Library: Use /opt:REF when building the dll. -
  • - -
  • -MS DLL Runtime: Use the /MD /D _STATIC_CPPLIB option. -
    -This causes your dll to become dependent on just MSVCR*.DLL. -The option /D _STATIC_CPPLIB prevents you from becoming dependent on the -C++ library MSVCP*.DLL. -This is what we use in the JDK, but there are probably many combinations -that you could safely use, unfortunately there are many combinations -of runtimes that will not work. -Check the Microsoft site on proper use of runtimes. -
  • - -
  • -Dependencies: Use VC++ dumpbin /exports and the VC++ "Dependency Walker". -
    -Provides dependency information similar to ldd. -
  • - -
- - -

For More Information

- -

-Remember, the complete source to all these agents is contained in the JDK -installations at demo/jvmti. - -

-For more detailed information on JVM TI, refer to - -http://java.sun.com/j2se/latest/docs/guide/jvmti. - -

-More information on using JNI and building native libraries refer to: - -http://java.sun.com/j2se/latest/docs/guide/jni. - -

-Additional information can also be found by doing a search on "jvmti" at -http://java.sun.com/j2se. -Various technical articles are also available through this website. -And don't forget the -Java Tutorials at -http://docs.oracle.com/javase/tutorial -for getting a quick start on all the various interfaces. - -

Comments and Feedback

- -

-Comments regarding JVM TI or on any of these demonstrations should be -sent through -http://java.sun.com/mail/ - - - - diff --git a/jdk/src/demo/share/jvmti/java_crw_demo/README.txt b/jdk/src/demo/share/jvmti/java_crw_demo/README.txt deleted file mode 100644 index c242793a6a2..00000000000 --- a/jdk/src/demo/share/jvmti/java_crw_demo/README.txt +++ /dev/null @@ -1,77 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -java_crw_demo Library - -The library java_crw_demo is a small C library that is used by HPROF -and other agent libraries to do some very basic bytecode -insertion (BCI) of class files. This is not an agent -library but a general purpose library that can be used to do some -very limited bytecode insertion. - -In the demo sources, look for the use of java_crw_demo.h and -the C function java_crw_demo(). The java_crw_demo library is provided -as part of the JRE. - -The basic BCI that this library does includes: - - * On entry to the java.lang.Object init method (signature "()V"), - a invokestatic call to tclass.obj_init_method(object); is inserted. - - * On any newarray type opcode, immediately following it, the array - object is duplicated on the stack and an invokestatic call to - tclass.newarray_method(object); is inserted. - - * On entry to all methods, a invokestatic call to - tclass.call_method(cnum,mnum); is inserted. The agent can map the - two integers (cnum,mnum) to a method in a class, the cnum is the - number provided to the java_crw_demo library when the classfile was - modified. - - * On return from any method (any return opcode), a invokestatic call to - tclass.return_method(cnum,mnum); is inserted. - -Some methods are not modified at all, init methods and finalize methods -whose length is 1 will not be modified. Classes that are designated -"system" will not have their clinit methods modified. In addition, the -method java.lang.Thread.currentThread() is not modified. - -No methods or fields will be added to any class, however new constant -pool entries will be added at the end of the original constant pool table. -The exception, line, and local variable tables for each method is adjusted -for the modification. The bytecodes are compressed to use smaller offsets -and the fewest 'wide' opcodes. - -All attempts are made to minimize the number of bytecodes at each insertion -site, however, classes with N return opcodes or N newarray opcodes will get -N insertions. And only the necessary modification dictated by the input -arguments to java_crw_demo are actually made. - diff --git a/jdk/src/demo/share/jvmti/java_crw_demo/java_crw_demo.c b/jdk/src/demo/share/jvmti/java_crw_demo/java_crw_demo.c deleted file mode 100644 index eaa271e9e18..00000000000 --- a/jdk/src/demo/share/jvmti/java_crw_demo/java_crw_demo.c +++ /dev/null @@ -1,2535 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Class reader writer (java_crw_demo) for instrumenting bytecodes */ - -/* - * As long as the callbacks allow for it and the class number is unique, - * this code is completely re-entrant and any number of classfile - * injections can happen at the same time. - * - * The current logic requires a unique number for this class instance - * or (jclass,jobject loader) pair, this is done via the ClassIndex - * in hprof, which is passed in as the 'unsigned cnum' to java_crw_demo(). - * It's up to the user of this interface if it wants to use this - * feature. - * - */ - -#include -#include -#include - -/* Get Java and class file and bytecode information. */ - -#include - -#include "classfile_constants.h" - - -/* Include our own interface for cross check */ - -#include "java_crw_demo.h" - -/* Macros over error functions to capture line numbers */ - -/* Fatal error used in all builds. */ - -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE "java_crw.demo.c" /* Never use __FILE__ */ -#endif - -#define CRW_FATAL(ci, message) fatal_error(ci, message, THIS_FILE, __LINE__) - -#if defined(DEBUG) || !defined(NDEBUG) - - /* This assert macro is only used in the debug builds. */ - #define CRW_ASSERT(ci, cond) \ - ((cond)?(void)0:assert_error(ci, #cond, THIS_FILE, __LINE__)) - -#else - - #define CRW_ASSERT(ci, cond) - -#endif - -#define CRW_ASSERT_MI(mi) CRW_ASSERT((mi)?(mi)->ci:NULL,(mi)!=NULL) - -#define CRW_ASSERT_CI(ci) CRW_ASSERT(ci, ( (ci) != NULL && \ - (ci)->input_position <= (ci)->input_len && \ - (ci)->output_position <= (ci)->output_len) ) - -#define BUFSIZE 256 - -#ifdef _WIN32 -#define snprintf(buffer, count, format, ...) _snprintf_s(buffer, count, _TRUNCATE, format, ##__VA_ARGS__) -#endif - -/* Typedefs for various integral numbers, just for code clarity */ - -typedef unsigned ClassOpcode; /* One opcode */ -typedef unsigned char ByteCode; /* One byte from bytecodes */ -typedef int ByteOffset; /* Byte offset */ -typedef int ClassConstant; /* Constant pool kind */ -typedef long CrwPosition; /* Position in class image */ -typedef unsigned short CrwCpoolIndex; /* Index into constant pool */ - -/* Misc support macros */ - -/* Given the position of an opcode, find the next 4byte boundary position */ -#define NEXT_4BYTE_BOUNDARY(opcode_pos) (((opcode_pos)+4) & (~3)) - -#define LARGEST_INJECTION (12*3) /* 3 injections at same site */ -#define MAXIMUM_NEW_CPOOL_ENTRIES 64 /* don't add more than 32 entries */ - -/* Constant Pool Entry (internal table that mirrors pool in file image) */ - -typedef struct { - const char * ptr; /* Pointer to any string */ - unsigned short len; /* Length of string */ - unsigned int index1; /* 1st 16 bit index or 32bit value. */ - unsigned int index2; /* 2nd 16 bit index or 32bit value. */ - ClassConstant tag; /* Tag or kind of entry. */ -} CrwConstantPoolEntry; - -struct MethodImage; - -/* Class file image storage structure */ - -typedef struct CrwClassImage { - - /* Unique class number for this class */ - unsigned number; - - /* Name of class, given or gotten out of class image */ - const char * name; - - /* Input and Output class images tracking */ - const unsigned char * input; - unsigned char * output; - CrwPosition input_len; - CrwPosition output_len; - CrwPosition input_position; - CrwPosition output_position; - - /* Mirrored constant pool */ - CrwConstantPoolEntry * cpool; - CrwCpoolIndex cpool_max_elements; /* Max count */ - CrwCpoolIndex cpool_count_plus_one; - - /* Input flags about class (e.g. is it a system class) */ - int system_class; - - /* Class access flags gotten from file. */ - unsigned access_flags; - - /* Names of classes and methods. */ - char* tclass_name; /* Name of class that has tracker methods. */ - char* tclass_sig; /* Signature of class */ - char* call_name; /* Method name to call at offset 0 */ - char* call_sig; /* Signature of this method */ - char* return_name; /* Method name to call before any return */ - char* return_sig; /* Signature of this method */ - char* obj_init_name; /* Method name to call in Object */ - char* obj_init_sig; /* Signature of this method */ - char* newarray_name; /* Method name to call after newarray opcodes */ - char* newarray_sig; /* Signature of this method */ - - /* Constant pool index values for new entries */ - CrwCpoolIndex tracker_class_index; - CrwCpoolIndex object_init_tracker_index; - CrwCpoolIndex newarray_tracker_index; - CrwCpoolIndex call_tracker_index; - CrwCpoolIndex return_tracker_index; - CrwCpoolIndex class_number_index; /* Class number in pool */ - - /* Count of injections made into this class */ - int injection_count; - - /* This class must be the java.lang.Object class */ - jboolean is_object_class; - - /* This class must be the java.lang.Thread class */ - jboolean is_thread_class; - - /* Callback functions */ - FatalErrorHandler fatal_error_handler; - MethodNumberRegister mnum_callback; - - /* Table of method names and descr's */ - int method_count; - const char ** method_name; - const char ** method_descr; - struct MethodImage * current_mi; - -} CrwClassImage; - -/* Injection bytecodes (holds injected bytecodes for each code position) */ - -typedef struct { - ByteCode * code; - ByteOffset len; -} Injection; - -/* Method transformation data (allocated/freed as each method is processed) */ - -typedef struct MethodImage { - - /* Back reference to Class image data. */ - CrwClassImage * ci; - - /* Unique method number for this class. */ - unsigned number; - - /* Method name and descr */ - const char * name; - const char * descr; - - /* Map of input bytecode offsets to output bytecode offsets */ - ByteOffset * map; - - /* Bytecode injections for each input bytecode offset */ - Injection * injections; - - /* Widening setting for each input bytecode offset */ - signed char * widening; - - /* Length of original input bytecodes, and new bytecodes. */ - ByteOffset code_len; - ByteOffset new_code_len; - - /* Location in input where bytecodes are located. */ - CrwPosition start_of_input_bytecodes; - - /* Original max_stack and new max stack */ - unsigned max_stack; - unsigned new_max_stack; - - jboolean object_init_method; - jboolean skip_call_return_sites; - - /* Method access flags gotten from file. */ - unsigned access_flags; - -} MethodImage; - -/* ----------------------------------------------------------------- */ -/* General support functions (memory and error handling) */ - -static void -fatal_error(CrwClassImage *ci, const char *message, const char *file, int line) -{ - if ( ci != NULL && ci->fatal_error_handler != NULL ) { - (*ci->fatal_error_handler)(message, file, line); - } else { - /* Normal operation should NEVER reach here */ - /* NO CRW FATAL ERROR HANDLER! */ - (void)fprintf(stderr, "CRW: %s [%s:%d]\n", message, file, line); - } - abort(); -} - -#if defined(DEBUG) || !defined(NDEBUG) -static void -assert_error(CrwClassImage *ci, const char *condition, - const char *file, int line) -{ - char buf[512]; - MethodImage *mi; - ByteOffset byte_code_offset; - - mi = ci->current_mi; - if ( mi != NULL ) { - byte_code_offset = (ByteOffset)(mi->ci->input_position - mi->start_of_input_bytecodes); - } else { - byte_code_offset=-1; - } - - (void)sprintf(buf, - "CRW ASSERTION FAILURE: %s (%s:%s:%d)", - condition, - ci->name==NULL?"?":ci->name, - (mi==NULL||mi->name==NULL)?"?":mi->name, - byte_code_offset); - fatal_error(ci, buf, file, line); -} -#endif - -static void * -allocate(CrwClassImage *ci, int nbytes) -{ - void * ptr; - - if ( nbytes <= 0 ) { - CRW_FATAL(ci, "Cannot allocate <= 0 bytes"); - } - ptr = malloc(nbytes); - if ( ptr == NULL ) { - CRW_FATAL(ci, "Ran out of malloc memory"); - } - return ptr; -} - -static void * -reallocate(CrwClassImage *ci, void *optr, int nbytes) -{ - void * ptr; - - if ( optr == NULL ) { - CRW_FATAL(ci, "Cannot deallocate NULL"); - } - if ( nbytes <= 0 ) { - CRW_FATAL(ci, "Cannot reallocate <= 0 bytes"); - } - ptr = realloc(optr, nbytes); - if ( ptr == NULL ) { - CRW_FATAL(ci, "Ran out of malloc memory"); - } - return ptr; -} - -static void * -allocate_clean(CrwClassImage *ci, int nbytes) -{ - void * ptr; - - if ( nbytes <= 0 ) { - CRW_FATAL(ci, "Cannot allocate <= 0 bytes"); - } - ptr = calloc(nbytes, 1); - if ( ptr == NULL ) { - CRW_FATAL(ci, "Ran out of malloc memory"); - } - return ptr; -} - -static const char * -duplicate(CrwClassImage *ci, const char *str, int len) -{ - char *copy; - - copy = (char*)allocate(ci, len+1); - (void)memcpy(copy, str, len); - copy[len] = 0; - return (const char *)copy; -} - -static void -deallocate(CrwClassImage *ci, void *ptr) -{ - if ( ptr == NULL ) { - CRW_FATAL(ci, "Cannot deallocate NULL"); - } - (void)free(ptr); -} - -/* ----------------------------------------------------------------- */ -/* Functions for reading/writing bytes to/from the class images */ - -static unsigned -readU1(CrwClassImage *ci) -{ - CRW_ASSERT_CI(ci); - return ((unsigned)(ci->input[ci->input_position++])) & 0xFF; -} - -static unsigned -readU2(CrwClassImage *ci) -{ - unsigned res; - - res = readU1(ci); - return (res << 8) + readU1(ci); -} - -static signed short -readS2(CrwClassImage *ci) -{ - unsigned res; - - res = readU1(ci); - return ((res << 8) + readU1(ci)) & 0xFFFF; -} - -static unsigned -readU4(CrwClassImage *ci) -{ - unsigned res; - - res = readU2(ci); - return (res << 16) + readU2(ci); -} - -static void -writeU1(CrwClassImage *ci, unsigned val) /* Only writes out lower 8 bits */ -{ - CRW_ASSERT_CI(ci); - if ( ci->output != NULL ) { - ci->output[ci->output_position++] = val & 0xFF; - } -} - -static void -writeU2(CrwClassImage *ci, unsigned val) -{ - writeU1(ci, val >> 8); - writeU1(ci, val); -} - -static void -writeU4(CrwClassImage *ci, unsigned val) -{ - writeU2(ci, val >> 16); - writeU2(ci, val); -} - -static unsigned -copyU1(CrwClassImage *ci) -{ - unsigned value; - - value = readU1(ci); - writeU1(ci, value); - return value; -} - -static unsigned -copyU2(CrwClassImage *ci) -{ - unsigned value; - - value = readU2(ci); - writeU2(ci, value); - return value; -} - -static unsigned -copyU4(CrwClassImage *ci) -{ - unsigned value; - - value = readU4(ci); - writeU4(ci, value); - return value; -} - -static void -copy(CrwClassImage *ci, unsigned count) -{ - CRW_ASSERT_CI(ci); - if ( ci->output != NULL ) { - (void)memcpy(ci->output+ci->output_position, - ci->input+ci->input_position, count); - ci->output_position += count; - } - ci->input_position += count; - CRW_ASSERT_CI(ci); -} - -static void -skip(CrwClassImage *ci, unsigned count) -{ - CRW_ASSERT_CI(ci); - ci->input_position += count; -} - -static void -read_bytes(CrwClassImage *ci, void *bytes, unsigned count) -{ - CRW_ASSERT_CI(ci); - CRW_ASSERT(ci, bytes!=NULL); - (void)memcpy(bytes, ci->input+ci->input_position, count); - ci->input_position += count; -} - -static void -write_bytes(CrwClassImage *ci, void *bytes, unsigned count) -{ - CRW_ASSERT_CI(ci); - CRW_ASSERT(ci, bytes!=NULL); - if ( ci->output != NULL ) { - (void)memcpy(ci->output+ci->output_position, bytes, count); - ci->output_position += count; - } -} - -static void -random_writeU2(CrwClassImage *ci, CrwPosition pos, unsigned val) -{ - CrwPosition save_position; - - CRW_ASSERT_CI(ci); - save_position = ci->output_position; - ci->output_position = pos; - writeU2(ci, val); - ci->output_position = save_position; -} - -static void -random_writeU4(CrwClassImage *ci, CrwPosition pos, unsigned val) -{ - CrwPosition save_position; - - CRW_ASSERT_CI(ci); - save_position = ci->output_position; - ci->output_position = pos; - writeU4(ci, val); - ci->output_position = save_position; -} - -/* ----------------------------------------------------------------- */ -/* Constant Pool handling functions. */ - -static void -fillin_cpool_entry(CrwClassImage *ci, CrwCpoolIndex i, - ClassConstant tag, - unsigned int index1, unsigned int index2, - const char *ptr, int len) -{ - CRW_ASSERT_CI(ci); - CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one); - ci->cpool[i].tag = tag; - ci->cpool[i].index1 = index1; - ci->cpool[i].index2 = index2; - ci->cpool[i].ptr = ptr; - ci->cpool[i].len = (unsigned short)len; -} - -static CrwCpoolIndex -add_new_cpool_entry(CrwClassImage *ci, ClassConstant tag, - unsigned int index1, unsigned int index2, - const char *str, int len) -{ - CrwCpoolIndex i; - char *utf8 = NULL; - - CRW_ASSERT_CI(ci); - i = ci->cpool_count_plus_one++; - - /* NOTE: This implementation does not automatically expand the - * constant pool table beyond the expected number needed - * to handle this particular CrwTrackerInterface injections. - * See MAXIMUM_NEW_CPOOL_ENTRIES - */ - CRW_ASSERT(ci, ci->cpool_count_plus_one < ci->cpool_max_elements ); - - writeU1(ci, tag); - switch (tag) { - case JVM_CONSTANT_Class: - writeU2(ci, index1); - break; - case JVM_CONSTANT_String: - writeU2(ci, index1); - break; - case JVM_CONSTANT_Fieldref: - case JVM_CONSTANT_Methodref: - case JVM_CONSTANT_InterfaceMethodref: - case JVM_CONSTANT_Integer: - case JVM_CONSTANT_Float: - case JVM_CONSTANT_NameAndType: - writeU2(ci, index1); - writeU2(ci, index2); - break; - case JVM_CONSTANT_Long: - case JVM_CONSTANT_Double: - writeU4(ci, index1); - writeU4(ci, index2); - ci->cpool_count_plus_one++; - CRW_ASSERT(ci, ci->cpool_count_plus_one < ci->cpool_max_elements ); - break; - case JVM_CONSTANT_Utf8: - CRW_ASSERT(ci, len==(len & 0xFFFF)); - writeU2(ci, len); - write_bytes(ci, (void*)str, len); - utf8 = (char*)duplicate(ci, str, len); - break; - default: - CRW_FATAL(ci, "Unknown constant"); - break; - } - fillin_cpool_entry(ci, i, tag, index1, index2, (const char *)utf8, len); - CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one); - return i; -} - -static CrwCpoolIndex -add_new_class_cpool_entry(CrwClassImage *ci, const char *class_name) -{ - CrwCpoolIndex name_index; - CrwCpoolIndex class_index; - int len; - - CRW_ASSERT_CI(ci); - CRW_ASSERT(ci, class_name!=NULL); - - len = (int)strlen(class_name); - name_index = add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, - class_name, len); - class_index = add_new_cpool_entry(ci, JVM_CONSTANT_Class, name_index, 0, - NULL, 0); - return class_index; -} - -static CrwCpoolIndex -add_new_method_cpool_entry(CrwClassImage *ci, CrwCpoolIndex class_index, - const char *name, const char *descr) -{ - CrwCpoolIndex name_index; - CrwCpoolIndex descr_index; - CrwCpoolIndex name_type_index; - int len; - - CRW_ASSERT_CI(ci); - CRW_ASSERT(ci, name!=NULL); - CRW_ASSERT(ci, descr!=NULL); - len = (int)strlen(name); - name_index = - add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, name, len); - len = (int)strlen(descr); - descr_index = - add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, descr, len); - name_type_index = - add_new_cpool_entry(ci, JVM_CONSTANT_NameAndType, - name_index, descr_index, NULL, 0); - return add_new_cpool_entry(ci, JVM_CONSTANT_Methodref, - class_index, name_type_index, NULL, 0); -} - -static CrwConstantPoolEntry -cpool_entry(CrwClassImage *ci, CrwCpoolIndex c_index) -{ - CRW_ASSERT_CI(ci); - CRW_ASSERT(ci, c_index > 0 && c_index < ci->cpool_count_plus_one); - return ci->cpool[c_index]; -} - -static void -cpool_setup(CrwClassImage *ci) -{ - CrwCpoolIndex i; - CrwPosition cpool_output_position; - int count_plus_one; - - CRW_ASSERT_CI(ci); - cpool_output_position = ci->output_position; - count_plus_one = copyU2(ci); - CRW_ASSERT(ci, count_plus_one>1); - ci->cpool_max_elements = count_plus_one+MAXIMUM_NEW_CPOOL_ENTRIES; - ci->cpool = (CrwConstantPoolEntry*)allocate_clean(ci, - (int)((ci->cpool_max_elements)*sizeof(CrwConstantPoolEntry))); - ci->cpool_count_plus_one = (CrwCpoolIndex)count_plus_one; - - /* Index zero not in class file */ - for (i = 1; i < count_plus_one; ++i) { - CrwCpoolIndex ipos; - ClassConstant tag; - unsigned int index1; - unsigned int index2; - unsigned len; - char * utf8; - char message[BUFSIZE]; - - ipos = i; - index1 = 0; - index2 = 0; - len = 0; - utf8 = NULL; - - tag = copyU1(ci); - switch (tag) { - case JVM_CONSTANT_Class: - index1 = copyU2(ci); - break; - case JVM_CONSTANT_String: - index1 = copyU2(ci); - break; - case JVM_CONSTANT_Fieldref: - case JVM_CONSTANT_Methodref: - case JVM_CONSTANT_InterfaceMethodref: - case JVM_CONSTANT_Integer: - case JVM_CONSTANT_Float: - case JVM_CONSTANT_NameAndType: - index1 = copyU2(ci); - index2 = copyU2(ci); - break; - case JVM_CONSTANT_Long: - case JVM_CONSTANT_Double: - index1 = copyU4(ci); - index2 = copyU4(ci); - ++i; /* // these take two CP entries - duh! */ - break; - case JVM_CONSTANT_Utf8: - len = copyU2(ci); - index1 = (unsigned short)len; - utf8 = (char*)allocate(ci, len+1); - read_bytes(ci, (void*)utf8, len); - utf8[len] = 0; - write_bytes(ci, (void*)utf8, len); - break; - case JVM_CONSTANT_MethodType: - index1 = copyU2(ci); - break; - case JVM_CONSTANT_MethodHandle: - index1 = copyU1(ci); - index2 = copyU2(ci); - break; - case JVM_CONSTANT_InvokeDynamic: - index1 = copyU2(ci); - index2 = copyU2(ci); - break; - default: - snprintf(message, BUFSIZE, "Unknown tag: %d, at ipos %hu", tag, ipos); - CRW_FATAL(ci, message); - break; - } - fillin_cpool_entry(ci, ipos, tag, index1, index2, (const char *)utf8, len); - } - - if (ci->call_name != NULL || ci->return_name != NULL) { - if ( ci->number != (ci->number & 0x7FFF) ) { - ci->class_number_index = - add_new_cpool_entry(ci, JVM_CONSTANT_Integer, - (ci->number>>16) & 0xFFFF, ci->number & 0xFFFF, NULL, 0); - } - } - - if ( ci->tclass_name != NULL ) { - ci->tracker_class_index = - add_new_class_cpool_entry(ci, ci->tclass_name); - } - if (ci->obj_init_name != NULL) { - ci->object_init_tracker_index = add_new_method_cpool_entry(ci, - ci->tracker_class_index, - ci->obj_init_name, - ci->obj_init_sig); - } - if (ci->newarray_name != NULL) { - ci->newarray_tracker_index = add_new_method_cpool_entry(ci, - ci->tracker_class_index, - ci->newarray_name, - ci->newarray_sig); - } - if (ci->call_name != NULL) { - ci->call_tracker_index = add_new_method_cpool_entry(ci, - ci->tracker_class_index, - ci->call_name, - ci->call_sig); - } - if (ci->return_name != NULL) { - ci->return_tracker_index = add_new_method_cpool_entry(ci, - ci->tracker_class_index, - ci->return_name, - ci->return_sig); - } - - random_writeU2(ci, cpool_output_position, ci->cpool_count_plus_one); -} - -/* ----------------------------------------------------------------- */ -/* Functions that create the bytecodes to inject */ - -static ByteOffset -push_pool_constant_bytecodes(ByteCode *bytecodes, CrwCpoolIndex index) -{ - ByteOffset nbytes = 0; - - if ( index == (index&0x7F) ) { - bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc; - } else { - bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc_w; - bytecodes[nbytes++] = (ByteCode)((index >> 8) & 0xFF); - } - bytecodes[nbytes++] = (ByteCode)(index & 0xFF); - return nbytes; -} - -static ByteOffset -push_short_constant_bytecodes(ByteCode *bytecodes, unsigned number) -{ - ByteOffset nbytes = 0; - - if ( number <= 5 ) { - bytecodes[nbytes++] = (ByteCode)(JVM_OPC_iconst_0+number); - } else if ( number == (number&0x7F) ) { - bytecodes[nbytes++] = (ByteCode)JVM_OPC_bipush; - bytecodes[nbytes++] = (ByteCode)(number & 0xFF); - } else { - bytecodes[nbytes++] = (ByteCode)JVM_OPC_sipush; - bytecodes[nbytes++] = (ByteCode)((number >> 8) & 0xFF); - bytecodes[nbytes++] = (ByteCode)(number & 0xFF); - } - return nbytes; -} - -static ByteOffset -injection_template(MethodImage *mi, ByteCode *bytecodes, ByteOffset max_nbytes, - CrwCpoolIndex method_index) -{ - CrwClassImage * ci; - ByteOffset nbytes = 0; - unsigned max_stack; - int add_dup; - int add_aload; - int push_cnum; - int push_mnum; - - ci = mi->ci; - - CRW_ASSERT(ci, bytecodes!=NULL); - - if ( method_index == 0 ) { - return 0; - } - - if ( method_index == ci->newarray_tracker_index) { - max_stack = mi->max_stack + 1; - add_dup = JNI_TRUE; - add_aload = JNI_FALSE; - push_cnum = JNI_FALSE; - push_mnum = JNI_FALSE; - } else if ( method_index == ci->object_init_tracker_index) { - max_stack = mi->max_stack + 1; - add_dup = JNI_FALSE; - add_aload = JNI_TRUE; - push_cnum = JNI_FALSE; - push_mnum = JNI_FALSE; - } else { - max_stack = mi->max_stack + 2; - add_dup = JNI_FALSE; - add_aload = JNI_FALSE; - push_cnum = JNI_TRUE; - push_mnum = JNI_TRUE; - } - - if ( add_dup ) { - bytecodes[nbytes++] = (ByteCode)JVM_OPC_dup; - } - if ( add_aload ) { - bytecodes[nbytes++] = (ByteCode)JVM_OPC_aload_0; - } - if ( push_cnum ) { - if ( ci->number == (ci->number & 0x7FFF) ) { - nbytes += push_short_constant_bytecodes(bytecodes+nbytes, - ci->number); - } else { - CRW_ASSERT(ci, ci->class_number_index!=0); - nbytes += push_pool_constant_bytecodes(bytecodes+nbytes, - ci->class_number_index); - } - } - if ( push_mnum ) { - nbytes += push_short_constant_bytecodes(bytecodes+nbytes, - mi->number); - } - bytecodes[nbytes++] = (ByteCode)JVM_OPC_invokestatic; - bytecodes[nbytes++] = (ByteCode)(method_index >> 8); - bytecodes[nbytes++] = (ByteCode)method_index; - bytecodes[nbytes] = 0; - CRW_ASSERT(ci, nbytes mi->new_max_stack ) { - mi->new_max_stack = max_stack; - } - return nbytes; -} - -/* Called to create injection code at entry to a method */ -static ByteOffset -entry_injection_code(MethodImage *mi, ByteCode *bytecodes, ByteOffset len) -{ - CrwClassImage * ci; - ByteOffset nbytes = 0; - - CRW_ASSERT_MI(mi); - - ci = mi->ci; - - if ( mi->object_init_method ) { - nbytes = injection_template(mi, - bytecodes, len, ci->object_init_tracker_index); - } - if ( !mi->skip_call_return_sites ) { - nbytes += injection_template(mi, - bytecodes+nbytes, len-nbytes, ci->call_tracker_index); - } - return nbytes; -} - -/* Called to create injection code before an opcode */ -static ByteOffset -before_injection_code(MethodImage *mi, ClassOpcode opcode, - ByteCode *bytecodes, ByteOffset len) -{ - ByteOffset nbytes = 0; - - - CRW_ASSERT_MI(mi); - switch ( opcode ) { - case JVM_OPC_return: - case JVM_OPC_ireturn: - case JVM_OPC_lreturn: - case JVM_OPC_freturn: - case JVM_OPC_dreturn: - case JVM_OPC_areturn: - if ( !mi->skip_call_return_sites ) { - nbytes = injection_template(mi, - bytecodes, len, mi->ci->return_tracker_index); - } - break; - default: - break; - } - return nbytes; -} - -/* Called to create injection code after an opcode */ -static ByteOffset -after_injection_code(MethodImage *mi, ClassOpcode opcode, - ByteCode *bytecodes, ByteOffset len) -{ - CrwClassImage* ci; - ByteOffset nbytes; - - ci = mi->ci; - nbytes = 0; - - CRW_ASSERT_MI(mi); - switch ( opcode ) { - case JVM_OPC_new: - /* Can't inject here cannot pass around uninitialized object */ - break; - case JVM_OPC_newarray: - case JVM_OPC_anewarray: - case JVM_OPC_multianewarray: - nbytes = injection_template(mi, - bytecodes, len, ci->newarray_tracker_index); - break; - default: - break; - } - return nbytes; -} - -/* Actually inject the bytecodes */ -static void -inject_bytecodes(MethodImage *mi, ByteOffset at, - ByteCode *bytecodes, ByteOffset len) -{ - Injection injection; - CrwClassImage *ci; - - ci = mi->ci; - CRW_ASSERT_MI(mi); - CRW_ASSERT(ci, at <= mi->code_len); - - injection = mi->injections[at]; - - CRW_ASSERT(ci, len <= LARGEST_INJECTION/2); - CRW_ASSERT(ci, injection.len+len <= LARGEST_INJECTION); - - /* Either start an injection area or concatenate to what is there */ - if ( injection.code == NULL ) { - CRW_ASSERT(ci, injection.len==0); - injection.code = (ByteCode *)allocate_clean(ci, LARGEST_INJECTION+1); - } - - (void)memcpy(injection.code+injection.len, bytecodes, len); - injection.len += len; - injection.code[injection.len] = 0; - mi->injections[at] = injection; - ci->injection_count++; -} - -/* ----------------------------------------------------------------- */ -/* Method handling functions */ - -static MethodImage * -method_init(CrwClassImage *ci, unsigned mnum, ByteOffset code_len) -{ - MethodImage * mi; - ByteOffset i; - - mi = (MethodImage*)allocate_clean(ci, (int)sizeof(MethodImage)); - mi->ci = ci; - mi->name = ci->method_name[mnum]; - mi->descr = ci->method_descr[mnum]; - mi->code_len = code_len; - mi->map = (ByteOffset*)allocate_clean(ci, - (int)((code_len+1)*sizeof(ByteOffset))); - for(i=0; i<=code_len; i++) { - mi->map[i] = i; - } - mi->widening = (signed char*)allocate_clean(ci, code_len+1); - mi->injections = (Injection *)allocate_clean(ci, - (int)((code_len+1)*sizeof(Injection))); - mi->number = mnum; - ci->current_mi = mi; - return mi; -} - -static void -method_term(MethodImage *mi) -{ - CrwClassImage *ci; - - ci = mi->ci; - CRW_ASSERT_MI(mi); - if ( mi->map != NULL ) { - deallocate(ci, (void*)mi->map); - mi->map = NULL; - } - if ( mi->widening != NULL ) { - deallocate(ci, (void*)mi->widening); - mi->widening = NULL; - } - if ( mi->injections != NULL ) { - ByteOffset i; - for(i=0; i<= mi->code_len; i++) { - if ( mi->injections[i].code != NULL ) { - deallocate(ci, (void*)mi->injections[i].code); - mi->injections[i].code = NULL; - } - } - deallocate(ci, (void*)mi->injections); - mi->injections = NULL; - } - ci->current_mi = NULL; - deallocate(ci, (void*)mi); -} - -static ByteOffset -input_code_offset(MethodImage *mi) -{ - CRW_ASSERT_MI(mi); - return (ByteOffset)(mi->ci->input_position - mi->start_of_input_bytecodes); -} - -static void -rewind_to_beginning_of_input_bytecodes(MethodImage *mi) -{ - CRW_ASSERT_MI(mi); - mi->ci->input_position = mi->start_of_input_bytecodes; -} - -/* Starting at original byte position 'at', add 'offset' to it's new - * location. This may be a negative value. - * NOTE: That this map is not the new bytecode location of the opcode - * but the new bytecode location that should be used when - * a goto or jump instruction was targeting the old bytecode - * location. - */ -static void -adjust_map(MethodImage *mi, ByteOffset at, ByteOffset offset) -{ - ByteOffset i; - - CRW_ASSERT_MI(mi); - for (i = at; i <= mi->code_len; ++i) { - mi->map[i] += offset; - } -} - -static void -widen(MethodImage *mi, ByteOffset at, ByteOffset len) -{ - int delta; - - CRW_ASSERT(mi->ci, at <= mi->code_len); - delta = len - mi->widening[at]; - /* Adjust everything from the current input location by delta */ - adjust_map(mi, input_code_offset(mi), delta); - /* Mark at beginning of instruction */ - mi->widening[at] = (signed char)len; -} - -static void -verify_opc_wide(CrwClassImage *ci, ClassOpcode wopcode) -{ - switch (wopcode) { - case JVM_OPC_aload: case JVM_OPC_astore: - case JVM_OPC_fload: case JVM_OPC_fstore: - case JVM_OPC_iload: case JVM_OPC_istore: - case JVM_OPC_lload: case JVM_OPC_lstore: - case JVM_OPC_dload: case JVM_OPC_dstore: - case JVM_OPC_ret: case JVM_OPC_iinc: - break; - default: - CRW_FATAL(ci, "Invalid opcode supplied to wide opcode"); - break; - } -} - -static unsigned -opcode_length(CrwClassImage *ci, ClassOpcode opcode) -{ - /* Define array that holds length of an opcode */ - static unsigned char _opcode_length[JVM_OPC_MAX+1] = - JVM_OPCODE_LENGTH_INITIALIZER; - - if ( opcode > JVM_OPC_MAX ) { - CRW_FATAL(ci, "Invalid opcode supplied to opcode_length()"); - } - return _opcode_length[opcode]; -} - -/* Walk one instruction and inject instrumentation */ -static void -inject_for_opcode(MethodImage *mi) -{ - CrwClassImage * ci; - ClassOpcode opcode; - int pos; - - CRW_ASSERT_MI(mi); - ci = mi->ci; - pos = input_code_offset(mi); - opcode = readU1(ci); - - if (opcode == JVM_OPC_wide) { - ClassOpcode wopcode; - - wopcode = readU1(ci); - /* lvIndex not used */ - (void)readU2(ci); - verify_opc_wide(ci, wopcode); - if ( wopcode==JVM_OPC_iinc ) { - (void)readU1(ci); - (void)readU1(ci); - } - } else { - - ByteCode bytecodes[LARGEST_INJECTION+1]; - int header; - int instr_len; - int low; - int high; - int npairs; - ByteOffset len; - - /* Get bytecodes to inject before this opcode */ - len = before_injection_code(mi, opcode, bytecodes, (int)sizeof(bytecodes)); - if ( len > 0 ) { - inject_bytecodes(mi, pos, bytecodes, len); - /* Adjust map after processing this opcode */ - } - - /* Process this opcode */ - switch (opcode) { - case JVM_OPC_tableswitch: - header = NEXT_4BYTE_BOUNDARY(pos); - skip(ci, header - (pos+1)); - (void)readU4(ci); - low = readU4(ci); - high = readU4(ci); - skip(ci, (high+1-low) * 4); - break; - case JVM_OPC_lookupswitch: - header = NEXT_4BYTE_BOUNDARY(pos); - skip(ci, header - (pos+1)); - (void)readU4(ci); - npairs = readU4(ci); - skip(ci, npairs * 8); - break; - default: - instr_len = opcode_length(ci, opcode); - skip(ci, instr_len-1); - break; - } - - /* Get position after this opcode is processed */ - pos = input_code_offset(mi); - - /* Adjust for any before_injection_code() */ - if ( len > 0 ) { - /* Adjust everything past this opcode. - * Why past it? Because we want any jumps to this bytecode loc - * to go to the injected code, not where the opcode - * was moved too. - * Consider a 'return' opcode that is jumped too. - * NOTE: This may not be correct in all cases, but will - * when we are only dealing with non-variable opcodes - * like the return opcodes. Be careful if the - * before_injection_code() changes to include other - * opcodes that have variable length. - */ - adjust_map(mi, pos, len); - } - - /* Get bytecodes to inject after this opcode */ - len = after_injection_code(mi, opcode, bytecodes, (int)sizeof(bytecodes)); - if ( len > 0 ) { - inject_bytecodes(mi, pos, bytecodes, len); - - /* Adjust for any after_injection_code() */ - adjust_map(mi, pos, len); - } - - } -} - -/* Map original bytecode location to it's new location. (See adjust_map()). */ -static ByteOffset -method_code_map(MethodImage *mi, ByteOffset pos) -{ - CRW_ASSERT_MI(mi); - CRW_ASSERT(mi->ci, pos <= mi->code_len); - return mi->map[pos]; -} - -static int -adjust_instruction(MethodImage *mi) -{ - CrwClassImage * ci; - ClassOpcode opcode; - int pos; - int new_pos; - - CRW_ASSERT_MI(mi); - ci = mi->ci; - pos = input_code_offset(mi); - new_pos = method_code_map(mi,pos); - - opcode = readU1(ci); - - if (opcode == JVM_OPC_wide) { - ClassOpcode wopcode; - - wopcode = readU1(ci); - /* lvIndex not used */ - (void)readU2(ci); - verify_opc_wide(ci, wopcode); - if ( wopcode==JVM_OPC_iinc ) { - (void)readU1(ci); - (void)readU1(ci); - } - } else { - - int widened; - int header; - int newHeader; - int low; - int high; - int new_pad; - int old_pad; - int delta; - int new_delta; - int delta_pad; - int npairs; - int instr_len; - - switch (opcode) { - - case JVM_OPC_tableswitch: - widened = mi->widening[pos]; - header = NEXT_4BYTE_BOUNDARY(pos); - newHeader = NEXT_4BYTE_BOUNDARY(new_pos); - - skip(ci, header - (pos+1)); - - delta = readU4(ci); - low = readU4(ci); - high = readU4(ci); - skip(ci, (high+1-low) * 4); - new_pad = newHeader - new_pos; - old_pad = header - pos; - delta_pad = new_pad - old_pad; - if (widened != delta_pad) { - widen(mi, pos, delta_pad); - return 0; - } - break; - - case JVM_OPC_lookupswitch: - widened = mi->widening[pos]; - header = NEXT_4BYTE_BOUNDARY(pos); - newHeader = NEXT_4BYTE_BOUNDARY(new_pos); - - skip(ci, header - (pos+1)); - - delta = readU4(ci); - npairs = readU4(ci); - skip(ci, npairs * 8); - new_pad = newHeader - new_pos; - old_pad = header - pos; - delta_pad = new_pad - old_pad; - if (widened != delta_pad) { - widen(mi, pos, delta_pad); - return 0; - } - break; - - case JVM_OPC_jsr: case JVM_OPC_goto: - case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt: - case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne: - case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge: - case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt: - case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne: - case JVM_OPC_ifnull: case JVM_OPC_ifnonnull: - widened = mi->widening[pos]; - delta = readS2(ci); - if (widened == 0) { - new_delta = method_code_map(mi,pos+delta) - new_pos; - if ((new_delta < -32768) || (new_delta > 32767)) { - switch (opcode) { - case JVM_OPC_jsr: case JVM_OPC_goto: - widen(mi, pos, 2); - break; - default: - widen(mi, pos, 5); - break; - } - return 0; - } - } - break; - - case JVM_OPC_jsr_w: - case JVM_OPC_goto_w: - (void)readU4(ci); - break; - - default: - instr_len = opcode_length(ci, opcode); - skip(ci, instr_len-1); - break; - } - } - return 1; -} - -static void -write_instruction(MethodImage *mi) -{ - CrwClassImage * ci; - ClassOpcode opcode; - ByteOffset new_code_len; - int pos; - int new_pos; - - CRW_ASSERT_MI(mi); - ci = mi->ci; - pos = input_code_offset(mi); - new_pos = method_code_map(mi,pos); - new_code_len = mi->injections[pos].len; - if (new_code_len > 0) { - write_bytes(ci, (void*)mi->injections[pos].code, new_code_len); - } - - opcode = readU1(ci); - if (opcode == JVM_OPC_wide) { - ClassOpcode wopcode; - - writeU1(ci, opcode); - - wopcode = copyU1(ci); - /* lvIndex not used */ - (void)copyU2(ci); - verify_opc_wide(ci, wopcode); - if ( wopcode==JVM_OPC_iinc ) { - (void)copyU1(ci); - (void)copyU1(ci); - } - } else { - - ClassOpcode new_opcode; - int header; - int newHeader; - int low; - int high; - int i; - int npairs; - int widened; - int instr_len; - int delta; - int new_delta; - - switch (opcode) { - - case JVM_OPC_tableswitch: - header = NEXT_4BYTE_BOUNDARY(pos); - newHeader = NEXT_4BYTE_BOUNDARY(new_pos); - - skip(ci, header - (pos+1)); - - delta = readU4(ci); - new_delta = method_code_map(mi,pos+delta) - new_pos; - low = readU4(ci); - high = readU4(ci); - - writeU1(ci, opcode); - for (i = new_pos+1; i < newHeader; ++i) { - writeU1(ci, 0); - } - writeU4(ci, new_delta); - writeU4(ci, low); - writeU4(ci, high); - - for (i = low; i <= high; ++i) { - delta = readU4(ci); - new_delta = method_code_map(mi,pos+delta) - new_pos; - writeU4(ci, new_delta); - } - break; - - case JVM_OPC_lookupswitch: - header = NEXT_4BYTE_BOUNDARY(pos); - newHeader = NEXT_4BYTE_BOUNDARY(new_pos); - - skip(ci, header - (pos+1)); - - delta = readU4(ci); - new_delta = method_code_map(mi,pos+delta) - new_pos; - npairs = readU4(ci); - writeU1(ci, opcode); - for (i = new_pos+1; i < newHeader; ++i) { - writeU1(ci, 0); - } - writeU4(ci, new_delta); - writeU4(ci, npairs); - for (i = 0; i< npairs; ++i) { - unsigned match = readU4(ci); - delta = readU4(ci); - new_delta = method_code_map(mi,pos+delta) - new_pos; - writeU4(ci, match); - writeU4(ci, new_delta); - } - break; - - case JVM_OPC_jsr: case JVM_OPC_goto: - case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt: - case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne: - case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge: - case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt: - case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne: - case JVM_OPC_ifnull: case JVM_OPC_ifnonnull: - widened = mi->widening[pos]; - delta = readS2(ci); - new_delta = method_code_map(mi,pos+delta) - new_pos; - new_opcode = opcode; - if (widened == 0) { - writeU1(ci, opcode); - writeU2(ci, new_delta); - } else if (widened == 2) { - switch (opcode) { - case JVM_OPC_jsr: - new_opcode = JVM_OPC_jsr_w; - break; - case JVM_OPC_goto: - new_opcode = JVM_OPC_goto_w; - break; - default: - CRW_FATAL(ci, "unexpected opcode"); - break; - } - writeU1(ci, new_opcode); - writeU4(ci, new_delta); - } else if (widened == 5) { - switch (opcode) { - case JVM_OPC_ifeq: - new_opcode = JVM_OPC_ifne; - break; - case JVM_OPC_ifge: - new_opcode = JVM_OPC_iflt; - break; - case JVM_OPC_ifgt: - new_opcode = JVM_OPC_ifle; - break; - case JVM_OPC_ifle: - new_opcode = JVM_OPC_ifgt; - break; - case JVM_OPC_iflt: - new_opcode = JVM_OPC_ifge; - break; - case JVM_OPC_ifne: - new_opcode = JVM_OPC_ifeq; - break; - case JVM_OPC_if_icmpeq: - new_opcode = JVM_OPC_if_icmpne; - break; - case JVM_OPC_if_icmpne: - new_opcode = JVM_OPC_if_icmpeq; - break; - case JVM_OPC_if_icmpge: - new_opcode = JVM_OPC_if_icmplt; - break; - case JVM_OPC_if_icmpgt: - new_opcode = JVM_OPC_if_icmple; - break; - case JVM_OPC_if_icmple: - new_opcode = JVM_OPC_if_icmpgt; - break; - case JVM_OPC_if_icmplt: - new_opcode = JVM_OPC_if_icmpge; - break; - case JVM_OPC_if_acmpeq: - new_opcode = JVM_OPC_if_acmpne; - break; - case JVM_OPC_if_acmpne: - new_opcode = JVM_OPC_if_acmpeq; - break; - case JVM_OPC_ifnull: - new_opcode = JVM_OPC_ifnonnull; - break; - case JVM_OPC_ifnonnull: - new_opcode = JVM_OPC_ifnull; - break; - default: - CRW_FATAL(ci, "Unexpected opcode"); - break; - } - writeU1(ci, new_opcode); /* write inverse branch */ - writeU2(ci, 3 + 5); /* beyond if and goto_w */ - writeU1(ci, JVM_OPC_goto_w); /* add a goto_w */ - writeU4(ci, new_delta-3); /* write new and wide delta */ - } else { - CRW_FATAL(ci, "Unexpected widening"); - } - break; - - case JVM_OPC_jsr_w: - case JVM_OPC_goto_w: - delta = readU4(ci); - new_delta = method_code_map(mi,pos+delta) - new_pos; - writeU1(ci, opcode); - writeU4(ci, new_delta); - break; - - default: - instr_len = opcode_length(ci, opcode); - writeU1(ci, opcode); - copy(ci, instr_len-1); - break; - } - } -} - -static void -method_inject_and_write_code(MethodImage *mi) -{ - ByteCode bytecodes[LARGEST_INJECTION+1]; - ByteOffset len; - - CRW_ASSERT_MI(mi); - - /* Do injections */ - rewind_to_beginning_of_input_bytecodes(mi); - len = entry_injection_code(mi, bytecodes, (int)sizeof(bytecodes)); - if ( len > 0 ) { - int pos; - - pos = 0; - inject_bytecodes(mi, pos, bytecodes, len); - /* Adjust pos 0 to map to new pos 0, you never want to - * jump into this entry code injection. So the new pos 0 - * will be past this entry_injection_code(). - */ - adjust_map(mi, pos, len); /* Inject before behavior */ - } - while (input_code_offset(mi) < mi->code_len) { - inject_for_opcode(mi); - } - - /* Adjust instructions */ - rewind_to_beginning_of_input_bytecodes(mi); - while (input_code_offset(mi) < mi->code_len) { - if (!adjust_instruction(mi)) { - rewind_to_beginning_of_input_bytecodes(mi); - } - } - - /* Write new instructions */ - rewind_to_beginning_of_input_bytecodes(mi); - while (input_code_offset(mi) < mi->code_len) { - write_instruction(mi); - } -} - -static void -copy_attribute(CrwClassImage *ci) -{ - int len; - - (void)copyU2(ci); - len = copyU4(ci); - copy(ci, len); -} - -static void -copy_attributes(CrwClassImage *ci) -{ - unsigned i; - unsigned count; - - count = copyU2(ci); - for (i = 0; i < count; ++i) { - copy_attribute(ci); - } -} - -static void -copy_all_fields(CrwClassImage *ci) -{ - unsigned i; - unsigned count; - - count = copyU2(ci); - for (i = 0; i < count; ++i) { - /* access, name, descriptor */ - copy(ci, 6); - copy_attributes(ci); - } -} - -static void -write_line_table(MethodImage *mi) -{ - unsigned i; - unsigned count; - CrwClassImage * ci; - - CRW_ASSERT_MI(mi); - ci = mi->ci; - (void)copyU4(ci); - count = copyU2(ci); - for(i=0; ici; - (void)copyU4(ci); - count = copyU2(ci); - for(i=0; icode_len > 65535 ) { - return readU4(mi->ci); - } - return readU2(mi->ci); -} - -static void -writeUoffset(MethodImage *mi, unsigned val) -{ - if ( mi->new_code_len > 65535 ) { - writeU4(mi->ci, val); - } - writeU2(mi->ci, val); -} - -static unsigned -copyUoffset(MethodImage *mi) -{ - unsigned uoffset; - - uoffset = readUoffset(mi); - writeUoffset(mi, uoffset); - return uoffset; -} - -/* Copy over verification_type_info structure */ -static void -copy_verification_types(MethodImage *mi, int ntypes) -{ - /* If there were ntypes, we just copy that over, no changes */ - if ( ntypes > 0 ) { - int j; - - for ( j = 0 ; j < ntypes ; j++ ) { - unsigned tag; - - tag = copyU1(mi->ci); - switch ( tag ) { - case JVM_ITEM_Object: - (void)copyU2(mi->ci); /* Constant pool entry */ - break; - case JVM_ITEM_Uninitialized: - /* Code offset for 'new' opcode is for this object */ - writeUoffset(mi, method_code_map(mi, readUoffset(mi))); - break; - } - } - } -} - -/* Process the StackMapTable attribute. We didn't add any basic blocks - * so the frame count remains the same but we may need to process the - * frame types due to offset changes putting things out of range. - */ -static void -write_stackmap_table(MethodImage *mi) -{ - CrwClassImage *ci; - CrwPosition save_position; - ByteOffset last_pc; - ByteOffset last_new_pc; - unsigned i; - unsigned attr_len; - unsigned new_attr_len; - unsigned count; - unsigned delta_adj; - - CRW_ASSERT_MI(mi); - ci = mi->ci; - - /* Save the position of the attribute length so we can fix it later */ - save_position = ci->output_position; - attr_len = copyU4(ci); - count = copyUoffset(mi); /* uoffset: number_of_entries */ - if ( count == 0 ) { - CRW_ASSERT(ci, attr_len==2); - return; - } - - /* Process entire stackmap */ - last_pc = 0; - last_new_pc = 0; - delta_adj = 0; - for ( i = 0 ; i < count ; i++ ) { - ByteOffset new_pc=0; /* new pc in instrumented code */ - unsigned ft; /* frame_type */ - int delta=0; /* pc delta */ - int new_delta=0; /* new pc delta */ - - ft = readU1(ci); - if ( ft <= 63 ) { - /* Frame Type: same_frame ([0,63]) */ - unsigned new_ft; /* new frame_type */ - - delta = (delta_adj + ft); - new_pc = method_code_map(mi, last_pc + delta); - new_delta = new_pc - last_new_pc; - new_ft = (new_delta - delta_adj); - if ( new_ft > 63 ) { - /* Change to same_frame_extended (251) */ - new_ft = 251; - writeU1(ci, new_ft); - writeUoffset(mi, (new_delta - delta_adj)); - } else { - writeU1(ci, new_ft); - } - } else if ( ft >= 64 && ft <= 127 ) { - /* Frame Type: same_locals_1_stack_item_frame ([64,127]) */ - unsigned new_ft; /* new frame_type */ - - delta = (delta_adj + ft - 64); - new_pc = method_code_map(mi, last_pc + delta); - new_delta = new_pc - last_new_pc; - if ( (new_delta - delta_adj) > 63 ) { - /* Change to same_locals_1_stack_item_frame_extended (247) */ - new_ft = 247; - writeU1(ci, new_ft); - writeUoffset(mi, (new_delta - delta_adj)); - } else { - new_ft = (new_delta - delta_adj) + 64; - writeU1(ci, new_ft); - } - copy_verification_types(mi, 1); - } else if ( ft >= 128 && ft <= 246 ) { - /* Frame Type: reserved_for_future_use ([128,246]) */ - CRW_FATAL(ci, "Unknown frame type in StackMapTable attribute"); - } else if ( ft == 247 ) { - /* Frame Type: same_locals_1_stack_item_frame_extended (247) */ - delta = (delta_adj + readUoffset(mi)); - new_pc = method_code_map(mi, last_pc + delta); - new_delta = new_pc - last_new_pc; - writeU1(ci, ft); - writeUoffset(mi, (new_delta - delta_adj)); - copy_verification_types(mi, 1); - } else if ( ft >= 248 && ft <= 250 ) { - /* Frame Type: chop_frame ([248,250]) */ - delta = (delta_adj + readUoffset(mi)); - new_pc = method_code_map(mi, last_pc + delta); - new_delta = new_pc - last_new_pc; - writeU1(ci, ft); - writeUoffset(mi, (new_delta - delta_adj)); - } else if ( ft == 251 ) { - /* Frame Type: same_frame_extended (251) */ - delta = (delta_adj + readUoffset(mi)); - new_pc = method_code_map(mi, last_pc + delta); - new_delta = new_pc - last_new_pc; - writeU1(ci, ft); - writeUoffset(mi, (new_delta - delta_adj)); - } else if ( ft >= 252 && ft <= 254 ) { - /* Frame Type: append_frame ([252,254]) */ - delta = (delta_adj + readUoffset(mi)); - new_pc = method_code_map(mi, last_pc + delta); - new_delta = new_pc - last_new_pc; - writeU1(ci, ft); - writeUoffset(mi, (new_delta - delta_adj)); - copy_verification_types(mi, (ft - 251)); - } else if ( ft == 255 ) { - unsigned ntypes; - - /* Frame Type: full_frame (255) */ - delta = (delta_adj + readUoffset(mi)); - new_pc = method_code_map(mi, last_pc + delta); - new_delta = new_pc - last_new_pc; - writeU1(ci, ft); - writeUoffset(mi, (new_delta - delta_adj)); - ntypes = copyU2(ci); /* ulocalvar */ - copy_verification_types(mi, ntypes); - ntypes = copyU2(ci); /* ustack */ - copy_verification_types(mi, ntypes); - } - - /* Update last_pc and last_new_pc (save on calls to method_code_map) */ - CRW_ASSERT(ci, delta >= 0); - CRW_ASSERT(ci, new_delta >= 0); - last_pc += delta; - last_new_pc = new_pc; - CRW_ASSERT(ci, last_pc <= mi->code_len); - CRW_ASSERT(ci, last_new_pc <= mi->new_code_len); - - /* Delta adjustment, all deltas are -1 now in attribute */ - delta_adj = 1; - } - - /* Update the attribute length */ - new_attr_len = ci->output_position - (save_position + 4); - CRW_ASSERT(ci, new_attr_len >= attr_len); - random_writeU4(ci, save_position, new_attr_len); -} - -/* Process the CLDC StackMap attribute. We didn't add any basic blocks - * so the frame count remains the same but we may need to process the - * frame types due to offset changes putting things out of range. - */ -static void -write_cldc_stackmap_table(MethodImage *mi) -{ - CrwClassImage *ci; - CrwPosition save_position; - unsigned i; - unsigned attr_len; - unsigned new_attr_len; - unsigned count; - - CRW_ASSERT_MI(mi); - ci = mi->ci; - - /* Save the position of the attribute length so we can fix it later */ - save_position = ci->output_position; - attr_len = copyU4(ci); - count = copyUoffset(mi); /* uoffset: number_of_entries */ - if ( count == 0 ) { - CRW_ASSERT(ci, attr_len==2); - return; - } - - /* Process entire stackmap */ - for ( i = 0 ; i < count ; i++ ) { - unsigned ntypes; - - writeUoffset(mi, method_code_map(mi, readUoffset(mi))); - ntypes = copyU2(ci); /* ulocalvar */ - copy_verification_types(mi, ntypes); - ntypes = copyU2(ci); /* ustack */ - copy_verification_types(mi, ntypes); - } - - /* Update the attribute length */ - new_attr_len = ci->output_position - (save_position + 4); - CRW_ASSERT(ci, new_attr_len >= attr_len); - random_writeU4(ci, save_position, new_attr_len); -} - -static void -method_write_exception_table(MethodImage *mi) -{ - unsigned i; - unsigned count; - CrwClassImage * ci; - - CRW_ASSERT_MI(mi); - ci = mi->ci; - count = copyU2(ci); - for(i=0; ici; - name_index = copyU2(ci); - if ( attribute_match(ci, name_index, "LineNumberTable") ) { - write_line_table(mi); - } else if ( attribute_match(ci, name_index, "LocalVariableTable") ) { - write_var_table(mi); - } else if ( attribute_match(ci, name_index, "LocalVariableTypeTable") ) { - write_var_table(mi); /* Exact same format as the LocalVariableTable */ - } else if ( attribute_match(ci, name_index, "StackMapTable") ) { - write_stackmap_table(mi); - } else if ( attribute_match(ci, name_index, "StackMap") ) { - write_cldc_stackmap_table(mi); - } else { - unsigned len; - len = copyU4(ci); - copy(ci, len); - } -} - -static int -is_init_method(const char *name) -{ - if ( name!=NULL && strcmp(name,"")==0 ) { - return JNI_TRUE; - } - return JNI_FALSE; -} - -static int -is_clinit_method(const char *name) -{ - if ( name!=NULL && strcmp(name,"")==0 ) { - return JNI_TRUE; - } - return JNI_FALSE; -} - -static int -is_finalize_method(const char *name) -{ - if ( name!=NULL && strcmp(name,"finalize")==0 ) { - return JNI_TRUE; - } - return JNI_FALSE; -} - -static int -skip_method(CrwClassImage *ci, const char *name, - unsigned access_flags, ByteOffset code_len, - int system_class, jboolean *pskip_call_return_sites) -{ - *pskip_call_return_sites = JNI_FALSE; - if ( system_class ) { - if ( code_len == 1 && is_init_method(name) ) { - return JNI_TRUE; - } else if ( code_len == 1 && is_finalize_method(name) ) { - return JNI_TRUE; - } else if ( is_clinit_method(name) ) { - return JNI_TRUE; - } else if ( ci->is_thread_class && strcmp(name,"currentThread")==0 ) { - return JNI_TRUE; - } - /* - if ( access_flags & JVM_ACC_PRIVATE ) { - *pskip_call_return_sites = JNI_TRUE; - } - */ - } - return JNI_FALSE; -} - -/* Process all code attributes */ -static void -method_write_bytecodes(CrwClassImage *ci, unsigned mnum, unsigned access_flags) -{ - CrwPosition output_attr_len_position; - CrwPosition output_max_stack_position; - CrwPosition output_code_len_position; - CrwPosition start_of_output_bytecodes; - unsigned i; - unsigned attr_len; - unsigned max_stack; - ByteOffset code_len; - unsigned attr_count; - unsigned new_attr_len; - MethodImage * mi; - jboolean object_init_method; - jboolean skip_call_return_sites; - - CRW_ASSERT_CI(ci); - - /* Attribute Length */ - output_attr_len_position = ci->output_position; - attr_len = copyU4(ci); - - /* Max Stack */ - output_max_stack_position = ci->output_position; - max_stack = copyU2(ci); - - /* Max Locals */ - (void)copyU2(ci); - - /* Code Length */ - output_code_len_position = ci->output_position; - code_len = copyU4(ci); - start_of_output_bytecodes = ci->output_position; - - /* Some methods should not be instrumented */ - object_init_method = JNI_FALSE; - skip_call_return_sites = JNI_FALSE; - if ( ci->is_object_class && - is_init_method(ci->method_name[mnum]) && - strcmp(ci->method_descr[mnum],"()V")==0 ) { - object_init_method = JNI_TRUE; - skip_call_return_sites = JNI_TRUE; - } else if ( skip_method(ci, ci->method_name[mnum], access_flags, - code_len, ci->system_class, &skip_call_return_sites) ) { - /* Copy remainder minus already copied, the U2 max_stack, - * U2 max_locals, and U4 code_length fields have already - * been processed. - */ - copy(ci, attr_len - (2+2+4)); - return; - } - - /* Start Injection */ - mi = method_init(ci, mnum, code_len); - mi->object_init_method = object_init_method; - mi->access_flags = access_flags; - mi->skip_call_return_sites = skip_call_return_sites; - - /* Save the current position as the start of the input bytecodes */ - mi->start_of_input_bytecodes = ci->input_position; - - /* The max stack may increase */ - mi->max_stack = max_stack; - mi->new_max_stack = max_stack; - - /* Adjust all code offsets */ - method_inject_and_write_code(mi); - - /* Fix up code length (save new_code_len for later attribute processing) */ - mi->new_code_len = (int)(ci->output_position - start_of_output_bytecodes); - random_writeU4(ci, output_code_len_position, mi->new_code_len); - - /* Fixup max stack */ - CRW_ASSERT(ci, mi->new_max_stack <= 0xFFFF); - random_writeU2(ci, output_max_stack_position, mi->new_max_stack); - - /* Copy exception table */ - method_write_exception_table(mi); - - /* Copy code attributes (needs mi->new_code_len) */ - attr_count = copyU2(ci); - for (i = 0; i < attr_count; ++i) { - method_write_code_attribute(mi); - } - - /* Fix up attribute length */ - new_attr_len = (int)(ci->output_position - (output_attr_len_position + 4)); - random_writeU4(ci, output_attr_len_position, new_attr_len); - - /* Free method data */ - method_term(mi); - mi = NULL; - -} - -static void -method_write(CrwClassImage *ci, unsigned mnum) -{ - unsigned i; - unsigned access_flags; - CrwCpoolIndex name_index; - CrwCpoolIndex descr_index; - unsigned attr_count; - - access_flags = copyU2(ci); - name_index = copyU2(ci); - ci->method_name[mnum] = cpool_entry(ci, name_index).ptr; - descr_index = copyU2(ci); - ci->method_descr[mnum] = cpool_entry(ci, descr_index).ptr; - attr_count = copyU2(ci); - - for (i = 0; i < attr_count; ++i) { - CrwCpoolIndex name_index; - - name_index = copyU2(ci); - if ( attribute_match(ci, name_index, "Code") ) { - method_write_bytecodes(ci, mnum, access_flags); - } else { - unsigned len; - len = copyU4(ci); - copy(ci, len); - } - } -} - -static void -method_write_all(CrwClassImage *ci) -{ - unsigned i; - unsigned count; - - count = copyU2(ci); - ci->method_count = count; - if ( count > 0 ) { - ci->method_name = (const char **)allocate_clean(ci, count*(int)sizeof(const char*)); - ci->method_descr = (const char **)allocate_clean(ci, count*(int)sizeof(const char*)); - } - - for (i = 0; i < count; ++i) { - method_write(ci, i); - } - - if ( ci->mnum_callback != NULL ) { - (*(ci->mnum_callback))(ci->number, ci->method_name, ci->method_descr, - count); - } -} - -/* ------------------------------------------------------------------- */ -/* Cleanup function. */ - -static void -cleanup(CrwClassImage *ci) -{ - CRW_ASSERT_CI(ci); - if ( ci->name != NULL ) { - deallocate(ci, (void*)ci->name); - ci->name = NULL; - } - if ( ci->method_name != NULL ) { - deallocate(ci, (void*)ci->method_name); - ci->method_name = NULL; - } - if ( ci->method_descr != NULL ) { - deallocate(ci, (void*)ci->method_descr); - ci->method_descr = NULL; - } - if ( ci->cpool != NULL ) { - CrwCpoolIndex i; - for(i=0; icpool_count_plus_one; i++) { - if ( ci->cpool[i].ptr != NULL ) { - deallocate(ci, (void*)(ci->cpool[i].ptr)); - ci->cpool[i].ptr = NULL; - } - } - deallocate(ci, (void*)ci->cpool); - ci->cpool = NULL; - } -} - -static jboolean -skip_class(unsigned access_flags) -{ - if ( access_flags & JVM_ACC_INTERFACE ) { - return JNI_TRUE; - } - return JNI_FALSE; -} - -static long -inject_class(struct CrwClassImage *ci, - int system_class, - char* tclass_name, - char* tclass_sig, - char* call_name, - char* call_sig, - char* return_name, - char* return_sig, - char* obj_init_name, - char* obj_init_sig, - char* newarray_name, - char* newarray_sig, - unsigned char *buf, - long buf_len) -{ - CrwConstantPoolEntry cs; - CrwCpoolIndex this_class; - CrwCpoolIndex super_class; - unsigned magic; - unsigned classfileMajorVersion; - unsigned classfileMinorVersion; - unsigned interface_count; - - CRW_ASSERT_CI(ci); - CRW_ASSERT(ci, buf!=NULL); - CRW_ASSERT(ci, buf_len!=0); - - CRW_ASSERT(ci, strchr(tclass_name,'.')==NULL); /* internal qualified name */ - - ci->injection_count = 0; - ci->system_class = system_class; - ci->tclass_name = tclass_name; - ci->tclass_sig = tclass_sig; - ci->call_name = call_name; - ci->call_sig = call_sig; - ci->return_name = return_name; - ci->return_sig = return_sig; - ci->obj_init_name = obj_init_name; - ci->obj_init_sig = obj_init_sig; - ci->newarray_name = newarray_name; - ci->newarray_sig = newarray_sig; - ci->output = buf; - ci->output_len = buf_len; - - magic = copyU4(ci); - CRW_ASSERT(ci, magic==0xCAFEBABE); - if ( magic != 0xCAFEBABE ) { - return (long)0; - } - - /* minor version number not used */ - classfileMinorVersion = copyU2(ci); - /* major version number not used */ - classfileMajorVersion = copyU2(ci); - CRW_ASSERT(ci, (classfileMajorVersion <= JVM_CLASSFILE_MAJOR_VERSION) || - ((classfileMajorVersion == JVM_CLASSFILE_MAJOR_VERSION) && - (classfileMinorVersion <= JVM_CLASSFILE_MINOR_VERSION))); - - cpool_setup(ci); - - ci->access_flags = copyU2(ci); - if ( skip_class(ci->access_flags) ) { - return (long)0; - } - - this_class = copyU2(ci); - - cs = cpool_entry(ci, (CrwCpoolIndex)(cpool_entry(ci, this_class).index1)); - if ( ci->name == NULL ) { - ci->name = duplicate(ci, cs.ptr, cs.len); - CRW_ASSERT(ci, strchr(ci->name,'.')==NULL); /* internal qualified name */ - } - CRW_ASSERT(ci, (int)strlen(ci->name)==cs.len && strncmp(ci->name, cs.ptr, cs.len)==0); - - super_class = copyU2(ci); - if ( super_class == 0 ) { - ci->is_object_class = JNI_TRUE; - CRW_ASSERT(ci, strcmp(ci->name,"java/lang/Object")==0); - } - - interface_count = copyU2(ci); - copy(ci, interface_count * 2); - - copy_all_fields(ci); - - method_write_all(ci); - - if ( ci->injection_count == 0 ) { - return (long)0; - } - - copy_attributes(ci); - - return (long)ci->output_position; -} - -/* ------------------------------------------------------------------- */ -/* Exported interfaces */ - -JNIEXPORT void JNICALL -java_crw_demo(unsigned class_number, - const char *name, - const unsigned char *file_image, - long file_len, - int system_class, - char* tclass_name, /* Name of class that has tracker methods. */ - char* tclass_sig, /* Signature of tclass */ - char* call_name, /* Method name to call at offset 0 */ - char* call_sig, /* Signature of this method */ - char* return_name, /* Method name to call before any return */ - char* return_sig, /* Signature of this method */ - char* obj_init_name, /* Method name to call in Object */ - char* obj_init_sig, /* Signature of this method */ - char* newarray_name, /* Method name to call after newarray opcodes */ - char* newarray_sig, /* Signature of this method */ - unsigned char **pnew_file_image, - long *pnew_file_len, - FatalErrorHandler fatal_error_handler, - MethodNumberRegister mnum_callback) -{ - CrwClassImage ci; - long max_length; - long new_length; - void *new_image; - int len; - - /* Initial setup of the CrwClassImage structure */ - (void)memset(&ci, 0, (int)sizeof(CrwClassImage)); - ci.fatal_error_handler = fatal_error_handler; - ci.mnum_callback = mnum_callback; - - /* Do some interface error checks */ - if ( pnew_file_image==NULL ) { - CRW_FATAL(&ci, "pnew_file_image==NULL"); - } - if ( pnew_file_len==NULL ) { - CRW_FATAL(&ci, "pnew_file_len==NULL"); - } - - /* No file length means do nothing */ - *pnew_file_image = NULL; - *pnew_file_len = 0; - if ( file_len==0 ) { - return; - } - - /* Do some more interface error checks */ - if ( file_image == NULL ) { - CRW_FATAL(&ci, "file_image == NULL"); - } - if ( file_len < 0 ) { - CRW_FATAL(&ci, "file_len < 0"); - } - if ( system_class != 0 && system_class != 1 ) { - CRW_FATAL(&ci, "system_class is not 0 or 1"); - } - if ( tclass_name == NULL ) { - CRW_FATAL(&ci, "tclass_name == NULL"); - } - if ( tclass_sig == NULL || tclass_sig[0]!='L' ) { - CRW_FATAL(&ci, "tclass_sig is not a valid class signature"); - } - len = (int)strlen(tclass_sig); - if ( tclass_sig[len-1]!=';' ) { - CRW_FATAL(&ci, "tclass_sig is not a valid class signature"); - } - if ( call_name != NULL ) { - if ( call_sig == NULL || strcmp(call_sig, "(II)V") != 0 ) { - CRW_FATAL(&ci, "call_sig is not (II)V"); - } - } - if ( return_name != NULL ) { - if ( return_sig == NULL || strcmp(return_sig, "(II)V") != 0 ) { - CRW_FATAL(&ci, "return_sig is not (II)V"); - } - } - if ( obj_init_name != NULL ) { - if ( obj_init_sig == NULL || strcmp(obj_init_sig, "(Ljava/lang/Object;)V") != 0 ) { - CRW_FATAL(&ci, "obj_init_sig is not (Ljava/lang/Object;)V"); - } - } - if ( newarray_name != NULL ) { - if ( newarray_sig == NULL || strcmp(newarray_sig, "(Ljava/lang/Object;)V") != 0 ) { - CRW_FATAL(&ci, "newarray_sig is not (Ljava/lang/Object;)V"); - } - } - - /* Finish setup the CrwClassImage structure */ - ci.is_thread_class = JNI_FALSE; - if ( name != NULL ) { - CRW_ASSERT(&ci, strchr(name,'.')==NULL); /* internal qualified name */ - - ci.name = duplicate(&ci, name, (int)strlen(name)); - if ( strcmp(name, "java/lang/Thread")==0 ) { - ci.is_thread_class = JNI_TRUE; - } - } - ci.number = class_number; - ci.input = file_image; - ci.input_len = file_len; - - /* Do the injection */ - max_length = file_len*2 + 512; /* Twice as big + 512 */ - new_image = allocate(&ci, (int)max_length); - new_length = inject_class(&ci, - system_class, - tclass_name, - tclass_sig, - call_name, - call_sig, - return_name, - return_sig, - obj_init_name, - obj_init_sig, - newarray_name, - newarray_sig, - new_image, - max_length); - - /* Dispose or shrink the space to be returned. */ - if ( new_length == 0 ) { - deallocate(&ci, (void*)new_image); - new_image = NULL; - } else { - new_image = (void*)reallocate(&ci, (void*)new_image, (int)new_length); - } - - /* Return the new class image */ - *pnew_file_image = (unsigned char *)new_image; - *pnew_file_len = (long)new_length; - - /* Cleanup before we leave. */ - cleanup(&ci); -} - -/* Return the classname for this class which is inside the classfile image. */ -JNIEXPORT char * JNICALL -java_crw_demo_classname(const unsigned char *file_image, long file_len, - FatalErrorHandler fatal_error_handler) -{ - CrwClassImage ci; - CrwConstantPoolEntry cs; - CrwCpoolIndex this_class; - unsigned magic; - char * name; - - name = NULL; - - if ( file_len==0 || file_image==NULL ) { - return name; - } - - /* The only fields we need filled in are the image pointer and the error - * handler. - * By not adding an output buffer pointer, no output is created. - */ - (void)memset(&ci, 0, (int)sizeof(CrwClassImage)); - ci.input = file_image; - ci.input_len = file_len; - ci.fatal_error_handler = fatal_error_handler; - - /* Read out the bytes from the classfile image */ - - magic = readU4(&ci); /* magic number */ - CRW_ASSERT(&ci, magic==0xCAFEBABE); - if ( magic != 0xCAFEBABE ) { - return name; - } - (void)readU2(&ci); /* minor version number */ - (void)readU2(&ci); /* major version number */ - - /* Read in constant pool. Since no output setup, writes are NOP's */ - cpool_setup(&ci); - - (void)readU2(&ci); /* access flags */ - this_class = readU2(&ci); /* 'this' class */ - - /* Get 'this' constant pool entry */ - cs = cpool_entry(&ci, (CrwCpoolIndex)(cpool_entry(&ci, this_class).index1)); - - /* Duplicate the name */ - name = (char *)duplicate(&ci, cs.ptr, cs.len); - - /* Cleanup before we leave. */ - cleanup(&ci); - - /* Return malloc space */ - return name; -} diff --git a/jdk/src/demo/share/jvmti/java_crw_demo/java_crw_demo.h b/jdk/src/demo/share/jvmti/java_crw_demo/java_crw_demo.h deleted file mode 100644 index e2626784341..00000000000 --- a/jdk/src/demo/share/jvmti/java_crw_demo/java_crw_demo.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#ifndef JAVA_CRW_DEMO_H -#define JAVA_CRW_DEMO_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* This callback is used to notify the caller of a fatal error. */ - -typedef void (*FatalErrorHandler)(const char*message, const char*file, int line); - -/* This callback is used to return the method information for a class. - * Since the information was already read here, it was useful to - * return it here, with no JVMTI phase restrictions. - * If the class file does represent a "class" and it has methods, then - * this callback will be called with the class number and pointers to - * the array of names, array of signatures, and the count of methods. - */ - -typedef void (*MethodNumberRegister)(unsigned, const char**, const char**, int); - -/* Class file reader/writer interface. Basic input is a classfile image - * and details about what to inject. The output is a new classfile image - * that was allocated with malloc(), and should be freed by the caller. - */ - -/* Names of external symbols to look for. These are the names that we - * try and lookup in the shared library. On Windows 2000, the naming - * convention is to prefix a "_" and suffix a "@N" where N is 4 times - * the number or arguments supplied.It has 19 args, so 76 = 19*4. - * On Windows 2003, Linux, and Solaris, the first name will be - * found, on Windows 2000 a second try should find the second name. - * - * WARNING: If You change the JavaCrwDemo typedef, you MUST change - * multiple things in this file, including this name. - */ - -#define JAVA_CRW_DEMO_SYMBOLS { "java_crw_demo", "_java_crw_demo@76" } - -/* Typedef needed for type casting in dynamic access situations. */ - -typedef void (JNICALL *JavaCrwDemo)( - unsigned class_number, - const char *name, - const unsigned char *file_image, - long file_len, - int system_class, - char* tclass_name, - char* tclass_sig, - char* call_name, - char* call_sig, - char* return_name, - char* return_sig, - char* obj_init_name, - char* obj_init_sig, - char* newarray_name, - char* newarray_sig, - unsigned char **pnew_file_image, - long *pnew_file_len, - FatalErrorHandler fatal_error_handler, - MethodNumberRegister mnum_callback -); - -/* Function export (should match typedef above) */ - -JNIEXPORT void JNICALL java_crw_demo( - - unsigned class_number, /* Caller assigned class number for class */ - - const char *name, /* Internal class name, e.g. java/lang/Object */ - /* (Do not use "java.lang.Object" format) */ - - const unsigned char - *file_image, /* Pointer to classfile image for this class */ - - long file_len, /* Length of the classfile in bytes */ - - int system_class, /* Set to 1 if this is a system class */ - /* (prevents injections into empty */ - /* , finalize, and methods) */ - - char* tclass_name, /* Class that has methods we will call at */ - /* the injection sites (tclass) */ - - char* tclass_sig, /* Signature of tclass */ - /* (Must be "L" + tclass_name + ";") */ - - char* call_name, /* Method name in tclass to call at offset 0 */ - /* for every method */ - - char* call_sig, /* Signature of this call_name method */ - /* (Must be "(II)V") */ - - char* return_name, /* Method name in tclass to call at all */ - /* return opcodes in every method */ - - char* return_sig, /* Signature of this return_name method */ - /* (Must be "(II)V") */ - - char* obj_init_name, /* Method name in tclass to call first thing */ - /* when injecting java.lang.Object. */ - - char* obj_init_sig, /* Signature of this obj_init_name method */ - /* (Must be "(Ljava/lang/Object;)V") */ - - char* newarray_name, /* Method name in tclass to call after every */ - /* newarray opcode in every method */ - - char* newarray_sig, /* Signature of this method */ - /* (Must be "(Ljava/lang/Object;II)V") */ - - unsigned char - **pnew_file_image, /* Returns a pointer to new classfile image */ - - long *pnew_file_len, /* Returns the length of the new image */ - - FatalErrorHandler - fatal_error_handler, /* Pointer to function to call on any */ - /* fatal error. NULL sends error to stderr */ - - MethodNumberRegister - mnum_callback /* Pointer to function that gets called */ - /* with all details on methods in this */ - /* class. NULL means skip this call. */ - - ); - - -/* External to read the class name out of a class file . - * - * WARNING: If You change the typedef, you MUST change - * multiple things in this file, including this name. - */ - -#define JAVA_CRW_DEMO_CLASSNAME_SYMBOLS \ - { "java_crw_demo_classname", "_java_crw_demo_classname@12" } - -/* Typedef needed for type casting in dynamic access situations. */ - -typedef char * (JNICALL *JavaCrwDemoClassname)( - const unsigned char *file_image, - long file_len, - FatalErrorHandler fatal_error_handler); - -JNIEXPORT char * JNICALL java_crw_demo_classname( - const unsigned char *file_image, - long file_len, - FatalErrorHandler fatal_error_handler); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif diff --git a/jdk/src/demo/share/jvmti/java_crw_demo/sample.makefile.txt b/jdk/src/demo/share/jvmti/java_crw_demo/sample.makefile.txt deleted file mode 100644 index 81ce07938d4..00000000000 --- a/jdk/src/demo/share/jvmti/java_crw_demo/sample.makefile.txt +++ /dev/null @@ -1,144 +0,0 @@ -# -# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=java_crw_demo -SOURCES=java_crw_demo.c - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES=-lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES= - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule (build both native library and jar file) -all: $(LIBRARY) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Cleanup the built bits -clean: - rm -f -r classes - rm -f $(LIBRARY) $(OBJECTS) - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/minst/Minst.java b/jdk/src/demo/share/jvmti/minst/Minst.java deleted file mode 100644 index 2826cea04ba..00000000000 --- a/jdk/src/demo/share/jvmti/minst/Minst.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - - -/* Java class to hold static methods which will be called in byte code - * injections of all class files. - */ - -public class Minst { - - /* Master switch that activates methods. */ - - private static int engaged = 0; - - /* At the very beginning of every method, a call to method_entry() - * is injected. - */ - - public static void method_entry(int cnum, int mnum) { - Class x = Minst.class; - synchronized ( x ) { - if ( engaged > 0 ) { - engaged = 0; - String className = "Unknown"; - String methodName = "Unknown"; - Exception exp = new Exception(); - StackTraceElement[] stack = exp.getStackTrace(); - if (stack.length > 1) { - StackTraceElement location = stack[1]; - className = location.getClassName(); - methodName = location.getMethodName(); - } - System.out.println("Reached method entry: " + - className + "." + methodName + "()"); - engaged++; - } - } - } - -} diff --git a/jdk/src/demo/share/jvmti/minst/README.txt b/jdk/src/demo/share/jvmti/minst/README.txt deleted file mode 100644 index 3cc9b4fff3c..00000000000 --- a/jdk/src/demo/share/jvmti/minst/README.txt +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -minst - -This agent library can be used to inject code at method calls. -It uses the same java_crw_demo library used by HPROF to do BCI on all -or selected classfiles loaded into the Virtual Machine. -The class Minst.java can be customized to do whatever you wish, -within reason of course, and does not call native methods directly. - -You can use this agent library as follows: - - java -agentlib:minst ... - -To get help on the available options try: - - java -agentlib:minst=help - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - diff --git a/jdk/src/demo/share/jvmti/minst/minst.c b/jdk/src/demo/share/jvmti/minst/minst.c deleted file mode 100644 index 8317c1d3d61..00000000000 --- a/jdk/src/demo/share/jvmti/minst/minst.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include "stdlib.h" - -#include "minst.h" -#include "java_crw_demo.h" - - -/* ------------------------------------------------------------------- */ -/* Some constant maximum sizes */ - -#define MAX_TOKEN_LENGTH 80 -#define MAX_METHOD_NAME_LENGTH 256 - -/* Some constant names that tie to Java class/method names. - * We assume the Java class whose static methods we will be calling - * looks like: - * - * public class Minst { - * private static int engaged; - * private static native void _method_entry(Object thr, int cnum, int mnum); - * public static void method_entry(int cnum, int mnum) - * { - * ... - * } - * } - * - */ - -#define MINST_class Minst /* Name of class we are using */ -#define MINST_entry method_entry /* Name of java entry method */ -#define MINST_engaged engaged /* Name of java static field */ - -/* C macros to create strings from tokens */ -#define _STRING(s) #s -#define STRING(s) _STRING(s) - -/* ------------------------------------------------------------------- */ - -/* Global agent data structure */ - -typedef struct { - /* JVMTI Environment */ - jvmtiEnv *jvmti; - jboolean vm_is_dead; - jboolean vm_is_started; - /* Data access Lock */ - jrawMonitorID lock; - /* Options */ - char *include; - char *exclude; - /* Class Count/ID */ - jint ccount; -} GlobalAgentData; - -static GlobalAgentData *gdata; - -/* Enter a critical section by doing a JVMTI Raw Monitor Enter */ -static void -enter_critical_section(jvmtiEnv *jvmti) -{ - jvmtiError error; - - error = (*jvmti)->RawMonitorEnter(jvmti, gdata->lock); - check_jvmti_error(jvmti, error, "Cannot enter with raw monitor"); -} - -/* Exit a critical section by doing a JVMTI Raw Monitor Exit */ -static void -exit_critical_section(jvmtiEnv *jvmti) -{ - jvmtiError error; - - error = (*jvmti)->RawMonitorExit(jvmti, gdata->lock); - check_jvmti_error(jvmti, error, "Cannot exit with raw monitor"); -} - -/* Callback for JVMTI_EVENT_VM_START */ -static void JNICALL -cbVMStart(jvmtiEnv *jvmti, JNIEnv *env) -{ - enter_critical_section(jvmti); { - /* Indicate VM has started */ - gdata->vm_is_started = JNI_TRUE; - } exit_critical_section(jvmti); -} - -/* Callback for JVMTI_EVENT_VM_INIT */ -static void JNICALL -cbVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - enter_critical_section(jvmti); { - jclass klass; - jfieldID field; - - /* Register Natives for class whose methods we use */ - klass = (*env)->FindClass(env, STRING(MINST_class)); - if ( klass == NULL ) { - fatal_error("ERROR: JNI: Cannot find %s with FindClass\n", - STRING(MINST_class)); - } - - /* Engage calls. */ - field = (*env)->GetStaticFieldID(env, klass, STRING(MINST_engaged), "I"); - if ( field == NULL ) { - fatal_error("ERROR: JNI: Cannot get field from %s\n", - STRING(MINST_class)); - } - (*env)->SetStaticIntField(env, klass, field, 1); - } exit_critical_section(jvmti); -} - -/* Callback for JVMTI_EVENT_VM_DEATH */ -static void JNICALL -cbVMDeath(jvmtiEnv *jvmti, JNIEnv *env) -{ - enter_critical_section(jvmti); { - jclass klass; - jfieldID field; - - /* The VM has died. */ - stdout_message("VMDeath\n"); - - /* Disengage calls in MINST_class. */ - klass = (*env)->FindClass(env, STRING(MINST_class)); - if ( klass == NULL ) { - fatal_error("ERROR: JNI: Cannot find %s with FindClass\n", - STRING(MINST_class)); - } - field = (*env)->GetStaticFieldID(env, klass, STRING(MINST_engaged), "I"); - if ( field == NULL ) { - fatal_error("ERROR: JNI: Cannot get field from %s\n", - STRING(MINST_class)); - } - (*env)->SetStaticIntField(env, klass, field, -1); - - /* The critical section here is important to hold back the VM death - * until all other callbacks have completed. - */ - - /* Since this critical section could be holding up other threads - * in other event callbacks, we need to indicate that the VM is - * dead so that the other callbacks can short circuit their work. - * We don't expect any further events after VmDeath but we do need - * to be careful that existing threads might be in our own agent - * callback code. - */ - gdata->vm_is_dead = JNI_TRUE; - - } exit_critical_section(jvmti); - -} - -/* Callback for JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */ -static void JNICALL -cbClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv* env, - jclass class_being_redefined, jobject loader, - const char* name, jobject protection_domain, - jint class_data_len, const unsigned char* class_data, - jint* new_class_data_len, unsigned char** new_class_data) -{ - enter_critical_section(jvmti); { - /* It's possible we get here right after VmDeath event, be careful */ - if ( !gdata->vm_is_dead ) { - - const char *classname; - - /* Name could be NULL */ - if ( name == NULL ) { - classname = java_crw_demo_classname(class_data, class_data_len, - NULL); - if ( classname == NULL ) { - fatal_error("ERROR: No classname inside classfile\n"); - } - } else { - classname = strdup(name); - if ( classname == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - } - - *new_class_data_len = 0; - *new_class_data = NULL; - - /* The tracker class itself? */ - if ( interested((char*)classname, "", gdata->include, gdata->exclude) - && strcmp(classname, STRING(MINST_class)) != 0 ) { - jint cnum; - int system_class; - unsigned char *new_image; - long new_length; - - /* Get unique number for every class file image loaded */ - cnum = gdata->ccount++; - - /* Is it a system class? If the class load is before VmStart - * then we will consider it a system class that should - * be treated carefully. (See java_crw_demo) - */ - system_class = 0; - if ( !gdata->vm_is_started ) { - system_class = 1; - } - - new_image = NULL; - new_length = 0; - - /* Call the class file reader/write demo code */ - java_crw_demo(cnum, - classname, - class_data, - class_data_len, - system_class, - STRING(MINST_class), "L" STRING(MINST_class) ";", - STRING(MINST_entry), "(II)V", - NULL, NULL, - NULL, NULL, - NULL, NULL, - &new_image, - &new_length, - NULL, - NULL); - - /* If we got back a new class image, return it back as "the" - * new class image. This must be JVMTI Allocate space. - */ - if ( new_length > 0 ) { - unsigned char *jvmti_space; - - jvmti_space = (unsigned char *)allocate(jvmti, (jint)new_length); - (void)memcpy((void*)jvmti_space, (void*)new_image, (int)new_length); - *new_class_data_len = (jint)new_length; - *new_class_data = jvmti_space; /* VM will deallocate */ - } - - /* Always free up the space we get from java_crw_demo() */ - if ( new_image != NULL ) { - (void)free((void*)new_image); /* Free malloc() space with free() */ - } - } - (void)free((void*)classname); - } - } exit_critical_section(jvmti); -} - -/* Parse the options for this minst agent */ -static void -parse_agent_options(char *options) -{ - char token[MAX_TOKEN_LENGTH]; - char *next; - - /* Parse options and set flags in gdata */ - if ( options==NULL ) { - return; - } - - /* Get the first token from the options string. */ - next = get_token(options, ",=", token, sizeof(token)); - - /* While not at the end of the options string, process this option. */ - while ( next != NULL ) { - if ( strcmp(token,"help")==0 ) { - stdout_message("The minst JVMTI demo agent\n"); - stdout_message("\n"); - stdout_message(" java -agent:minst[=options] ...\n"); - stdout_message("\n"); - stdout_message("The options are comma separated:\n"); - stdout_message("\t help\t\t\t Print help information\n"); - stdout_message("\t include=item\t\t Only these classes/methods\n"); - stdout_message("\t exclude=item\t\t Exclude these classes/methods\n"); - stdout_message("\n"); - stdout_message("item\t Qualified class and/or method names\n"); - stdout_message("\t\t e.g. (*.;Foobar.method;sun.*)\n"); - stdout_message("\n"); - exit(0); - } else if ( strcmp(token,"include")==0 ) { - int used; - int maxlen; - - maxlen = MAX_METHOD_NAME_LENGTH; - if ( gdata->include == NULL ) { - gdata->include = (char*)calloc(maxlen+1, 1); - used = 0; - } else { - used = (int)strlen(gdata->include); - gdata->include[used++] = ','; - gdata->include[used] = 0; - gdata->include = (char*) - realloc((void*)gdata->include, used+maxlen+1); - } - if ( gdata->include == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - /* Add this item to the list */ - next = get_token(next, ",=", gdata->include+used, maxlen); - /* Check for token scan error */ - if ( next==NULL ) { - fatal_error("ERROR: include option error\n"); - } - } else if ( strcmp(token,"exclude")==0 ) { - int used; - int maxlen; - - maxlen = MAX_METHOD_NAME_LENGTH; - if ( gdata->exclude == NULL ) { - gdata->exclude = (char*)calloc(maxlen+1, 1); - used = 0; - } else { - used = (int)strlen(gdata->exclude); - gdata->exclude[used++] = ','; - gdata->exclude[used] = 0; - gdata->exclude = (char*) - realloc((void*)gdata->exclude, used+maxlen+1); - } - if ( gdata->exclude == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - /* Add this item to the list */ - next = get_token(next, ",=", gdata->exclude+used, maxlen); - /* Check for token scan error */ - if ( next==NULL ) { - fatal_error("ERROR: exclude option error\n"); - } - } else if ( token[0]!=0 ) { - /* We got a non-empty token and we don't know what it is. */ - fatal_error("ERROR: Unknown option: %s\n", token); - } - /* Get the next token (returns NULL if there are no more) */ - next = get_token(next, ",=", token, sizeof(token)); - } -} - -/* Agent_OnLoad: This is called immediately after the shared library is - * loaded. This is the first code executed. - */ -JNIEXPORT jint JNICALL -DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - static GlobalAgentData data; - jvmtiEnv *jvmti; - jvmtiError error; - jint res; - jvmtiCapabilities capabilities; - jvmtiEventCallbacks callbacks; - - /* Setup initial global agent data area - * Use of static/extern data should be handled carefully here. - * We need to make sure that we are able to cleanup after ourselves - * so anything allocated in this library needs to be freed in - * the Agent_OnUnload() function. - */ - (void)memset((void*)&data, 0, sizeof(data)); - gdata = &data; - - /* First thing we need to do is get the jvmtiEnv* or JVMTI environment */ - res = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1); - if (res != JNI_OK) { - /* This means that the VM was unable to obtain this version of the - * JVMTI interface, this is a fatal error. - */ - fatal_error("ERROR: Unable to access JVMTI Version 1 (0x%x)," - " is your JDK a 5.0 or newer version?" - " JNIEnv's GetEnv() returned %d\n", - JVMTI_VERSION_1, res); - } - - /* Here we save the jvmtiEnv* for Agent_OnUnload(). */ - gdata->jvmti = jvmti; - - /* Parse any options supplied on java command line */ - parse_agent_options(options); - - /* Immediately after getting the jvmtiEnv* we need to ask for the - * capabilities this agent will need. In this case we need to make - * sure that we can get all class load hooks. - */ - (void)memset(&capabilities,0, sizeof(capabilities)); - capabilities.can_generate_all_class_hook_events = 1; - error = (*jvmti)->AddCapabilities(jvmti, &capabilities); - check_jvmti_error(jvmti, error, "Unable to get necessary JVMTI capabilities."); - - /* Next we need to provide the pointers to the callback functions to - * to this jvmtiEnv* - */ - (void)memset(&callbacks,0, sizeof(callbacks)); - /* JVMTI_EVENT_VM_START */ - callbacks.VMStart = &cbVMStart; - /* JVMTI_EVENT_VM_INIT */ - callbacks.VMInit = &cbVMInit; - /* JVMTI_EVENT_VM_DEATH */ - callbacks.VMDeath = &cbVMDeath; - /* JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */ - callbacks.ClassFileLoadHook = &cbClassFileLoadHook; - error = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, (jint)sizeof(callbacks)); - check_jvmti_error(jvmti, error, "Cannot set jvmti callbacks"); - - /* At first the only initial events we are interested in are VM - * initialization, VM death, and Class File Loads. - * Once the VM is initialized we will request more events. - */ - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_START, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_DEATH, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - - /* Here we create a raw monitor for our use in this agent to - * protect critical sections of code. - */ - error = (*jvmti)->CreateRawMonitor(jvmti, "agent data", &(gdata->lock)); - check_jvmti_error(jvmti, error, "Cannot create raw monitor"); - - /* Add demo jar file to boot classpath */ - add_demo_jar_to_bootclasspath(jvmti, "minst"); - - /* We return JNI_OK to signify success */ - return JNI_OK; -} - -/* Agent_OnUnload: This is called immediately before the shared library is - * unloaded. This is the last code executed. - */ -JNIEXPORT void JNICALL -DEF_Agent_OnUnload(JavaVM *vm) -{ - /* Make sure all malloc/calloc/strdup space is freed */ - if ( gdata->include != NULL ) { - (void)free((void*)gdata->include); - gdata->include = NULL; - } - if ( gdata->exclude != NULL ) { - (void)free((void*)gdata->exclude); - gdata->exclude = NULL; - } -} diff --git a/jdk/src/demo/share/jvmti/minst/minst.h b/jdk/src/demo/share/jvmti/minst/minst.h deleted file mode 100644 index d852ad4dcb8..00000000000 --- a/jdk/src/demo/share/jvmti/minst/minst.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Primary minst #include file, should be included by most if not - * all minst source files. Gives access to the global data structure - * and all global macros. - */ - -#ifndef MINST_H -#define MINST_H - -/* Standard C functions used throughout. */ - -#include -#include -#include -#include -#include - -/* General JVM/Java functions, types and macros. */ - -#include -#include "jni.h" -#include "jvmti.h" - -/* Utility functions */ - -#include "agent_util.h" - -#endif diff --git a/jdk/src/demo/share/jvmti/minst/sample.makefile.txt b/jdk/src/demo/share/jvmti/minst/sample.makefile.txt deleted file mode 100644 index 5c8f422fb40..00000000000 --- a/jdk/src/demo/share/jvmti/minst/sample.makefile.txt +++ /dev/null @@ -1,163 +0,0 @@ -# -# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo minst -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=minst -SOURCES=minst.c ../agent_util/agent_util.c -JAVA_SOURCES=Minst.java - -# Name of jar file that needs to be created -JARFILE=minst.jar - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Add in java_crw_demo obj file on windows (easier) - SOURCES+=../java_crw_demo/java_crw_demo.c - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES=$(JDK)/ - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I../agent_util -CFLAGS += -I../java_crw_demo -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule (build both native library and jar file) -all: $(LIBRARY) $(JARFILE) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Build jar file -$(JARFILE): $(JAVA_SOURCES) - rm -f -r classes - mkdir -p classes - $(JDK)/bin/javac -d classes $(JAVA_SOURCES) - (cd classes; $(JDK)/bin/jar cf ../$@ *) - -# Cleanup the built bits -clean: - rm -f -r classes - rm -f $(LIBRARY) $(JARFILE) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=. $(JDK)/bin/java -agentlib:$(LIBNAME) -Xbootclasspath/a:./$(JARFILE) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/mtrace/Mtrace.java b/jdk/src/demo/share/jvmti/mtrace/Mtrace.java deleted file mode 100644 index ecebf75a450..00000000000 --- a/jdk/src/demo/share/jvmti/mtrace/Mtrace.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - - -/* Java class to hold static methods which will be called in byte code - * injections of all class files. - */ - -public class Mtrace { - - /* Master switch that activates methods. */ - - private static int engaged = 0; - - /* At the very beginning of every method, a call to method_entry() - * is injected. - */ - - private static native void _method_entry(Object thr, int cnum, int mnum); - public static void method_entry(int cnum, int mnum) - { - if ( engaged != 0 ) { - _method_entry(Thread.currentThread(), cnum, mnum); - } - } - - /* Before any of the return bytecodes, a call to method_exit() - * is injected. - */ - - private static native void _method_exit(Object thr, int cnum, int mnum); - public static void method_exit(int cnum, int mnum) - { - if ( engaged != 0 ) { - _method_exit(Thread.currentThread(), cnum, mnum); - } - } - -} diff --git a/jdk/src/demo/share/jvmti/mtrace/README.txt b/jdk/src/demo/share/jvmti/mtrace/README.txt deleted file mode 100644 index 3c5519726da..00000000000 --- a/jdk/src/demo/share/jvmti/mtrace/README.txt +++ /dev/null @@ -1,50 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -mtrace - -This agent library can be used to track method call and return counts. -It uses the same java_crw_demo library used by HPROF to do BCI on all or -selected classfiles loaded into the Virtual Machine. It will print out a -sorted list of the most heavily used classes (as determined by the number -of method calls into the class) and also include the call and return counts -for all methods that are called. - -You can use this agent library as follows: - - java -Xbootclasspath/a:mtrace.jar -agentlib:mtrace ... - -To get help on the available options try: - - java -agentlib:mtrace=help - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - diff --git a/jdk/src/demo/share/jvmti/mtrace/mtrace.c b/jdk/src/demo/share/jvmti/mtrace/mtrace.c deleted file mode 100644 index 82b9e662e40..00000000000 --- a/jdk/src/demo/share/jvmti/mtrace/mtrace.c +++ /dev/null @@ -1,833 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include "stdlib.h" - -#include "mtrace.h" -#include "java_crw_demo.h" - - -/* ------------------------------------------------------------------- */ -/* Some constant maximum sizes */ - -#define MAX_TOKEN_LENGTH 16 -#define MAX_THREAD_NAME_LENGTH 512 -#define MAX_METHOD_NAME_LENGTH 1024 - -/* Some constant names that tie to Java class/method names. - * We assume the Java class whose static methods we will be calling - * looks like: - * - * public class Mtrace { - * private static int engaged; - * private static native void _method_entry(Object thr, int cnum, int mnum); - * public static void method_entry(int cnum, int mnum) - * { - * if ( engaged != 0 ) { - * _method_entry(Thread.currentThread(), cnum, mnum); - * } - * } - * private static native void _method_exit(Object thr, int cnum, int mnum); - * public static void method_exit(int cnum, int mnum) - * { - * if ( engaged != 0 ) { - * _method_exit(Thread.currentThread(), cnum, mnum); - * } - * } - * } - * - * The engaged field allows us to inject all classes (even system classes) - * and delay the actual calls to the native code until the VM has reached - * a safe time to call native methods (Past the JVMTI VM_START event). - * - */ - -#define MTRACE_class Mtrace /* Name of class we are using */ -#define MTRACE_entry method_entry /* Name of java entry method */ -#define MTRACE_exit method_exit /* Name of java exit method */ -#define MTRACE_native_entry _method_entry /* Name of java entry native */ -#define MTRACE_native_exit _method_exit /* Name of java exit native */ -#define MTRACE_engaged engaged /* Name of java static field */ - -/* C macros to create strings from tokens */ -#define _STRING(s) #s -#define STRING(s) _STRING(s) - -/* ------------------------------------------------------------------- */ - -/* Data structure to hold method and class information in agent */ - -typedef struct MethodInfo { - const char *name; /* Method name */ - const char *signature; /* Method signature */ - int calls; /* Method call count */ - int returns; /* Method return count */ -} MethodInfo; - -typedef struct ClassInfo { - const char *name; /* Class name */ - int mcount; /* Method count */ - MethodInfo *methods; /* Method information */ - int calls; /* Method call count for this class */ -} ClassInfo; - -/* Global agent data structure */ - -typedef struct { - /* JVMTI Environment */ - jvmtiEnv *jvmti; - jboolean vm_is_dead; - jboolean vm_is_started; - /* Data access Lock */ - jrawMonitorID lock; - /* Options */ - char *include; - char *exclude; - int max_count; - /* ClassInfo Table */ - ClassInfo *classes; - jint ccount; -} GlobalAgentData; - -static GlobalAgentData *gdata; - -/* Enter a critical section by doing a JVMTI Raw Monitor Enter */ -static void -enter_critical_section(jvmtiEnv *jvmti) -{ - jvmtiError error; - - error = (*jvmti)->RawMonitorEnter(jvmti, gdata->lock); - check_jvmti_error(jvmti, error, "Cannot enter with raw monitor"); -} - -/* Exit a critical section by doing a JVMTI Raw Monitor Exit */ -static void -exit_critical_section(jvmtiEnv *jvmti) -{ - jvmtiError error; - - error = (*jvmti)->RawMonitorExit(jvmti, gdata->lock); - check_jvmti_error(jvmti, error, "Cannot exit with raw monitor"); -} - -/* Get a name for a jthread */ -static void -get_thread_name(jvmtiEnv *jvmti, jthread thread, char *tname, int maxlen) -{ - jvmtiThreadInfo info; - jvmtiError error; - - /* Make sure the stack variables are garbage free */ - (void)memset(&info,0, sizeof(info)); - - /* Assume the name is unknown for now */ - (void)strcpy(tname, "Unknown"); - - /* Get the thread information, which includes the name */ - error = (*jvmti)->GetThreadInfo(jvmti, thread, &info); - check_jvmti_error(jvmti, error, "Cannot get thread info"); - - /* The thread might not have a name, be careful here. */ - if ( info.name != NULL ) { - int len; - - /* Copy the thread name into tname if it will fit */ - len = (int)strlen(info.name); - if ( len < maxlen ) { - (void)strcpy(tname, info.name); - } - - /* Every string allocated by JVMTI needs to be freed */ - deallocate(jvmti, (void*)info.name); - } -} - -/* Qsort class compare routine */ -static int -class_compar(const void *e1, const void *e2) -{ - ClassInfo *c1 = (ClassInfo*)e1; - ClassInfo *c2 = (ClassInfo*)e2; - if ( c1->calls > c2->calls ) return 1; - if ( c1->calls < c2->calls ) return -1; - return 0; -} - -/* Qsort method compare routine */ -static int -method_compar(const void *e1, const void *e2) -{ - MethodInfo *m1 = (MethodInfo*)e1; - MethodInfo *m2 = (MethodInfo*)e2; - if ( m1->calls > m2->calls ) return 1; - if ( m1->calls < m2->calls ) return -1; - return 0; -} - -/* Callback from java_crw_demo() that gives us mnum mappings */ -static void -mnum_callbacks(unsigned cnum, const char **names, const char**sigs, int mcount) -{ - ClassInfo *cp; - int mnum; - - if ( cnum >= (unsigned)gdata->ccount ) { - fatal_error("ERROR: Class number out of range\n"); - } - if ( mcount == 0 ) { - return; - } - - cp = gdata->classes + (int)cnum; - cp->calls = 0; - cp->mcount = mcount; - cp->methods = (MethodInfo*)calloc(mcount, sizeof(MethodInfo)); - if ( cp->methods == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - - for ( mnum = 0 ; mnum < mcount ; mnum++ ) { - MethodInfo *mp; - - mp = cp->methods + mnum; - mp->name = (const char *)strdup(names[mnum]); - if ( mp->name == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - mp->signature = (const char *)strdup(sigs[mnum]); - if ( mp->signature == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - } -} - -/* Java Native Method for entry */ -static void -MTRACE_native_entry(JNIEnv *env, jclass klass, jobject thread, jint cnum, jint mnum) -{ - enter_critical_section(gdata->jvmti); { - /* It's possible we get here right after VmDeath event, be careful */ - if ( !gdata->vm_is_dead ) { - ClassInfo *cp; - MethodInfo *mp; - - if ( cnum >= gdata->ccount ) { - fatal_error("ERROR: Class number out of range\n"); - } - cp = gdata->classes + cnum; - if ( mnum >= cp->mcount ) { - fatal_error("ERROR: Method number out of range\n"); - } - mp = cp->methods + mnum; - if ( interested((char*)cp->name, (char*)mp->name, - gdata->include, gdata->exclude) ) { - mp->calls++; - cp->calls++; - } - } - } exit_critical_section(gdata->jvmti); -} - -/* Java Native Method for exit */ -static void -MTRACE_native_exit(JNIEnv *env, jclass klass, jobject thread, jint cnum, jint mnum) -{ - enter_critical_section(gdata->jvmti); { - /* It's possible we get here right after VmDeath event, be careful */ - if ( !gdata->vm_is_dead ) { - ClassInfo *cp; - MethodInfo *mp; - - if ( cnum >= gdata->ccount ) { - fatal_error("ERROR: Class number out of range\n"); - } - cp = gdata->classes + cnum; - if ( mnum >= cp->mcount ) { - fatal_error("ERROR: Method number out of range\n"); - } - mp = cp->methods + mnum; - if ( interested((char*)cp->name, (char*)mp->name, - gdata->include, gdata->exclude) ) { - mp->returns++; - } - } - } exit_critical_section(gdata->jvmti); -} - -/* Callback for JVMTI_EVENT_VM_START */ -static void JNICALL -cbVMStart(jvmtiEnv *jvmti, JNIEnv *env) -{ - enter_critical_section(jvmti); { - jclass klass; - jfieldID field; - int rc; - - /* Java Native Methods for class */ - static JNINativeMethod registry[2] = { - {STRING(MTRACE_native_entry), "(Ljava/lang/Object;II)V", - (void*)&MTRACE_native_entry}, - {STRING(MTRACE_native_exit), "(Ljava/lang/Object;II)V", - (void*)&MTRACE_native_exit} - }; - - /* The VM has started. */ - stdout_message("VMStart\n"); - - /* Register Natives for class whose methods we use */ - klass = (*env)->FindClass(env, STRING(MTRACE_class)); - if ( klass == NULL ) { - fatal_error("ERROR: JNI: Cannot find %s with FindClass\n", - STRING(MTRACE_class)); - } - rc = (*env)->RegisterNatives(env, klass, registry, 2); - if ( rc != 0 ) { - fatal_error("ERROR: JNI: Cannot register native methods for %s\n", - STRING(MTRACE_class)); - } - - /* Engage calls. */ - field = (*env)->GetStaticFieldID(env, klass, STRING(MTRACE_engaged), "I"); - if ( field == NULL ) { - fatal_error("ERROR: JNI: Cannot get field from %s\n", - STRING(MTRACE_class)); - } - (*env)->SetStaticIntField(env, klass, field, 1); - - /* Indicate VM has started */ - gdata->vm_is_started = JNI_TRUE; - - } exit_critical_section(jvmti); -} - -/* Callback for JVMTI_EVENT_VM_INIT */ -static void JNICALL -cbVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - enter_critical_section(jvmti); { - char tname[MAX_THREAD_NAME_LENGTH]; - static jvmtiEvent events[] = - { JVMTI_EVENT_THREAD_START, JVMTI_EVENT_THREAD_END }; - int i; - - /* The VM has started. */ - get_thread_name(jvmti, thread, tname, sizeof(tname)); - stdout_message("VMInit %s\n", tname); - - /* The VM is now initialized, at this time we make our requests - * for additional events. - */ - - for( i=0; i < (int)(sizeof(events)/sizeof(jvmtiEvent)); i++) { - jvmtiError error; - - /* Setup event notification modes */ - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - events[i], (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - } - - } exit_critical_section(jvmti); -} - -/* Callback for JVMTI_EVENT_VM_DEATH */ -static void JNICALL -cbVMDeath(jvmtiEnv *jvmti, JNIEnv *env) -{ - enter_critical_section(jvmti); { - jclass klass; - jfieldID field; - - /* The VM has died. */ - stdout_message("VMDeath\n"); - - /* Disengage calls in MTRACE_class. */ - klass = (*env)->FindClass(env, STRING(MTRACE_class)); - if ( klass == NULL ) { - fatal_error("ERROR: JNI: Cannot find %s with FindClass\n", - STRING(MTRACE_class)); - } - field = (*env)->GetStaticFieldID(env, klass, STRING(MTRACE_engaged), "I"); - if ( field == NULL ) { - fatal_error("ERROR: JNI: Cannot get field from %s\n", - STRING(MTRACE_class)); - } - (*env)->SetStaticIntField(env, klass, field, 0); - - /* The critical section here is important to hold back the VM death - * until all other callbacks have completed. - */ - - /* Since this critical section could be holding up other threads - * in other event callbacks, we need to indicate that the VM is - * dead so that the other callbacks can short circuit their work. - * We don't expect any further events after VmDeath but we do need - * to be careful that existing threads might be in our own agent - * callback code. - */ - gdata->vm_is_dead = JNI_TRUE; - - /* Dump out stats */ - stdout_message("Begin Class Stats\n"); - if ( gdata->ccount > 0 ) { - int cnum; - - /* Sort table (in place) by number of method calls into class. */ - /* Note: Do not use this table after this qsort! */ - qsort(gdata->classes, gdata->ccount, sizeof(ClassInfo), - &class_compar); - - /* Dump out gdata->max_count most called classes */ - for ( cnum=gdata->ccount-1 ; - cnum >= 0 && cnum >= gdata->ccount - gdata->max_count; - cnum-- ) { - ClassInfo *cp; - int mnum; - - cp = gdata->classes + cnum; - stdout_message("Class %s %d calls\n", cp->name, cp->calls); - if ( cp->calls==0 ) continue; - - /* Sort method table (in place) by number of method calls. */ - /* Note: Do not use this table after this qsort! */ - qsort(cp->methods, cp->mcount, sizeof(MethodInfo), - &method_compar); - for ( mnum=cp->mcount-1 ; mnum >= 0 ; mnum-- ) { - MethodInfo *mp; - - mp = cp->methods + mnum; - if ( mp->calls==0 ) continue; - stdout_message("\tMethod %s %s %d calls %d returns\n", - mp->name, mp->signature, mp->calls, mp->returns); - } - } - } - stdout_message("End Class Stats\n"); - (void)fflush(stdout); - - } exit_critical_section(jvmti); - -} - -/* Callback for JVMTI_EVENT_THREAD_START */ -static void JNICALL -cbThreadStart(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - enter_critical_section(jvmti); { - /* It's possible we get here right after VmDeath event, be careful */ - if ( !gdata->vm_is_dead ) { - char tname[MAX_THREAD_NAME_LENGTH]; - - get_thread_name(jvmti, thread, tname, sizeof(tname)); - stdout_message("ThreadStart %s\n", tname); - } - } exit_critical_section(jvmti); -} - -/* Callback for JVMTI_EVENT_THREAD_END */ -static void JNICALL -cbThreadEnd(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - enter_critical_section(jvmti); { - /* It's possible we get here right after VmDeath event, be careful */ - if ( !gdata->vm_is_dead ) { - char tname[MAX_THREAD_NAME_LENGTH]; - - get_thread_name(jvmti, thread, tname, sizeof(tname)); - stdout_message("ThreadEnd %s\n", tname); - } - } exit_critical_section(jvmti); -} - -/* Callback for JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */ -static void JNICALL -cbClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv* env, - jclass class_being_redefined, jobject loader, - const char* name, jobject protection_domain, - jint class_data_len, const unsigned char* class_data, - jint* new_class_data_len, unsigned char** new_class_data) -{ - enter_critical_section(jvmti); { - /* It's possible we get here right after VmDeath event, be careful */ - if ( !gdata->vm_is_dead ) { - - const char *classname; - - /* Name could be NULL */ - if ( name == NULL ) { - classname = java_crw_demo_classname(class_data, class_data_len, - NULL); - if ( classname == NULL ) { - fatal_error("ERROR: No classname inside classfile\n"); - } - } else { - classname = strdup(name); - if ( classname == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - } - - *new_class_data_len = 0; - *new_class_data = NULL; - - /* The tracker class itself? */ - if ( interested((char*)classname, "", gdata->include, gdata->exclude) - && strcmp(classname, STRING(MTRACE_class)) != 0 ) { - jint cnum; - int system_class; - unsigned char *new_image; - long new_length; - ClassInfo *cp; - - /* Get unique number for every class file image loaded */ - cnum = gdata->ccount++; - - /* Save away class information */ - if ( gdata->classes == NULL ) { - gdata->classes = (ClassInfo*)malloc( - gdata->ccount*sizeof(ClassInfo)); - } else { - gdata->classes = (ClassInfo*) - realloc((void*)gdata->classes, - gdata->ccount*sizeof(ClassInfo)); - } - if ( gdata->classes == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - cp = gdata->classes + cnum; - cp->name = (const char *)strdup(classname); - if ( cp->name == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - cp->calls = 0; - cp->mcount = 0; - cp->methods = NULL; - - /* Is it a system class? If the class load is before VmStart - * then we will consider it a system class that should - * be treated carefully. (See java_crw_demo) - */ - system_class = 0; - if ( !gdata->vm_is_started ) { - system_class = 1; - } - - new_image = NULL; - new_length = 0; - - /* Call the class file reader/write demo code */ - java_crw_demo(cnum, - classname, - class_data, - class_data_len, - system_class, - STRING(MTRACE_class), "L" STRING(MTRACE_class) ";", - STRING(MTRACE_entry), "(II)V", - STRING(MTRACE_exit), "(II)V", - NULL, NULL, - NULL, NULL, - &new_image, - &new_length, - NULL, - &mnum_callbacks); - - /* If we got back a new class image, return it back as "the" - * new class image. This must be JVMTI Allocate space. - */ - if ( new_length > 0 ) { - unsigned char *jvmti_space; - - jvmti_space = (unsigned char *)allocate(jvmti, (jint)new_length); - (void)memcpy((void*)jvmti_space, (void*)new_image, (int)new_length); - *new_class_data_len = (jint)new_length; - *new_class_data = jvmti_space; /* VM will deallocate */ - } - - /* Always free up the space we get from java_crw_demo() */ - if ( new_image != NULL ) { - (void)free((void*)new_image); /* Free malloc() space with free() */ - } - } - (void)free((void*)classname); - } - } exit_critical_section(jvmti); -} - -/* Parse the options for this mtrace agent */ -static void -parse_agent_options(char *options) -{ - char token[MAX_TOKEN_LENGTH]; - char *next; - - gdata->max_count = 10; /* Default max=n */ - - /* Parse options and set flags in gdata */ - if ( options==NULL ) { - return; - } - - /* Get the first token from the options string. */ - next = get_token(options, ",=", token, sizeof(token)); - - /* While not at the end of the options string, process this option. */ - while ( next != NULL ) { - if ( strcmp(token,"help")==0 ) { - stdout_message("The mtrace JVMTI demo agent\n"); - stdout_message("\n"); - stdout_message(" java -agent:mtrace[=options] ...\n"); - stdout_message("\n"); - stdout_message("The options are comma separated:\n"); - stdout_message("\t help\t\t\t Print help information\n"); - stdout_message("\t max=n\t\t Only list top n classes\n"); - stdout_message("\t include=item\t\t Only these classes/methods\n"); - stdout_message("\t exclude=item\t\t Exclude these classes/methods\n"); - stdout_message("\n"); - stdout_message("item\t Qualified class and/or method names\n"); - stdout_message("\t\t e.g. (*.;Foobar.method;sun.*)\n"); - stdout_message("\n"); - exit(0); - } else if ( strcmp(token,"max")==0 ) { - char number[MAX_TOKEN_LENGTH]; - - /* Get the numeric option */ - next = get_token(next, ",=", number, (int)sizeof(number)); - /* Check for token scan error */ - if ( next==NULL ) { - fatal_error("ERROR: max=n option error\n"); - } - /* Save numeric value */ - gdata->max_count = atoi(number); - } else if ( strcmp(token,"include")==0 ) { - int used; - int maxlen; - - maxlen = MAX_METHOD_NAME_LENGTH; - if ( gdata->include == NULL ) { - gdata->include = (char*)calloc(maxlen+1, 1); - used = 0; - } else { - used = (int)strlen(gdata->include); - gdata->include[used++] = ','; - gdata->include[used] = 0; - gdata->include = (char*) - realloc((void*)gdata->include, used+maxlen+1); - } - if ( gdata->include == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - /* Add this item to the list */ - next = get_token(next, ",=", gdata->include+used, maxlen); - /* Check for token scan error */ - if ( next==NULL ) { - fatal_error("ERROR: include option error\n"); - } - } else if ( strcmp(token,"exclude")==0 ) { - int used; - int maxlen; - - maxlen = MAX_METHOD_NAME_LENGTH; - if ( gdata->exclude == NULL ) { - gdata->exclude = (char*)calloc(maxlen+1, 1); - used = 0; - } else { - used = (int)strlen(gdata->exclude); - gdata->exclude[used++] = ','; - gdata->exclude[used] = 0; - gdata->exclude = (char*) - realloc((void*)gdata->exclude, used+maxlen+1); - } - if ( gdata->exclude == NULL ) { - fatal_error("ERROR: Out of malloc memory\n"); - } - /* Add this item to the list */ - next = get_token(next, ",=", gdata->exclude+used, maxlen); - /* Check for token scan error */ - if ( next==NULL ) { - fatal_error("ERROR: exclude option error\n"); - } - } else if ( token[0]!=0 ) { - /* We got a non-empty token and we don't know what it is. */ - fatal_error("ERROR: Unknown option: %s\n", token); - } - /* Get the next token (returns NULL if there are no more) */ - next = get_token(next, ",=", token, sizeof(token)); - } -} - -/* Agent_OnLoad: This is called immediately after the shared library is - * loaded. This is the first code executed. - */ -JNIEXPORT jint JNICALL -DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - static GlobalAgentData data; - jvmtiEnv *jvmti; - jvmtiError error; - jint res; - jvmtiCapabilities capabilities; - jvmtiEventCallbacks callbacks; - - /* Setup initial global agent data area - * Use of static/extern data should be handled carefully here. - * We need to make sure that we are able to cleanup after ourselves - * so anything allocated in this library needs to be freed in - * the Agent_OnUnload() function. - */ - (void)memset((void*)&data, 0, sizeof(data)); - gdata = &data; - - /* First thing we need to do is get the jvmtiEnv* or JVMTI environment */ - res = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1); - if (res != JNI_OK) { - /* This means that the VM was unable to obtain this version of the - * JVMTI interface, this is a fatal error. - */ - fatal_error("ERROR: Unable to access JVMTI Version 1 (0x%x)," - " is your JDK a 5.0 or newer version?" - " JNIEnv's GetEnv() returned %d\n", - JVMTI_VERSION_1, res); - } - - /* Here we save the jvmtiEnv* for Agent_OnUnload(). */ - gdata->jvmti = jvmti; - - /* Parse any options supplied on java command line */ - parse_agent_options(options); - - /* Immediately after getting the jvmtiEnv* we need to ask for the - * capabilities this agent will need. In this case we need to make - * sure that we can get all class load hooks. - */ - (void)memset(&capabilities,0, sizeof(capabilities)); - capabilities.can_generate_all_class_hook_events = 1; - error = (*jvmti)->AddCapabilities(jvmti, &capabilities); - check_jvmti_error(jvmti, error, "Unable to get necessary JVMTI capabilities."); - - /* Next we need to provide the pointers to the callback functions to - * to this jvmtiEnv* - */ - (void)memset(&callbacks,0, sizeof(callbacks)); - /* JVMTI_EVENT_VM_START */ - callbacks.VMStart = &cbVMStart; - /* JVMTI_EVENT_VM_INIT */ - callbacks.VMInit = &cbVMInit; - /* JVMTI_EVENT_VM_DEATH */ - callbacks.VMDeath = &cbVMDeath; - /* JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */ - callbacks.ClassFileLoadHook = &cbClassFileLoadHook; - /* JVMTI_EVENT_THREAD_START */ - callbacks.ThreadStart = &cbThreadStart; - /* JVMTI_EVENT_THREAD_END */ - callbacks.ThreadEnd = &cbThreadEnd; - error = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, (jint)sizeof(callbacks)); - check_jvmti_error(jvmti, error, "Cannot set jvmti callbacks"); - - /* At first the only initial events we are interested in are VM - * initialization, VM death, and Class File Loads. - * Once the VM is initialized we will request more events. - */ - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_START, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_DEATH, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, (jthread)NULL); - check_jvmti_error(jvmti, error, "Cannot set event notification"); - - /* Here we create a raw monitor for our use in this agent to - * protect critical sections of code. - */ - error = (*jvmti)->CreateRawMonitor(jvmti, "agent data", &(gdata->lock)); - check_jvmti_error(jvmti, error, "Cannot create raw monitor"); - - /* Add demo jar file to boot classpath */ - add_demo_jar_to_bootclasspath(jvmti, "mtrace"); - - /* We return JNI_OK to signify success */ - return JNI_OK; -} - -/* Agent_OnUnload: This is called immediately before the shared library is - * unloaded. This is the last code executed. - */ -JNIEXPORT void JNICALL -DEF_Agent_OnUnload(JavaVM *vm) -{ - /* Make sure all malloc/calloc/strdup space is freed */ - if ( gdata->include != NULL ) { - (void)free((void*)gdata->include); - gdata->include = NULL; - } - if ( gdata->exclude != NULL ) { - (void)free((void*)gdata->exclude); - gdata->exclude = NULL; - } - if ( gdata->classes != NULL ) { - int cnum; - - for ( cnum = 0 ; cnum < gdata->ccount ; cnum++ ) { - ClassInfo *cp; - - cp = gdata->classes + cnum; - (void)free((void*)cp->name); - if ( cp->mcount > 0 ) { - int mnum; - - for ( mnum = 0 ; mnum < cp->mcount ; mnum++ ) { - MethodInfo *mp; - - mp = cp->methods + mnum; - (void)free((void*)mp->name); - (void)free((void*)mp->signature); - } - (void)free((void*)cp->methods); - } - } - (void)free((void*)gdata->classes); - gdata->classes = NULL; - } -} diff --git a/jdk/src/demo/share/jvmti/mtrace/mtrace.h b/jdk/src/demo/share/jvmti/mtrace/mtrace.h deleted file mode 100644 index 39f483ddf14..00000000000 --- a/jdk/src/demo/share/jvmti/mtrace/mtrace.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Primary mtrace #include file, should be included by most if not - * all mtrace source files. Gives access to the global data structure - * and all global macros. - */ - -#ifndef MTRACE_H -#define MTRACE_H - -/* Standard C functions used throughout. */ - -#include -#include -#include -#include -#include - -/* General JVM/Java functions, types and macros. */ - -#include -#include "jni.h" -#include "jvmti.h" - -/* Utility functions */ - -#include "agent_util.h" - -#endif diff --git a/jdk/src/demo/share/jvmti/mtrace/sample.makefile.txt b/jdk/src/demo/share/jvmti/mtrace/sample.makefile.txt deleted file mode 100644 index b342e785020..00000000000 --- a/jdk/src/demo/share/jvmti/mtrace/sample.makefile.txt +++ /dev/null @@ -1,163 +0,0 @@ -# -# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo mtrace -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=mtrace -SOURCES=mtrace.c ../agent_util/agent_util.c -JAVA_SOURCES=Mtrace.java - -# Name of jar file that needs to be created -JARFILE=mtrace.jar - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-L $(JDK)/jre/lib/$(LIBARCH) -ljava_crw_demo -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Add in java_crw_demo obj file on windows (easier) - SOURCES+=../java_crw_demo/java_crw_demo.c - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES=$(JDK)/ - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I../agent_util -CFLAGS += -I../java_crw_demo -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule (build both native library and jar file) -all: $(LIBRARY) $(JARFILE) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Build jar file -$(JARFILE): $(JAVA_SOURCES) - rm -f -r classes - mkdir -p classes - $(JDK)/bin/javac -d classes $(JAVA_SOURCES) - (cd classes; $(JDK)/bin/jar cf ../$@ *) - -# Cleanup the built bits -clean: - rm -f -r classes - rm -f $(LIBRARY) $(JARFILE) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=. $(JDK)/bin/java -agentlib:$(LIBNAME) -Xbootclasspath/a:./$(JARFILE) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/versionCheck/README.txt b/jdk/src/demo/share/jvmti/versionCheck/README.txt deleted file mode 100644 index 838af415252..00000000000 --- a/jdk/src/demo/share/jvmti/versionCheck/README.txt +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -versionCheck - -This agent library just makes some simple calls and checks -the version of the interface being used to build the agent, -with that supplied by the VM at runtime. - -You can use this agent library as follows: - - java -agentlib:versionCheck ... - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - diff --git a/jdk/src/demo/share/jvmti/versionCheck/sample.makefile.txt b/jdk/src/demo/share/jvmti/versionCheck/sample.makefile.txt deleted file mode 100644 index 01240330398..00000000000 --- a/jdk/src/demo/share/jvmti/versionCheck/sample.makefile.txt +++ /dev/null @@ -1,148 +0,0 @@ -# -# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo versionCheck -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=versionCheck -SOURCES=versionCheck.c ../agent_util/agent_util.c - -# Solaris Studio C Compiler Version 12.4 -ifeq ($(OSNAME), solaris) - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Options that help find errors - COMMON_FLAGS+= -Xa -v -xc99=%none - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CFLAGS=-xO2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES= -lc - # Building a shared library - LINK_SHARED=$(LINK.c) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CFLAGS=-O2 $(COMMON_FLAGS) - else - CFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES=-lc - # Building a shared library - LINK_SHARED=$(LINK.c) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.c=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES= - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CFLAGS += -I. -CFLAGS += -I../agent_util -CFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule -all: $(LIBRARY) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Cleanup the built bits -clean: - rm -f $(LIBRARY) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=`pwd` $(JDK)/bin/java -agentlib:$(LIBNAME) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.c - $(COMPILE.c) $< -endif - diff --git a/jdk/src/demo/share/jvmti/versionCheck/versionCheck.c b/jdk/src/demo/share/jvmti/versionCheck/versionCheck.c deleted file mode 100644 index 0ed58263b26..00000000000 --- a/jdk/src/demo/share/jvmti/versionCheck/versionCheck.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -#include "agent_util.h" - -/* Create major.minor.micro version string */ -static void -version_check(jint cver, jint rver) -{ - jint cmajor, cminor, cmicro; - jint rmajor, rminor, rmicro; - - cmajor = (cver & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR; - cminor = (cver & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR; - cmicro = (cver & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO; - rmajor = (rver & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR; - rminor = (rver & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR; - rmicro = (rver & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO; - stdout_message("Compile Time JVMTI Version: %d.%d.%d (0x%08x)\n", - cmajor, cminor, cmicro, cver); - stdout_message("Run Time JVMTI Version: %d.%d.%d (0x%08x)\n", - rmajor, rminor, rmicro, rver); - if ( (cmajor > rmajor) || (cmajor == rmajor && cminor > rminor) ) { - fatal_error( - "ERROR: Compile Time JVMTI and Run Time JVMTI are incompatible\n"); - } -} - -/* Callback for JVMTI_EVENT_VM_INIT */ -static void JNICALL -vm_init(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - jvmtiError err; - jint runtime_version; - - /* The exact JVMTI version doesn't have to match, however this - * code demonstrates how you can check that the JVMTI version seen - * in the jvmti.h include file matches that being supplied at runtime - * by the VM. - */ - err = (*jvmti)->GetVersionNumber(jvmti, &runtime_version); - check_jvmti_error(jvmti, err, "get version number"); - version_check(JVMTI_VERSION, runtime_version); -} - -/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */ -JNIEXPORT jint JNICALL -DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - jint rc; - jvmtiError err; - jvmtiEventCallbacks callbacks; - jvmtiEnv *jvmti; - - /* Get JVMTI environment */ - rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION); - if (rc != JNI_OK) { - fatal_error("ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc); - return -1; - } - - /* Set callbacks and enable event notifications */ - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.VMInit = &vm_init; - err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); - check_jvmti_error(jvmti, err, "set event callbacks"); - err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - return 0; -} - -/* Agent_OnUnload() is called last */ -JNIEXPORT void JNICALL -DEF_Agent_OnUnload(JavaVM *vm) -{ -} diff --git a/jdk/src/demo/share/jvmti/waiters/Agent.cpp b/jdk/src/demo/share/jvmti/waiters/Agent.cpp deleted file mode 100644 index 8f67f5480a5..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/Agent.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -#include "agent_util.h" - -#include "Monitor.hpp" -#include "Thread.hpp" -#include "Agent.hpp" - -/* Implementation of the Agent class */ - -/* Given a jvmtiEnv* and jthread, find the Thread instance */ -Thread * -Agent::get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - jvmtiError err; - Thread *t; - - /* This should always be in the Thread Local Storage */ - t = NULL; - err = jvmti->GetThreadLocalStorage(thread, (void**)&t); - check_jvmti_error(jvmti, err, "get thread local storage"); - if ( t == NULL ) { - /* This jthread has never been seen before? */ - stdout_message("WARNING: Never before seen jthread?\n"); - t = new Thread(jvmti, env, thread); - err = jvmti->SetThreadLocalStorage(thread, (const void*)t); - check_jvmti_error(jvmti, err, "set thread local storage"); - } - return t; -} - -/* Given a jvmtiEnv* and jobject, find the Monitor instance or create one */ -Monitor * -Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object) -{ - jvmtiError err; - Monitor *m; - jlong tag; - - m = NULL; - tag = (jlong)0; - err = jvmti->GetTag(object, &tag); - check_jvmti_error(jvmti, err, "get tag"); - /*LINTED*/ - m = (Monitor *)(void *)(ptrdiff_t)tag; - if ( m == NULL ) { - m = new Monitor(jvmti, env, object); - /* Save monitor on list */ - if (monitor_count == monitor_list_size) { - monitor_list_size += monitor_list_grow_size; - monitor_list = (Monitor**)realloc((void*)monitor_list, - (monitor_list_size)*(int)sizeof(Monitor*)); - } - monitor_list[monitor_count] = m; - m->set_slot(monitor_count); - monitor_count++; - /*LINTED*/ - tag = (jlong)(ptrdiff_t)(void *)m; - err = jvmti->SetTag(object, tag); - check_jvmti_error(jvmti, err, "set tag"); - } - return m; -} - -/* VM initialization and VM death calls to Agent */ -Agent::Agent(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - stdout_message("Agent created..\n"); - stdout_message("VMInit...\n"); - /* Start monitor list */ - monitor_count = 0; - monitor_list_size = initial_monitor_list_size; - monitor_list = (Monitor**) - malloc(monitor_list_size*(int)sizeof(Monitor*)); -} - -Agent::~Agent() -{ - stdout_message("Agent reclaimed..\n"); -} - -void Agent::vm_death(jvmtiEnv *jvmti, JNIEnv *env) -{ - /* Delete all Monitors we allocated */ - for ( int i = 0; i < (int)monitor_count; i++ ) { - delete monitor_list[i]; - } - free(monitor_list); - /* Print death message */ - stdout_message("VMDeath...\n"); -} - -/* Thread start event, setup a new thread */ -void Agent::thread_start(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - jvmtiError err; - Thread *t; - - /* Allocate a new Thread instance, put it in the Thread Local - * Storage for easy access later. - */ - t = new Thread(jvmti, env, thread); - err = jvmti->SetThreadLocalStorage(thread, (const void*)t); - check_jvmti_error(jvmti, err, "set thread local storage"); -} - - -/* Thread end event, we need to reclaim the space */ -void Agent::thread_end(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - jvmtiError err; - Thread *t; - - /* Find the thread */ - t = get_thread(jvmti, env, thread); - - /* Clear out the Thread Local Storage */ - err = jvmti->SetThreadLocalStorage(thread, (const void*)NULL); - check_jvmti_error(jvmti, err, "set thread local storage"); - - /* Reclaim the C++ object space */ - delete t; -} - -/* Monitor contention begins for a thread. */ -void Agent::monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object) -{ - get_monitor(jvmti, env, object)->contended(); - get_thread(jvmti, env, thread)-> - monitor_contended_enter(jvmti, env, thread, object); -} - -/* Monitor contention ends for a thread. */ -void Agent::monitor_contended_entered(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object) -{ - /* Do nothing for now */ -} - -/* Monitor wait begins for a thread. */ -void Agent::monitor_wait(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jlong timeout) -{ - get_monitor(jvmti, env, object)->waited(); - get_thread(jvmti, env, thread)-> - monitor_wait(jvmti, env, thread, object, timeout); -} - -/* Monitor wait ends for a thread. */ -void Agent::monitor_waited(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jboolean timed_out) -{ - if ( timed_out ) { - get_monitor(jvmti, env, object)->timeout(); - } - get_thread(jvmti, env, thread)-> - monitor_waited(jvmti, env, thread, object, timed_out); -} - -/* A tagged object has been freed */ -void Agent::object_free(jvmtiEnv* jvmti, jlong tag) -{ - /* We just cast the tag to a C++ pointer and delete it. - * we know it can only be a Monitor *. - */ - Monitor *m; - /*LINTED*/ - m = (Monitor *)(ptrdiff_t)tag; - if (monitor_count > 1) { - /* Move the last element to this Monitor's slot */ - int slot = m->get_slot(); - Monitor *last = monitor_list[monitor_count-1]; - monitor_list[slot] = last; - last->set_slot(slot); - } - monitor_count--; - delete m; -} diff --git a/jdk/src/demo/share/jvmti/waiters/Agent.hpp b/jdk/src/demo/share/jvmti/waiters/Agent.hpp deleted file mode 100644 index 20f03229ef9..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/Agent.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* C++ Agent class */ - -class Agent { - - private: - enum { - initial_monitor_list_size = 64, - monitor_list_grow_size = 16 - }; - Monitor **monitor_list; - unsigned monitor_list_size; - unsigned monitor_count; - Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread); - Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object); - - public: - Agent(jvmtiEnv *jvmti, JNIEnv *env, jthread thread); - ~Agent(); - void vm_death(jvmtiEnv *jvmti, JNIEnv *env); - void thread_start(jvmtiEnv *jvmti, JNIEnv *env, jthread thread); - void thread_end(jvmtiEnv *jvmti, JNIEnv *env, jthread thread); - void monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object); - void monitor_contended_entered(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object); - void monitor_wait(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jlong timeout); - void monitor_waited(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jboolean timed_out); - void object_free(jvmtiEnv* jvmti, jlong tag); - -}; diff --git a/jdk/src/demo/share/jvmti/waiters/Monitor.cpp b/jdk/src/demo/share/jvmti/waiters/Monitor.cpp deleted file mode 100644 index db215c8b7b7..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/Monitor.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -#include "agent_util.h" - -#include "Monitor.hpp" - -/* Implementation of the Monitor class */ - -Monitor::Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object) -{ - jvmtiError err; - jclass klass; - char *signature; - - /* Clear counters */ - contends = 0; - waits = 0; - timeouts = 0; - - /* Get the class name for this monitor object */ - (void)strcpy(name, "Unknown"); - klass = env->GetObjectClass(object); - if ( klass == NULL ) { - fatal_error("ERROR: Cannot find jclass from jobject\n"); - } - err = jvmti->GetClassSignature(klass, &signature, NULL); - check_jvmti_error(jvmti, err, "get class signature"); - if ( signature != NULL ) { - (void)strncpy(name, signature, (int)sizeof(name)-1); - deallocate(jvmti, signature); - } -} - -Monitor::~Monitor() -{ - stdout_message("Monitor %s summary: %d contends, %d waits, %d timeouts\n", - name, contends, waits, timeouts); -} - -int Monitor::get_slot() -{ - return slot; -} - -void Monitor::set_slot(int aslot) -{ - slot = aslot; -} - -void Monitor::contended() -{ - contends++; -} - -void Monitor::waited() -{ - waits++; -} - -void Monitor::timeout() -{ - timeouts++; -} diff --git a/jdk/src/demo/share/jvmti/waiters/Monitor.hpp b/jdk/src/demo/share/jvmti/waiters/Monitor.hpp deleted file mode 100644 index 2906e5779f6..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/Monitor.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - -#ifdef STATIC_BUILD -#define Monitor WaiterMonitor -#endif - - -/* C++ Monitor class */ - -class Monitor { - - private: - char name[64]; - int slot; - unsigned contends; - unsigned waits; - unsigned timeouts; - - public: - Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object); - ~Monitor(); - int get_slot(); - void set_slot(int i); - void contended(); - void waited(); - void timeout(); - -}; diff --git a/jdk/src/demo/share/jvmti/waiters/README.txt b/jdk/src/demo/share/jvmti/waiters/README.txt deleted file mode 100644 index f0d940bd34e..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/README.txt +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -waiters - -This agent library can be used to track threads that wait on monitors. -This agent is written in C++. - -You can use this agent library as follows: - - java -agentlib:waiters ... - -To get help on the available options try: - - java -agentlib:waiters=help - -See ${JAVA_HOME}/demo/jvmti/index.html for help running and building agents. - diff --git a/jdk/src/demo/share/jvmti/waiters/Thread.cpp b/jdk/src/demo/share/jvmti/waiters/Thread.cpp deleted file mode 100644 index 589976963e0..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/Thread.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - -#ifdef STATIC_BUILD -#define Thread WaiterThread -#endif - -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -#include "agent_util.h" - -#include "Thread.hpp" - -/* Implementation of the Thread class */ - -Thread::Thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) -{ - jvmtiError err; - jvmtiThreadInfo info; - - /* Get and save the name of the thread */ - info.name = NULL; - (void)strcpy(name, "Unknown"); - err = jvmti->GetThreadInfo(thread, &info); - check_jvmti_error(jvmti, err, "get thread info"); - if ( info.name != NULL ) { - (void)strncpy(name, info.name, (int)sizeof(name)-1); - name[(int)sizeof(name)-1] = 0; - deallocate(jvmti, info.name); - } - - /* Clear thread counters */ - contends = 0; - waits = 0; - timeouts = 0; -} - -Thread::~Thread() -{ - /* Send out summary message */ - stdout_message("Thread %s summary: %d waits plus %d contended\n", - name, waits, contends); -} - -void Thread::monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object) -{ - contends++; -} - -void Thread::monitor_wait(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jlong timeout) -{ - waits++; -} - -void Thread::monitor_waited(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jboolean timed_out) -{ - if ( timed_out ) { - timeouts++; - } -} diff --git a/jdk/src/demo/share/jvmti/waiters/Thread.hpp b/jdk/src/demo/share/jvmti/waiters/Thread.hpp deleted file mode 100644 index 0ad661521e6..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/Thread.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* C++ Thread class */ - -class Thread { - - private: - char name[64]; - unsigned contends; - unsigned waits; - unsigned timeouts; - - public: - Thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread); - ~Thread(); - void monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object); - void monitor_wait(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jlong timeout); - void monitor_waited(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jboolean timed_out); - -}; diff --git a/jdk/src/demo/share/jvmti/waiters/sample.makefile.txt b/jdk/src/demo/share/jvmti/waiters/sample.makefile.txt deleted file mode 100644 index 51cbca4a395..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/sample.makefile.txt +++ /dev/null @@ -1,149 +0,0 @@ -# -# Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -######################################################################## -# -# Sample GNU Makefile for building JVMTI Demo waiters -# -# Example uses: -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparc] -# gnumake JDK= OSNAME=solaris [OPT=true] [LIBARCH=sparcv9] -# gnumake JDK= OSNAME=linux [OPT=true] -# gnumake JDK= OSNAME=win32 [OPT=true] -# -######################################################################## - -# Source lists -LIBNAME=waiters -SOURCES=waiters.cpp Agent.cpp Thread.cpp Monitor.cpp ../agent_util/agent_util.c - -# Solaris Sun C Compiler Version 5.5 -ifeq ($(OSNAME), solaris) - # Tell gnumake which compilers to use - CC=cc - CXX=CC - # Sun Solaris Compiler options needed - COMMON_FLAGS=-mt -KPIC - # Check LIBARCH for any special compiler options - LIBARCH=$(shell uname -p) - ifeq ($(LIBARCH), sparc) - COMMON_FLAGS+=-xarch=v8 -xregs=no%appl - endif - ifeq ($(LIBARCH), sparcv9) - COMMON_FLAGS+=-xarch=v9 -xregs=no%appl - endif - ifeq ($(OPT), true) - CXXFLAGS=-xO2 $(COMMON_FLAGS) - else - CXXFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.cpp=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-z defs -ztext - # Libraries we are dependent on - LIBRARIES= -lc - # Building a shared library - LINK_SHARED=$(LINK.cc) -G -o $@ -endif - -# Linux GNU C Compiler -ifeq ($(OSNAME), linux) - # GNU Compiler options needed to build it - COMMON_FLAGS=-fno-strict-aliasing -fPIC -fno-omit-frame-pointer - # Options that help find errors - COMMON_FLAGS+= -W -Wall -Wno-unused -Wno-parentheses - ifeq ($(OPT), true) - CXXFLAGS=-O2 $(COMMON_FLAGS) - else - CXXFLAGS=-g $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.cpp=%.o) - # Library name and options needed to build it - LIBRARY=lib$(LIBNAME).so - LDFLAGS=-Wl,-soname=$(LIBRARY) -static-libgcc - # Libraries we are dependent on - LIBRARIES= - # Building a shared library - LINK_SHARED=$(LINK.cc) -shared -o $@ -endif - -# Windows Microsoft C/C++ Optimizing Compiler Version 12 -ifeq ($(OSNAME), win32) - CC=cl - # Compiler options needed to build it - COMMON_FLAGS=-Gy -DWIN32 - # Options that help find errors - COMMON_FLAGS+=-W0 -WX - ifeq ($(OPT), true) - CXXFLAGS= -Ox -Op -Zi $(COMMON_FLAGS) - else - CXXFLAGS= -Od -Zi $(COMMON_FLAGS) - endif - # Object files needed to create library - OBJECTS=$(SOURCES:%.cpp=%.obj) - # Library name and options needed to build it - LIBRARY=$(LIBNAME).dll - LDFLAGS= - # Libraries we are dependent on - LIBRARIES= - # Building a shared library - LINK_SHARED=link -dll -out:$@ -endif - -# Common -I options -CXXFLAGS += -I. -CXXFLAGS += -I../agent_util -CXXFLAGS += -I$(JDK)/include -I$(JDK)/include/$(OSNAME) - -# Default rule -all: $(LIBRARY) - -# Build native library -$(LIBRARY): $(OBJECTS) - $(LINK_SHARED) $(OBJECTS) $(LIBRARIES) - -# Cleanup the built bits -clean: - rm -f $(LIBRARY) $(OBJECTS) - -# Simple tester -test: all - LD_LIBRARY_PATH=`pwd` $(JDK)/bin/java -agentlib:$(LIBNAME) -version - -# Compilation rule only needed on Windows -ifeq ($(OSNAME), win32) -%.obj: %.cpp - $(COMPILE.cc) $< -endif - diff --git a/jdk/src/demo/share/jvmti/waiters/waiters.cpp b/jdk/src/demo/share/jvmti/waiters/waiters.cpp deleted file mode 100644 index cf38e00e160..00000000000 --- a/jdk/src/demo/share/jvmti/waiters/waiters.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* Example of using JVMTI events: - * JVMTI_EVENT_VM_INIT - * JVMTI_EVENT_VM_DEATH - * JVMTI_EVENT_THREAD_START - * JVMTI_EVENT_THREAD_END - * JVMTI_EVENT_MONITOR_CONTENDED_ENTER - * JVMTI_EVENT_MONITOR_WAIT - * JVMTI_EVENT_MONITOR_WAITED - * JVMTI_EVENT_OBJECT_FREE - */ - -#include -#include -#include - -#include "jni.h" -#include "jvmti.h" - -#include "agent_util.h" - -#include "Monitor.hpp" -#include "Thread.hpp" -#include "Agent.hpp" - -static jrawMonitorID vm_death_lock; -static jboolean vm_death_active; - -/* Given a jvmtiEnv*, return the C++ Agent class instance */ -static Agent * -get_agent(jvmtiEnv *jvmti) -{ - jvmtiError err; - Agent *agent; - - agent = NULL; - err = jvmti->GetEnvironmentLocalStorage((void**)&agent); - check_jvmti_error(jvmti, err, "get env local storage"); - if ( agent == NULL ) { - /* This should never happen, but we should check */ - fatal_error("ERROR: GetEnvironmentLocalStorage() returned NULL"); - } - return agent; -} - -/* Enter raw monitor */ -static void -menter(jvmtiEnv *jvmti, jrawMonitorID rmon) -{ - jvmtiError err; - - err = jvmti->RawMonitorEnter(rmon); - check_jvmti_error(jvmti, err, "raw monitor enter"); -} - -/* Exit raw monitor */ -static void -mexit(jvmtiEnv *jvmti, jrawMonitorID rmon) -{ - jvmtiError err; - - err = jvmti->RawMonitorExit(rmon); - check_jvmti_error(jvmti, err, "raw monitor exit"); -} - - -/* All callbacks need to be extern "C" */ -extern "C" { - static void JNICALL - vm_init(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) - { - jvmtiError err; - Agent *agent; - - /* Create raw monitor to protect against threads running after death */ - err = jvmti->CreateRawMonitor("Waiters vm_death lock", &vm_death_lock); - check_jvmti_error(jvmti, err, "create raw monitor"); - vm_death_active = JNI_FALSE; - - /* Create an Agent instance, set JVMTI Local Storage */ - agent = new Agent(jvmti, env, thread); - err = jvmti->SetEnvironmentLocalStorage((const void*)agent); - check_jvmti_error(jvmti, err, "set env local storage"); - - /* Enable all other events we want */ - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_VM_DEATH, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_THREAD_START, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_THREAD_END, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_MONITOR_WAIT, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_MONITOR_WAITED, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_OBJECT_FREE, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - } - static void JNICALL - vm_death(jvmtiEnv *jvmti, JNIEnv *env) - { - jvmtiError err; - Agent *agent; - - /* Block all callbacks */ - menter(jvmti, vm_death_lock); { - /* Set flag for other callbacks */ - vm_death_active = JNI_TRUE; - - /* Inform Agent instance of VM_DEATH */ - agent = get_agent(jvmti); - agent->vm_death(jvmti, env); - - /* Reclaim space of Agent */ - err = jvmti->SetEnvironmentLocalStorage((const void*)NULL); - check_jvmti_error(jvmti, err, "set env local storage"); - delete agent; - } mexit(jvmti, vm_death_lock); - - } - static void JNICALL - thread_start(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) - { - menter(jvmti, vm_death_lock); { - if ( !vm_death_active ) { - get_agent(jvmti)->thread_start(jvmti, env, thread); - } - } mexit(jvmti, vm_death_lock); - } - static void JNICALL - thread_end(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) - { - menter(jvmti, vm_death_lock); { - if ( !vm_death_active ) { - get_agent(jvmti)->thread_end(jvmti, env, thread); - } - } mexit(jvmti, vm_death_lock); - } - static void JNICALL - monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object) - { - menter(jvmti, vm_death_lock); { - if ( !vm_death_active ) { - get_agent(jvmti)->monitor_contended_enter(jvmti, env, - thread, object); - } - } mexit(jvmti, vm_death_lock); - } - static void JNICALL - monitor_contended_entered(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object) - { - menter(jvmti, vm_death_lock); { - if ( !vm_death_active ) { - get_agent(jvmti)->monitor_contended_entered(jvmti, env, - thread, object); - } - } mexit(jvmti, vm_death_lock); - } - static void JNICALL - monitor_wait(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jlong timeout) - { - menter(jvmti, vm_death_lock); { - if ( !vm_death_active ) { - get_agent(jvmti)->monitor_wait(jvmti, env, thread, - object, timeout); - } - } mexit(jvmti, vm_death_lock); - } - static void JNICALL - monitor_waited(jvmtiEnv* jvmti, JNIEnv *env, - jthread thread, jobject object, jboolean timed_out) - { - menter(jvmti, vm_death_lock); { - if ( !vm_death_active ) { - get_agent(jvmti)->monitor_waited(jvmti, env, thread, - object, timed_out); - } - } mexit(jvmti, vm_death_lock); - } - static void JNICALL - object_free(jvmtiEnv* jvmti, jlong tag) - { - menter(jvmti, vm_death_lock); { - if ( !vm_death_active ) { - get_agent(jvmti)->object_free(jvmti, tag); - } - } mexit(jvmti, vm_death_lock); - } - - /* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */ - JNIEXPORT jint JNICALL - DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved) - { - jvmtiEnv *jvmti; - jint rc; - jvmtiError err; - jvmtiCapabilities capabilities; - jvmtiEventCallbacks callbacks; - - /* Get JVMTI environment */ - rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION); - if (rc != JNI_OK) { - fatal_error("ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc); - return -1; - } - - /* Get/Add JVMTI capabilities */ - (void)memset(&capabilities, 0, sizeof(capabilities)); - capabilities.can_generate_monitor_events = 1; - capabilities.can_get_monitor_info = 1; - capabilities.can_tag_objects = 1; - capabilities.can_generate_object_free_events = 1; - err = jvmti->AddCapabilities(&capabilities); - check_jvmti_error(jvmti, err, "add capabilities"); - - /* Set all callbacks and enable VM_INIT event notification */ - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.VMInit = &vm_init; - callbacks.VMDeath = &vm_death; - callbacks.ThreadStart = &thread_start; - callbacks.ThreadEnd = &thread_end; - callbacks.MonitorContendedEnter = &monitor_contended_enter; - callbacks.MonitorContendedEntered = &monitor_contended_entered; - callbacks.MonitorWait = &monitor_wait; - callbacks.MonitorWaited = &monitor_waited; - callbacks.ObjectFree = &object_free; - err = jvmti->SetEventCallbacks(&callbacks, (jint)sizeof(callbacks)); - check_jvmti_error(jvmti, err, "set event callbacks"); - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, NULL); - check_jvmti_error(jvmti, err, "set event notify"); - return 0; - } - - /* Agent_OnUnload() is called last */ - JNIEXPORT void JNICALL - DEF_Agent_OnUnload(JavaVM *vm) - { - } - -} /* of extern "C" */ diff --git a/jdk/src/demo/share/management/FullThreadDump/Deadlock.java b/jdk/src/demo/share/management/FullThreadDump/Deadlock.java deleted file mode 100644 index 85668ee50da..00000000000 --- a/jdk/src/demo/share/management/FullThreadDump/Deadlock.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - */ - -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.io.IOException; - -/** - * This Deadlock class demonstrates the capability of performing - * deadlock detection programmatically within the application using - * the java.lang.management API. - * - * See ThreadMonitor.java for the use of java.lang.management.ThreadMXBean - * API. - */ -public class Deadlock { - public static void main(String[] argv) { - new Deadlock(); - - // Now find deadlock - ThreadMonitor monitor = new ThreadMonitor(); - boolean found = false; - while (!found) { - found = monitor.findDeadlock(); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - System.exit(1); - } - } - - System.out.println("\nPress to exit this Deadlock program.\n"); - waitForEnterPressed(); - } - - - private CyclicBarrier barrier = new CyclicBarrier(6); - public Deadlock() { - DeadlockThread[] dThreads = new DeadlockThread[6]; - - Monitor a = new Monitor("a"); - Monitor b = new Monitor("b"); - Monitor c = new Monitor("c"); - dThreads[0] = new DeadlockThread("MThread-1", a, b); - dThreads[1] = new DeadlockThread("MThread-2", b, c); - dThreads[2] = new DeadlockThread("MThread-3", c, a); - - Lock d = new ReentrantLock(); - Lock e = new ReentrantLock(); - Lock f = new ReentrantLock(); - - dThreads[3] = new DeadlockThread("SThread-4", d, e); - dThreads[4] = new DeadlockThread("SThread-5", e, f); - dThreads[5] = new DeadlockThread("SThread-6", f, d); - - // make them daemon threads so that the test will exit - for (int i = 0; i < 6; i++) { - dThreads[i].setDaemon(true); - dThreads[i].start(); - } - } - - class DeadlockThread extends Thread { - private Lock lock1 = null; - private Lock lock2 = null; - private Monitor mon1 = null; - private Monitor mon2 = null; - private boolean useSync; - - DeadlockThread(String name, Lock lock1, Lock lock2) { - super(name); - this.lock1 = lock1; - this.lock2 = lock2; - this.useSync = true; - } - DeadlockThread(String name, Monitor mon1, Monitor mon2) { - super(name); - this.mon1 = mon1; - this.mon2 = mon2; - this.useSync = false; - } - @Override - public void run() { - if (useSync) { - syncLock(); - } else { - monitorLock(); - } - } - private void syncLock() { - lock1.lock(); - try { - try { - barrier.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - System.exit(1); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - System.exit(1); - } - goSyncDeadlock(); - } finally { - lock1.unlock(); - } - } - private void goSyncDeadlock() { - try { - barrier.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - System.exit(1); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - System.exit(1); - } - lock2.lock(); - throw new RuntimeException("should not reach here."); - } - private void monitorLock() { - synchronized (mon1) { - try { - barrier.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - System.exit(1); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - System.exit(1); - } - goMonitorDeadlock(); - } - } - private void goMonitorDeadlock() { - try { - barrier.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - System.exit(1); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - System.exit(1); - } - synchronized (mon2) { - throw new RuntimeException(getName() + " should not reach here."); - } - } - } - - class Monitor { - String name; - Monitor(String name) { - this.name = name; - } - } - - private static void waitForEnterPressed() { - try { - boolean done = false; - while (!done) { - char ch = (char) System.in.read(); - if (ch<0||ch=='\n') { - done = true; - } - } - } - catch (IOException e) { - e.printStackTrace(); - System.exit(0); - } - } -} diff --git a/jdk/src/demo/share/management/FullThreadDump/FullThreadDump.java b/jdk/src/demo/share/management/FullThreadDump/FullThreadDump.java deleted file mode 100644 index ba46eeb828c..00000000000 --- a/jdk/src/demo/share/management/FullThreadDump/FullThreadDump.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - */ - -import javax.management.*; -import javax.management.remote.*; -import java.io.IOException; -import java.net.MalformedURLException; - -/** - * This FullThreadDump class demonstrates the capability to get - * a full thread dump and also detect deadlock remotely. - */ -public class FullThreadDump { - private MBeanServerConnection server; - private JMXConnector jmxc; - public FullThreadDump(String hostname, int port) { - System.out.println("Connecting to " + hostname + ":" + port); - - // Create an RMI connector client and connect it to - // the RMI connector server - String urlPath = "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi"; - connect(urlPath); - } - - public void dump() { - try { - ThreadMonitor monitor = new ThreadMonitor(server); - monitor.threadDump(); - if (!monitor.findDeadlock()) { - System.out.println("No deadlock found."); - } - } catch (IOException e) { - System.err.println("\nCommunication error: " + e.getMessage()); - System.exit(1); - } - } - - /** - * Connect to a JMX agent of a given URL. - */ - private void connect(String urlPath) { - try { - JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath); - this.jmxc = JMXConnectorFactory.connect(url); - this.server = jmxc.getMBeanServerConnection(); - } catch (MalformedURLException e) { - // should not reach here - } catch (IOException e) { - System.err.println("\nCommunication error: " + e.getMessage()); - System.exit(1); - } - } - - public static void main(String[] args) { - if (args.length != 1) { - usage(); - } - - String[] arg2 = args[0].split(":"); - if (arg2.length != 2) { - usage(); - } - String hostname = arg2[0]; - int port = -1; - try { - port = Integer.parseInt(arg2[1]); - } catch (NumberFormatException x) { - usage(); - } - if (port < 0) { - usage(); - } - - // get full thread dump and perform deadlock detection - FullThreadDump ftd = new FullThreadDump(hostname, port); - ftd.dump(); - } - - private static void usage() { - System.out.println("Usage: java FullThreadDump :"); - } -} diff --git a/jdk/src/demo/share/management/FullThreadDump/README.txt b/jdk/src/demo/share/management/FullThreadDump/README.txt deleted file mode 100644 index 1571fb86596..00000000000 --- a/jdk/src/demo/share/management/FullThreadDump/README.txt +++ /dev/null @@ -1,52 +0,0 @@ -FullThreadDump demonstrates the use of the java.lang.management API -to print the full thread dump. JDK 6 defines a new API to dump -the information about monitors and java.util.concurrent ownable -synchronizers. - -This demo also illustrates how to monitor JDK 5 and JDK 6 VMs with -two versions of APIs. - -It contains two parts: -a) Local monitoring within the application -b) Remote monitoring by connecting to a JMX agent with a JMX service URL: - service:jmx:rmi:///jndi/rmi://:/jmxrmi - where is the hostname and is the port number - to which the JMX agent will be connected. - -To run the demo ---------------- -a) Local Monitoring - - java -cp /demo/management/FullThreadDump/FullThreadDump.jar Deadlock - - This will dump the stack trace and then detect deadlocks locally - within the application. - -b) Remote Monitoring - - (1) Start the Deadlock application (or any other application) - with the JMX agent as follows: - - java -Dcom.sun.management.jmxremote.port=1090 - -Dcom.sun.management.jmxremote.ssl=false - -Dcom.sun.management.jmxremote.authenticate=false - -cp /demo/management/FullThreadDump/FullThreadDump.jar - Deadlock - - This instruction uses the Sun's built-in support to enable a JMX agent. - You can programmatically start a JMX agent with the RMI connector - using javax.management.remote API. See the javadoc and examples for - javax.management.remote API for details. - - (2) Run FullThreadDump - - java -jar /demo/management/FullThreadDump/FullThreadDump.jar \ - localhost:1090 - - This will dump the stack trace and then print out the deadlocked threads. - -These instructions assume that this installation's version of the java -command is in your path. If it isn't, then you should either -specify the complete path to the java command or update your -PATH environment variable as described in the installation -instructions for the Java(TM) SDK. diff --git a/jdk/src/demo/share/management/FullThreadDump/ThreadMonitor.java b/jdk/src/demo/share/management/FullThreadDump/ThreadMonitor.java deleted file mode 100644 index 05846e7c182..00000000000 --- a/jdk/src/demo/share/management/FullThreadDump/ThreadMonitor.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - */ - -import static java.lang.management.ManagementFactory.*; -import java.lang.management.ThreadMXBean; -import java.lang.management.ThreadInfo; -import java.lang.management.LockInfo; -import java.lang.management.MonitorInfo; -import javax.management.*; -import java.io.*; - -/** - * Example of using the java.lang.management API to dump stack trace - * and to perform deadlock detection. - * - * @author Mandy Chung - */ -public class ThreadMonitor { - private MBeanServerConnection server; - private ThreadMXBean tmbean; - private ObjectName objname; - - // default - JDK 6+ VM - private String findDeadlocksMethodName = "findDeadlockedThreads"; - private boolean canDumpLocks = true; - - /** - * Constructs a ThreadMonitor object to get thread information - * in a remote JVM. - */ - public ThreadMonitor(MBeanServerConnection server) throws IOException { - this.server = server; - this.tmbean = newPlatformMXBeanProxy(server, - THREAD_MXBEAN_NAME, - ThreadMXBean.class); - try { - objname = new ObjectName(THREAD_MXBEAN_NAME); - } catch (MalformedObjectNameException e) { - // should not reach here - InternalError ie = new InternalError(e.getMessage()); - ie.initCause(e); - throw ie; - } - parseMBeanInfo(); - } - - /** - * Constructs a ThreadMonitor object to get thread information - * in the local JVM. - */ - public ThreadMonitor() { - this.tmbean = getThreadMXBean(); - } - - /** - * Prints the thread dump information to System.out. - */ - public void threadDump() { - if (canDumpLocks) { - if (tmbean.isObjectMonitorUsageSupported() && - tmbean.isSynchronizerUsageSupported()) { - // Print lock info if both object monitor usage - // and synchronizer usage are supported. - // This sample code can be modified to handle if - // either monitor usage or synchronizer usage is supported. - dumpThreadInfoWithLocks(); - } - } else { - dumpThreadInfo(); - } - } - - private void dumpThreadInfo() { - System.out.println("Full Java thread dump"); - long[] tids = tmbean.getAllThreadIds(); - ThreadInfo[] tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); - for (ThreadInfo ti : tinfos) { - printThreadInfo(ti); - } - } - - /** - * Prints the thread dump information with locks info to System.out. - */ - private void dumpThreadInfoWithLocks() { - System.out.println("Full Java thread dump with locks info"); - - ThreadInfo[] tinfos = tmbean.dumpAllThreads(true, true); - for (ThreadInfo ti : tinfos) { - printThreadInfo(ti); - LockInfo[] syncs = ti.getLockedSynchronizers(); - printLockInfo(syncs); - } - System.out.println(); - } - - private static String INDENT = " "; - - private void printThreadInfo(ThreadInfo ti) { - // print thread information - printThread(ti); - - // print stack trace with locks - StackTraceElement[] stacktrace = ti.getStackTrace(); - MonitorInfo[] monitors = ti.getLockedMonitors(); - for (int i = 0; i < stacktrace.length; i++) { - StackTraceElement ste = stacktrace[i]; - System.out.println(INDENT + "at " + ste.toString()); - for (MonitorInfo mi : monitors) { - if (mi.getLockedStackDepth() == i) { - System.out.println(INDENT + " - locked " + mi); - } - } - } - System.out.println(); - } - - private void printThread(ThreadInfo ti) { - StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" + - " Id=" + ti.getThreadId() + - " in " + ti.getThreadState()); - if (ti.getLockName() != null) { - sb.append(" on lock=" + ti.getLockName()); - } - if (ti.isSuspended()) { - sb.append(" (suspended)"); - } - if (ti.isInNative()) { - sb.append(" (running in native)"); - } - System.out.println(sb.toString()); - if (ti.getLockOwnerName() != null) { - System.out.println(INDENT + " owned by " + ti.getLockOwnerName() + - " Id=" + ti.getLockOwnerId()); - } - } - - private void printMonitorInfo(ThreadInfo ti) { - MonitorInfo[] monitors = ti.getLockedMonitors(); - System.out.println(INDENT + "Locked monitors: count = " + monitors.length); - for (MonitorInfo mi : monitors) { - System.out.println(INDENT + " - " + mi + " locked at "); - System.out.println(INDENT + " " + mi.getLockedStackDepth() + - " " + mi.getLockedStackFrame()); - } - } - - private void printLockInfo(LockInfo[] locks) { - System.out.println(INDENT + "Locked synchronizers: count = " + locks.length); - for (LockInfo li : locks) { - System.out.println(INDENT + " - " + li); - } - System.out.println(); - } - - /** - * Checks if any threads are deadlocked. If any, print - * the thread dump information. - */ - public boolean findDeadlock() { - long[] tids; - if (findDeadlocksMethodName.equals("findDeadlockedThreads") && - tmbean.isSynchronizerUsageSupported()) { - tids = tmbean.findDeadlockedThreads(); - if (tids == null) { - return false; - } - - System.out.println("Deadlock found :-"); - ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true); - for (ThreadInfo ti : infos) { - printThreadInfo(ti); - printMonitorInfo(ti); - printLockInfo(ti.getLockedSynchronizers()); - System.out.println(); - } - } else { - tids = tmbean.findMonitorDeadlockedThreads(); - if (tids == null) { - return false; - } - ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); - for (ThreadInfo ti : infos) { - // print thread information - printThreadInfo(ti); - } - } - - return true; - } - - - private void parseMBeanInfo() throws IOException { - try { - MBeanOperationInfo[] mopis = server.getMBeanInfo(objname).getOperations(); - - // look for findDeadlockedThreads operations; - boolean found = false; - for (MBeanOperationInfo op : mopis) { - if (op.getName().equals(findDeadlocksMethodName)) { - found = true; - break; - } - } - if (!found) { - // if findDeadlockedThreads operation doesn't exist, - // the target VM is running on JDK 5 and details about - // synchronizers and locks cannot be dumped. - findDeadlocksMethodName = "findMonitorDeadlockedThreads"; - canDumpLocks = false; - } - } catch (IntrospectionException e) { - InternalError ie = new InternalError(e.getMessage()); - ie.initCause(e); - throw ie; - } catch (InstanceNotFoundException e) { - InternalError ie = new InternalError(e.getMessage()); - ie.initCause(e); - throw ie; - } catch (ReflectionException e) { - InternalError ie = new InternalError(e.getMessage()); - ie.initCause(e); - throw ie; - } - } -} diff --git a/jdk/src/demo/share/management/JTop/JTop.java b/jdk/src/demo/share/management/JTop/JTop.java deleted file mode 100644 index c1d48cc3716..00000000000 --- a/jdk/src/demo/share/management/JTop/JTop.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * - * Example of using the java.lang.management API to sort threads - * by CPU usage. - * - * JTop class can be run as a standalone application. - * It first establishs a connection to a target VM specified - * by the given hostname and port number where the JMX agent - * to be connected. It then polls for the thread information - * and the CPU consumption of each thread to display every 2 - * seconds. - * - * It is also used by JTopPlugin which is a JConsolePlugin - * that can be used with JConsole (see README.txt). The JTop - * GUI will be added as a JConsole tab by the JTop plugin. - * - * @see com.sun.tools.jconsole.JConsolePlugin - * - * @author Mandy Chung - */ -import java.lang.management.*; -import javax.management.*; -import javax.management.remote.*; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.Timer; -import java.util.TimerTask; -import java.util.TreeMap; -import java.util.concurrent.ExecutionException; -import java.text.NumberFormat; -import java.net.MalformedURLException; -import static java.lang.management.ManagementFactory.*; - -import java.awt.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.table.*; - -/** - * JTop is a JPanel to display thread's name, CPU time, and its state - * in a table. - */ -public class JTop extends JPanel { - - private static class StatusBar extends JPanel { - private static final long serialVersionUID = -6483392381797633018L; - private final JLabel statusText; - - public StatusBar(boolean defaultVisible) { - super(new GridLayout(1, 1)); - statusText = new JLabel(); - statusText.setVisible(defaultVisible); - add(statusText); - } - - @Override - public Dimension getMaximumSize() { - Dimension maximum = super.getMaximumSize(); - Dimension minimum = getMinimumSize(); - return new Dimension(maximum.width, minimum.height); - } - - public void setMessage(String text) { - statusText.setText(text); - statusText.setVisible(true); - } - } - private static final long serialVersionUID = -1499762160973870696L; - private MBeanServerConnection server; - private ThreadMXBean tmbean; - private MyTableModel tmodel; - private final StatusBar statusBar; - public JTop() { - super(new GridBagLayout()); - - tmodel = new MyTableModel(); - JTable table = new JTable(tmodel); - table.setPreferredScrollableViewportSize(new Dimension(500, 300)); - - // Set the renderer to format Double - table.setDefaultRenderer(Double.class, new DoubleRenderer()); - // Add some space - table.setIntercellSpacing(new Dimension(6,3)); - table.setRowHeight(table.getRowHeight() + 4); - - // Create the scroll pane and add the table to it. - JScrollPane scrollPane = new JScrollPane(table); - - // Add the scroll pane to this panel. - GridBagConstraints c1 = new GridBagConstraints(); - c1.fill = GridBagConstraints.BOTH; - c1.gridy = 0; - c1.gridx = 0; - c1.weightx = 1; - c1.weighty = 1; - add(scrollPane, c1); - - statusBar = new StatusBar(false); - GridBagConstraints c2 = new GridBagConstraints(); - c2.fill = GridBagConstraints.HORIZONTAL; - c2.gridy = 1; - c2.gridx = 0; - c2.weightx = 1.0; - c2.weighty = 0.0; - add(statusBar, c2); - } - - // Set the MBeanServerConnection object for communicating - // with the target VM - public void setMBeanServerConnection(MBeanServerConnection mbs) { - this.server = mbs; - try { - this.tmbean = newPlatformMXBeanProxy(server, - THREAD_MXBEAN_NAME, - ThreadMXBean.class); - } catch (IOException e) { - e.printStackTrace(); - } - if (!tmbean.isThreadCpuTimeSupported()) { - statusBar.setMessage("Monitored VM does not support thread CPU time measurement"); - } else { - try { - tmbean.setThreadCpuTimeEnabled(true); - } catch (SecurityException e) { - statusBar.setMessage("Monitored VM does not have permission for enabling thread cpu time measurement"); - } - } - } - - class MyTableModel extends AbstractTableModel { - private static final long serialVersionUID = -7877310288576779514L; - private String[] columnNames = {"ThreadName", - "CPU(sec)", - "State"}; - // List of all threads. The key of each entry is the CPU time - // and its value is the ThreadInfo object with no stack trace. - private List> threadList = - Collections.emptyList(); - - public MyTableModel() { - } - - @Override - public int getColumnCount() { - return columnNames.length; - } - - @Override - public int getRowCount() { - return threadList.size(); - } - - @Override - public String getColumnName(int col) { - return columnNames[col]; - } - - @Override - public Object getValueAt(int row, int col) { - Map.Entry me = threadList.get(row); - switch (col) { - case 0 : - // Column 0 shows the thread name - return me.getValue().getThreadName(); - case 1 : - // Column 1 shows the CPU usage - long ns = me.getKey().longValue(); - double sec = ns / 1000000000; - return new Double(sec); - case 2 : - // Column 2 shows the thread state - return me.getValue().getThreadState(); - default: - return null; - } - } - - @Override - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - void setThreadList(List> list) { - threadList = list; - } - } - - /** - * Get the thread list with CPU consumption and the ThreadInfo - * for each thread sorted by the CPU time. - */ - private List> getThreadList() { - // Get all threads and their ThreadInfo objects - // with no stack trace - long[] tids = tmbean.getAllThreadIds(); - ThreadInfo[] tinfos = tmbean.getThreadInfo(tids); - - // build a map with key = CPU time and value = ThreadInfo - SortedMap map = new TreeMap(); - for (int i = 0; i < tids.length; i++) { - long cpuTime = tmbean.getThreadCpuTime(tids[i]); - // filter out threads that have been terminated - if (cpuTime != -1 && tinfos[i] != null) { - map.put(new Long(cpuTime), tinfos[i]); - } - } - - // build the thread list and sort it with CPU time - // in decreasing order - Set> set = map.entrySet(); - List> list = - new ArrayList>(set); - Collections.reverse(list); - return list; - } - - - /** - * Format Double with 4 fraction digits - */ - class DoubleRenderer extends DefaultTableCellRenderer { - private static final long serialVersionUID = 1704639497162584382L; - NumberFormat formatter; - public DoubleRenderer() { - super(); - setHorizontalAlignment(JLabel.RIGHT); - } - - @Override - public void setValue(Object value) { - if (formatter==null) { - formatter = NumberFormat.getInstance(); - formatter.setMinimumFractionDigits(4); - } - setText((value == null) ? "" : formatter.format(value)); - } - } - - // SwingWorker responsible for updating the GUI - // - // It first gets the thread and CPU usage information as a - // background task done by a worker thread so that - // it will not block the event dispatcher thread. - // - // When the worker thread finishes, the event dispatcher - // thread will invoke the done() method which will update - // the UI. - class Worker extends SwingWorker>,Object> { - private MyTableModel tmodel; - Worker(MyTableModel tmodel) { - this.tmodel = tmodel; - } - - // Get the current thread info and CPU time - @Override - public List> doInBackground() { - return getThreadList(); - } - - // fire table data changed to trigger GUI update - // when doInBackground() is finished - @Override - protected void done() { - try { - // Set table model with the new thread list - tmodel.setThreadList(get()); - // refresh the table model - tmodel.fireTableDataChanged(); - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - } - } - - // Return a new SwingWorker for UI update - public SwingWorker newSwingWorker() { - return new Worker(tmodel); - } - - public static void main(String[] args) throws Exception { - // Validate the input arguments - if (args.length != 1) { - usage(); - } - - String[] arg2 = args[0].split(":"); - if (arg2.length != 2) { - usage(); - } - String hostname = arg2[0]; - int port = -1; - try { - port = Integer.parseInt(arg2[1]); - } catch (NumberFormatException x) { - usage(); - } - if (port < 0) { - usage(); - } - - // Create the JTop Panel - final JTop jtop = new JTop(); - // Set up the MBeanServerConnection to the target VM - MBeanServerConnection server = connect(hostname, port); - jtop.setMBeanServerConnection(server); - - // A timer task to update GUI per each interval - TimerTask timerTask = new TimerTask() { - @Override - public void run() { - // Schedule the SwingWorker to update the GUI - jtop.newSwingWorker().execute(); - } - }; - - // Create the standalone window with JTop panel - // by the event dispatcher thread - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - createAndShowGUI(jtop); - } - }); - - // refresh every 2 seconds - Timer timer = new Timer("JTop Sampling thread"); - timer.schedule(timerTask, 0, 2000); - - } - - // Establish a connection with the remote application - // - // You can modify the urlPath to the address of the JMX agent - // of your application if it has a different URL. - // - // You can also modify the following code to take - // username and password for client authentication. - private static MBeanServerConnection connect(String hostname, int port) { - // Create an RMI connector client and connect it to - // the RMI connector server - String urlPath = "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi"; - MBeanServerConnection server = null; - try { - JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath); - JMXConnector jmxc = JMXConnectorFactory.connect(url); - server = jmxc.getMBeanServerConnection(); - } catch (MalformedURLException e) { - // should not reach here - } catch (IOException e) { - System.err.println("\nCommunication error: " + e.getMessage()); - System.exit(1); - } - return server; - } - - private static void usage() { - System.out.println("Usage: java JTop :"); - System.exit(1); - } - /** - * Create the GUI and show it. For thread safety, - * this method should be invoked from the - * event-dispatching thread. - */ - private static void createAndShowGUI(JPanel jtop) { - // Create and set up the window. - JFrame frame = new JFrame("JTop"); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - - // Create and set up the content pane. - JComponent contentPane = (JComponent) frame.getContentPane(); - contentPane.add(jtop, BorderLayout.CENTER); - contentPane.setOpaque(true); //content panes must be opaque - contentPane.setBorder(new EmptyBorder(12, 12, 12, 12)); - frame.setContentPane(contentPane); - - // Display the window. - frame.pack(); - frame.setVisible(true); - } - -} diff --git a/jdk/src/demo/share/management/JTop/JTopPlugin.java b/jdk/src/demo/share/management/JTop/JTopPlugin.java deleted file mode 100644 index 785bb328db4..00000000000 --- a/jdk/src/demo/share/management/JTop/JTopPlugin.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * - * Example of a JConsole Plugin. This loads JTop as a JConsole tab. - * - * @author Mandy Chung - */ - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.swing.JPanel; -import javax.swing.SwingWorker; - -import com.sun.tools.jconsole.JConsoleContext; -import com.sun.tools.jconsole.JConsoleContext.ConnectionState; -import com.sun.tools.jconsole.JConsolePlugin; - -/** - * JTopPlugin is a subclass to com.sun.tools.jconsole.JConsolePlugin - * - * JTopPlugin is loaded and instantiated by JConsole. One instance - * is created for each window that JConsole creates. It listens to - * the connected property change so that it will update JTop with - * the valid MBeanServerConnection object. JTop is a JPanel object - * displaying the thread and its CPU usage information. - */ -public class JTopPlugin extends JConsolePlugin implements PropertyChangeListener -{ - private JTop jtop = null; - private Map tabs = null; - - public JTopPlugin() { - // register itself as a listener - addContextPropertyChangeListener(this); - } - - /* - * Returns a JTop tab to be added in JConsole. - */ - @Override - public synchronized Map getTabs() { - if (tabs == null) { - jtop = new JTop(); - jtop.setMBeanServerConnection( - getContext().getMBeanServerConnection()); - // use LinkedHashMap if you want a predictable order - // of the tabs to be added in JConsole - tabs = new LinkedHashMap(); - tabs.put("JTop", jtop); - } - return tabs; - } - - /* - * Returns a SwingWorker which is responsible for updating the JTop tab. - */ - @Override - public SwingWorker newSwingWorker() { - return jtop.newSwingWorker(); - } - - // You can implement the dispose() method if you need to release - // any resource when the plugin instance is disposed when the JConsole - // window is closed. - // - // public void dispose() { - // } - - /* - * Property listener to reset the MBeanServerConnection - * at reconnection time. - */ - @Override - public void propertyChange(PropertyChangeEvent ev) { - String prop = ev.getPropertyName(); - if (prop == JConsoleContext.CONNECTION_STATE_PROPERTY) { - ConnectionState newState = (ConnectionState)ev.getNewValue(); - // JConsole supports disconnection and reconnection - // The MBeanServerConnection will become invalid when - // disconnected. Need to use the new MBeanServerConnection object - // created at reconnection time. - if (newState == ConnectionState.CONNECTED && jtop != null) { - jtop.setMBeanServerConnection( - getContext().getMBeanServerConnection()); - } - } - } -} diff --git a/jdk/src/demo/share/management/JTop/META-INF/services/com.sun.tools.jconsole.JConsolePlugin b/jdk/src/demo/share/management/JTop/META-INF/services/com.sun.tools.jconsole.JConsolePlugin deleted file mode 100644 index 11aa2aea385..00000000000 --- a/jdk/src/demo/share/management/JTop/META-INF/services/com.sun.tools.jconsole.JConsolePlugin +++ /dev/null @@ -1 +0,0 @@ -JTopPlugin diff --git a/jdk/src/demo/share/management/JTop/README.txt b/jdk/src/demo/share/management/JTop/README.txt deleted file mode 100644 index b2d3ae43c04..00000000000 --- a/jdk/src/demo/share/management/JTop/README.txt +++ /dev/null @@ -1,61 +0,0 @@ -JTop monitors the CPU usage of all threads in a remote application -which has remote management enabled. JTop demonstrates the use of -the java.lang.management API to obtain the CPU consumption for -each thread. - -JTop is also a JConsole Plugin. See below for details. - -JTop Standalone GUI -=================== - -JTop first establishes a connection to a JMX agent in a remote -application with a JMX service URL: - service:jmx:rmi:///jndi/rmi://:/jmxrmi - -where is the hostname and is the port number -to which the JMX agent will be connected. - -To run the demo ---------------- -(1) Start the application with the JMX agent - here's an example of - how the Java2D is started - - java -Dcom.sun.management.jmxremote.port=1090 - -Dcom.sun.management.jmxremote.ssl=false - -Dcom.sun.management.jmxremote.authenticate=false - -jar /demo/jfc/Java2D/Java2Demo.jar - - This instruction uses the Sun's built-in support to enable a JMX agent - with a JMX service URL as described above. - You can programmatically start a JMX agent with the RMI connector - using javax.management.remote API. See the javadoc and examples for - javax.management.remote API for details. - -(2) Run JTop on a different machine: - - java -jar /demo/management/JTop/JTop.jar :1090 - - where is where the Java2Demo.jar runs in step (1). - -These instructions assume that this installation's version of the java -command is in your path. If it isn't, then you should either -specify the complete path to the java command or update your -PATH environment variable as described in the installation -instructions for the Java(TM) SDK. - -JTop JConsole Plugin -==================== - -JTop is a JConsole Plugin which adds a "JTop" tab to JConsole. - -To run JConsole with the JTop plugin ------------------------------------- - jconsole -pluginpath /demo/management/JTop/JTop.jar - - -To compile ----------- - javac -classpath /lib/jconsole.jar JTopPlugin.java - -com.sun.tools.jconsole API is in jconsole.jar which is needed -in the classpath for compilation. diff --git a/jdk/src/demo/share/management/MemoryMonitor/MemoryMonitor.java b/jdk/src/demo/share/management/MemoryMonitor/MemoryMonitor.java deleted file mode 100644 index 3d2769b917a..00000000000 --- a/jdk/src/demo/share/management/MemoryMonitor/MemoryMonitor.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - */ - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.BufferedImage; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.util.Date; -import javax.swing.*; -import javax.swing.border.EtchedBorder; -import javax.swing.border.TitledBorder; -import java.lang.management.*; -/** - * Demo code which plots the memory usage by all memory pools. - * The memory usage is sampled at some time interval using - * java.lang.management API. This demo code is modified based - * java2d MemoryMonitor demo. - */ -public class MemoryMonitor extends JPanel { - - private static final long serialVersionUID = -3463003810776195761L; - static JCheckBox dateStampCB = new JCheckBox("Output Date Stamp"); - public Surface surf; - JPanel controls; - boolean doControls; - JTextField tf; - // Get memory pools. - static java.util.List mpools = - ManagementFactory.getMemoryPoolMXBeans(); - // Total number of memory pools. - static int numPools = mpools.size(); - - public MemoryMonitor() { - setLayout(new BorderLayout()); - setBorder(new TitledBorder(new EtchedBorder(), "Memory Monitor")); - add(surf = new Surface()); - controls = new JPanel(); - controls.setPreferredSize(new Dimension(135,80)); - Font font = new Font("serif", Font.PLAIN, 10); - JLabel label = new JLabel("Sample Rate"); - label.setFont(font); - label.setForeground(Color.red); - controls.add(label); - tf = new JTextField("1000"); - tf.setPreferredSize(new Dimension(45,20)); - controls.add(tf); - controls.add(label = new JLabel("ms")); - label.setFont(font); - label.setForeground(Color.red); - controls.add(dateStampCB); - dateStampCB.setFont(font); - addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - removeAll(); - if ((doControls = !doControls)) { - surf.stop(); - add(controls); - } else { - try { - surf.sleepAmount = Long.parseLong(tf.getText().trim()); - } catch (Exception ex) {} - surf.start(); - add(surf); - } - validate(); - repaint(); - } - }); - } - - - public class Surface extends JPanel implements Runnable { - - public Thread thread; - public long sleepAmount = 1000; - public int usageHistCount = 20000; - private int w, h; - private BufferedImage bimg; - private Graphics2D big; - private Font font = new Font("Times New Roman", Font.PLAIN, 11); - private int columnInc; - private float usedMem[][]; - private float usedMemMax[]; // Used when max pool size is undefined - private int ptNum[]; - private int ascent, descent; - private Rectangle graphOutlineRect = new Rectangle(); - private Rectangle2D mfRect = new Rectangle2D.Float(); - private Rectangle2D muRect = new Rectangle2D.Float(); - private Line2D graphLine = new Line2D.Float(); - private Color graphColor = new Color(46, 139, 87); - private Color mfColor = new Color(0, 100, 0); - private String usedStr; - - - public Surface() { - setBackground(Color.black); - addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (thread == null) start(); else stop(); - } - }); - usedMem = new float[numPools][]; - usedMemMax = new float[numPools]; - for (int i = 0; i < numPools; i++) { - usedMemMax[i] = 1024f * 1024f ; - } - ptNum = new int[numPools]; - } - - @Override - public Dimension getMinimumSize() { - return getPreferredSize(); - } - - @Override - public Dimension getMaximumSize() { - return getPreferredSize(); - } - - @Override - public Dimension getPreferredSize() { - return new Dimension(135,80); - } - - - @Override - public void paint(Graphics g) { - - if (big == null) { - return; - } - - big.setBackground(getBackground()); - big.clearRect(0,0,w,h); - - - h = h / ((numPools + numPools%2) / 2); - w = w / 2; - - int k=0; // index of memory pool. - for (int i=0; i < 2;i++) { - for (int j=0; j < (numPools + numPools%2)/ 2; j++) { - plotMemoryUsage(w*i,h*j,w,h,k); - if (++k >= numPools) { - i = 3; - j = (numPools + numPools%2)/ 2; - break; - } - } - } - g.drawImage(bimg, 0, 0, this); - } - - public void plotMemoryUsage(int x1, int y1, int x2, int y2, int npool) { - - MemoryPoolMXBean mp = mpools.get(npool); - float usedMemory = mp.getUsage().getUsed(); - float totalMemory = mp.getUsage().getMax(); - if (totalMemory < 0) { // Max is undefined for this pool - if (usedMemory > usedMemMax[npool]) { - usedMemMax[npool] = usedMemory; - } - totalMemory = usedMemMax[npool]; - } - - // .. Draw allocated and used strings .. - big.setColor(Color.green); - - // Print Max memory allocated for this memory pool. - big.drawString(String.valueOf((int)totalMemory/1024) + "K Max ", x1+4.0f, (float) y1 + ascent+0.5f); - big.setColor(Color.yellow); - - // Print the memory pool name. - big.drawString(mp.getName(), x1+x2/2, (float) y1 + ascent+0.5f); - - // Print the memory used by this memory pool. - usedStr = String.valueOf((int)usedMemory/1024) - + "K used"; - big.setColor(Color.green); - big.drawString(usedStr, x1+4, y1+y2-descent); - - // Calculate remaining size - float ssH = ascent + descent; - float remainingHeight = y2 - (ssH*2) - 0.5f; - float blockHeight = remainingHeight/10; - float blockWidth = 20.0f; - float remainingWidth = x2 - blockWidth - 10; - - // .. Memory Free .. - big.setColor(mfColor); - int MemUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10); - int i = 0; - for ( ; i < MemUsage ; i++) { - mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight, - blockWidth, blockHeight-1); - big.fill(mfRect); - } - - // .. Memory Used .. - big.setColor(Color.green); - for ( ; i < 10; i++) { - muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight, - blockWidth, blockHeight-1); - big.fill(muRect); - } - - // .. Draw History Graph .. - if (remainingWidth <= 30) remainingWidth = (float)30; - if (remainingHeight <= ssH) remainingHeight = ssH; - big.setColor(graphColor); - int graphX = x1+30; - int graphY = y1 + (int) ssH; - int graphW = (int) remainingWidth; - int graphH = (int) remainingHeight; - - graphOutlineRect.setRect(graphX, graphY, graphW, graphH); - big.draw(graphOutlineRect); - - int graphRow = graphH/10; - - // .. Draw row .. - for (int j = graphY; j <= graphH+graphY; j += graphRow) { - graphLine.setLine(graphX,j,graphX+graphW,j); - big.draw(graphLine); - } - - // .. Draw animated column movement .. - int graphColumn = graphW/15; - - if (columnInc == 0) { - columnInc = graphColumn; - } - - for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) { - graphLine.setLine(j,graphY,j,graphY+graphH); - big.draw(graphLine); - } - - --columnInc; - - // Plot memory usage by this memory pool. - if (usedMem[npool] == null) { - usedMem[npool] = new float[usageHistCount]; - ptNum[npool] = 0; - } - - // save memory usage history. - usedMem[npool][ptNum[npool]] = usedMemory; - - big.setColor(Color.yellow); - - int w1; // width of memory usage history. - if (ptNum[npool] > graphW) { - w1 = graphW; - } else { - w1 = ptNum[npool]; - } - - - for (int j=graphX+graphW-w1, k=ptNum[npool]-w1; k < ptNum[npool]; - k++, j++) { - if (k != 0) { - if (usedMem[npool][k] != usedMem[npool][k-1]) { - int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k-1])/totalMemory)); - int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory)); - big.drawLine(j-1, h1, j, h2); - } else { - int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory)); - big.fillRect(j, h1, 1, 1); - } - } - } - if (ptNum[npool]+2 == usedMem[npool].length) { - // throw out oldest point - for (int j = 1;j < ptNum[npool]; j++) { - usedMem[npool][j-1] = usedMem[npool][j]; - } - --ptNum[npool]; - } else { - ptNum[npool]++; - } - } - - - public void start() { - thread = new Thread(this); - thread.setPriority(Thread.MIN_PRIORITY); - thread.setName("MemoryMonitor"); - thread.start(); - } - - - public synchronized void stop() { - thread = null; - notify(); - } - - @Override - public void run() { - - Thread me = Thread.currentThread(); - - while (thread == me && !isShowing() || getSize().width == 0) { - try { - Thread.sleep(500); - } catch (InterruptedException e) { return; } - } - - while (thread == me && isShowing()) { - Dimension d = getSize(); - if (d.width != w || d.height != h) { - w = d.width; - h = d.height; - bimg = (BufferedImage) createImage(w, h); - big = bimg.createGraphics(); - big.setFont(font); - FontMetrics fm = big.getFontMetrics(font); - ascent = fm.getAscent(); - descent = fm.getDescent(); - } - repaint(); - try { - Thread.sleep(sleepAmount); - } catch (InterruptedException e) { break; } - if (MemoryMonitor.dateStampCB.isSelected()) { - System.out.println(new Date().toString() + " " + usedStr); - } - } - thread = null; - } - } - - - // Test thread to consume memory - static class Memeater extends ClassLoader implements Runnable { - Object y[]; - public Memeater() {} - @Override - public void run() { - y = new Object[10000000]; - int k =0; - while(true) { - if (k == 5000000) k=0; - y[k++] = new Object(); - try { - Thread.sleep(20); - } catch (Exception x){} - - // to consume perm gen storage - try { - // the classes are small so we load 10 at a time - for (int i=0; i<10; i++) { - loadNext(); - } - } catch (ClassNotFoundException x) { - // ignore exception - } - - } - - } - - Class loadNext() throws ClassNotFoundException { - - // public class TestNNNNNN extends java.lang.Object{ - // public TestNNNNNN(); - // Code: - // 0: aload_0 - // 1: invokespecial #1; //Method java/lang/Object."":()V - // 4: return - // } - - int begin[] = { - 0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07, - 0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06, - 0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00, - 0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43, - 0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05, - 0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 }; - - int end [] = { - 0x01, 0x00, 0x10, - 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e, - 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, - 0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 }; - - - // TestNNNNNN - - String name = "Test" + Integer.toString(count++); - - byte value[]; - try { - value = name.substring(4).getBytes("UTF-8"); - } catch (java.io.UnsupportedEncodingException x) { - throw new Error(); - } - - // construct class file - - int len = begin.length + value.length + end.length; - byte b[] = new byte[len]; - int pos=0; - for (int i: begin) { - b[pos++] = (byte) i; - } - for (byte v: value) { - b[pos++] = v; - } - for (int e: end) { - b[pos++] = (byte) e; - } - - return defineClass(name, b, 0, b.length); - - } - static int count = 100000; - - } - - public static void main(String s[]) { - final MemoryMonitor demo = new MemoryMonitor(); - WindowListener l = new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) {System.exit(0);} - @Override - public void windowDeiconified(WindowEvent e) { demo.surf.start(); } - @Override - public void windowIconified(WindowEvent e) { demo.surf.stop(); } - }; - JFrame f = new JFrame("MemoryMonitor"); - f.addWindowListener(l); - f.getContentPane().add("Center", demo); - f.pack(); - f.setSize(new Dimension(400,500)); - f.setVisible(true); - demo.surf.start(); - Thread thr = new Thread(new Memeater()); - thr.start(); - } - -} diff --git a/jdk/src/demo/share/management/MemoryMonitor/README.txt b/jdk/src/demo/share/management/MemoryMonitor/README.txt deleted file mode 100644 index 5a421dbdc90..00000000000 --- a/jdk/src/demo/share/management/MemoryMonitor/README.txt +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Oracle nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -MemoryMonitor demonstrates the use of the java.lang.management API -in observing the memory usage of all memory pools consumed by -the application. - -This simple demo program queries the memory usage of each memory pool -and plots the memory usage history graph. - -To run the MemoryMonitor demo - - java -jar /demo/management/MemoryMonitor/MemoryMonitor.jar - -These instructions assume that this installation's version of the java -command is in your path. If it isn't, then you should either -specify the complete path to the java command or update your -PATH environment variable as described in the installation -instructions for the Java(TM) SDK. - diff --git a/jdk/src/demo/share/management/VerboseGC/PrintGCStat.java b/jdk/src/demo/share/management/VerboseGC/PrintGCStat.java deleted file mode 100644 index 565c8dc5c2c..00000000000 --- a/jdk/src/demo/share/management/VerboseGC/PrintGCStat.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - */ - -import static java.lang.management.ManagementFactory.*; -import java.lang.management.*; -import javax.management.*; -import java.io.*; -import java.util.*; - -/** - * Example of using the java.lang.management API to monitor - * the memory usage and garbage collection statistics. - * - * @author Mandy Chung - */ -public class PrintGCStat { - private RuntimeMXBean rmbean; - private MemoryMXBean mmbean; - private List pools; - private List gcmbeans; - - /** - * Constructs a PrintGCStat object to monitor a remote JVM. - */ - public PrintGCStat(MBeanServerConnection server) throws IOException { - // Create the platform mxbean proxies - this.rmbean = newPlatformMXBeanProxy(server, - RUNTIME_MXBEAN_NAME, - RuntimeMXBean.class); - this.mmbean = newPlatformMXBeanProxy(server, - MEMORY_MXBEAN_NAME, - MemoryMXBean.class); - ObjectName poolName = null; - ObjectName gcName = null; - try { - poolName = new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE+",*"); - gcName = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE+",*"); - } catch (MalformedObjectNameException e) { - // should not reach here - assert(false); - } - - Set mbeans = server.queryNames(poolName, null); - if (mbeans != null) { - pools = new ArrayList(); - for (ObjectName objName : mbeans) { - MemoryPoolMXBean p = - newPlatformMXBeanProxy(server, - objName.getCanonicalName(), - MemoryPoolMXBean.class); - pools.add(p); - } - } - - mbeans = server.queryNames(gcName, null); - if (mbeans != null) { - gcmbeans = new ArrayList(); - for (ObjectName objName : mbeans) { - GarbageCollectorMXBean gc = - newPlatformMXBeanProxy(server, - objName.getCanonicalName(), - GarbageCollectorMXBean.class); - gcmbeans.add(gc); - } - } - } - - /** - * Constructs a PrintGCStat object to monitor the local JVM. - */ - public PrintGCStat() { - // Obtain the platform mxbean instances for the running JVM. - this.rmbean = getRuntimeMXBean(); - this.mmbean = getMemoryMXBean(); - this.pools = getMemoryPoolMXBeans(); - this.gcmbeans = getGarbageCollectorMXBeans(); - } - - /** - * Prints the verbose GC log to System.out to list the memory usage - * of all memory pools as well as the GC statistics. - */ - public void printVerboseGc() { - System.out.println("Uptime: " + formatMillis(rmbean.getUptime())); - System.out.println("Heap usage: " + mmbean.getHeapMemoryUsage()); - System.out.println("Non-Heap memory usage: " + mmbean.getNonHeapMemoryUsage()); - for (GarbageCollectorMXBean gc : gcmbeans) { - System.out.print(" [" + gc.getName() + ": "); - System.out.print("Count=" + gc.getCollectionCount()); - System.out.print(" GCTime=" + formatMillis(gc.getCollectionTime())); - System.out.print("]"); - } - System.out.println(); - for (MemoryPoolMXBean p : pools) { - System.out.print(" [" + p.getName() + ":"); - MemoryUsage u = p.getUsage(); - System.out.print(" Used=" + formatBytes(u.getUsed())); - System.out.print(" Committed=" + formatBytes(u.getCommitted())); - System.out.println("]"); - } - } - - private String formatMillis(long ms) { - return String.format("%.4fsec", ms / (double) 1000); - } - private String formatBytes(long bytes) { - long kb = bytes; - if (bytes > 0) { - kb = bytes / 1024; - } - return kb + "K"; - } -} diff --git a/jdk/src/demo/share/management/VerboseGC/README.txt b/jdk/src/demo/share/management/VerboseGC/README.txt deleted file mode 100644 index f7a9011e422..00000000000 --- a/jdk/src/demo/share/management/VerboseGC/README.txt +++ /dev/null @@ -1,31 +0,0 @@ -VerboseGC demonstrates the use of the java.lang.management API to -print the garbage collection statistics and memory usage remotely -by connecting to a JMX agent with a JMX service URL: - service:jmx:rmi:///jndi/rmi://:/jmxrmi -where is the hostname and is the port number -to which the JMX agent will be connected. - -To run the VerboseGC demo - -(1) Start the application with the JMX agent - here's an example of - how the Java2D is started - - java -Dcom.sun.management.jmxremote.port=1090 - -Dcom.sun.management.jmxremote.ssl=false - -Dcom.sun.management.jmxremote.authenticate=false - -jar /demo/jfc/Java2D/Java2Demo.jar - - This instruction uses the Sun's built-in support to enable a JMX agent. - You can programmatically start a JMX agent with the RMI connector - using javax.management.remote API. See the javadoc and examples for - javax.management.remote API for details. - -(2) Run VerboseGC - - java -jar /demo/management/VerboseGC/VerboseGC.jar localhost:1090 - -These instructions assume that this installation's version of the java -command is in your path. If it isn't, then you should either -specify the complete path to the java command or update your -PATH environment variable as described in the installation -instructions for the Java(TM) SDK. diff --git a/jdk/src/demo/share/management/VerboseGC/VerboseGC.java b/jdk/src/demo/share/management/VerboseGC/VerboseGC.java deleted file mode 100644 index 57f78b8a53a..00000000000 --- a/jdk/src/demo/share/management/VerboseGC/VerboseGC.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - */ - -import javax.management.*; -import javax.management.remote.*; -import java.io.IOException; -import java.net.MalformedURLException; - -/** - * This VerboseGC class demonstrates the capability to get - * the garbage collection statistics and memory usage remotely. - */ -public class VerboseGC { - private MBeanServerConnection server; - private JMXConnector jmxc; - public VerboseGC(String hostname, int port) { - System.out.println("Connecting to " + hostname + ":" + port); - - // Create an RMI connector client and connect it to - // the RMI connector server - String urlPath = "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi"; - connect(urlPath); - } - - public void dump(long interval, long samples) { - try { - PrintGCStat pstat = new PrintGCStat(server); - for (int i = 0; i < samples; i++) { - pstat.printVerboseGc(); - try { - Thread.sleep(interval); - } catch (InterruptedException e) { - System.exit(1); - } - } - } catch (IOException e) { - System.err.println("\nCommunication error: " + e.getMessage()); - System.exit(1); - } - } - - /** - * Connect to a JMX agent of a given URL. - */ - private void connect(String urlPath) { - try { - JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath); - this.jmxc = JMXConnectorFactory.connect(url); - this.server = jmxc.getMBeanServerConnection(); - } catch (MalformedURLException e) { - // should not reach here - } catch (IOException e) { - System.err.println("\nCommunication error: " + e.getMessage()); - System.exit(1); - } - } - - public static void main(String[] args) { - if (args.length < 1) { - usage(); - } - - String hostname = ""; - int port = -1; - long interval = 5000; // default is 5 second interval - long mins = 5; - for (String arg: args) { - if (arg.startsWith("-")) { - if (arg.equals("-h") || - arg.equals("-help") || - arg.equals("-?")) { - usage(); - } else if (arg.startsWith("-interval=")) { - try { - interval = Integer.parseInt(arg.substring(10)) * 1000; - } catch (NumberFormatException ex) { - usage(); - } - } else if (arg.startsWith("-duration=")) { - try { - mins = Integer.parseInt(arg.substring(10)); - } catch (NumberFormatException ex) { - usage(); - } - } else { - // Unknown switch - System.err.println("Unrecognized option: " + arg); - usage(); - } - } else { - String[] arg2 = arg.split(":"); - if (arg2.length != 2) { - usage(); - } - hostname = arg2[0]; - try { - port = Integer.parseInt(arg2[1]); - } catch (NumberFormatException x) { - usage(); - } - if (port < 0) { - usage(); - } - } - } - - // get full thread dump and perform deadlock detection - VerboseGC vgc = new VerboseGC(hostname, port); - long samples = (mins * 60 * 1000) / interval; - vgc.dump(interval, samples); - - } - - private static void usage() { - System.out.print("Usage: java VerboseGC : "); - System.out.println(" [-interval=seconds] [-duration=minutes]"); - } -} diff --git a/jdk/src/demo/share/management/index.html b/jdk/src/demo/share/management/index.html deleted file mode 100644 index f9f35064221..00000000000 --- a/jdk/src/demo/share/management/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - java.lang.management Demonstration Code - - -

java.lang.management Demonstration Code

- -
    - -
  • -FullThreadDump -
    -Shows how to get thread dumps and look for deadlocks. -
  • - -
  • -VerboseGC -
    -Shows how you can find out about Garbage Collection in the VM. -
  • - -
  • -MemoryMonitor -
    -Shows how you can find out the memory usage in the VM. -
  • - -
  • -JTop -
    -Shows how you can find out the threads with top CPU usage. -
  • - - -
- - - -

Comments and Feedback

- -

-Comments regarding java.lang.management API or on any of these -demonstrations should be sent through -http://java.sun.com/mail/ - - - diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/README.txt b/jdk/src/demo/share/scripting/jconsole-plugin/README.txt deleted file mode 100644 index fc4bbf199aa..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/README.txt +++ /dev/null @@ -1,64 +0,0 @@ -What is this demo about? - -This is "script shell" plugin for jconsole - the monitoring and management -client tool shipped with JRE. This plugin adds "Script Shell" tab to jconsole. -This serves as a demo for jconsole plugin API (com.sun.tools.jconsole) as well -as a demo for scripting API (javax.script) for the Java platform. - -Script console is an interactive read-eval-print interface that can be used -used to execute advanced monitoring and management queries. By default, -JavaScript is used as the scripting language. The scripting language can be -changed using the system property com.sun.demo.jconsole.console.language. To -use other scripting languages, you need to specify the corresponding engine -jar file in pluginpath along with this plugin's jar file. - -The following 3 global variables are exposed to the script engine: - - window javax.swing.JPanel - engine javax.script.ScriptEngine - plugin com.sun.tools.jconsole.JConsolePlugin - -If you use JavaScript, there are many useful global functions defined in -./src/resources/jconsole.js. This is built into the script plugin jar file. -In addition, you can add other global functions and global variables by -defining those in ~/jconsole.js (or jconsole. where is the file -extension for your scripting language of choice under your home directory). - -How do I compile script console plugin? - -You can use the Java based build tool "ant" (http://ant.apache.org) to build -this plugin. To build using ant, please use the following command in the -current directory: - - ant - -How do I use script console plugin? - -To start jconsole with this plugin, please use the following command - - jconsole -pluginpath jconsole-plugin.jar - -How do I load my own script files in script console? - -If you use JavaScript (the default), then there is a global function called -"load" to load any script file from your file system. In script console -prompt, enter the following: - - load(); - -where is the path of your script file to load. If you don't -specify the file path, then the load function shows file dialog box to choose -the script file to load. - -How do I get help on script global functions? - -If you use JavaScript (the default), then there is a global function called -"help" that prints one-line help messages on global functions. In script -console prompt, enter the following: - - help(); - -Where are the sample JavaScript files? - -./src/scripts directory contains JavaScript files that can be loaded into -script console. diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/build.xml b/jdk/src/demo/share/scripting/jconsole-plugin/build.xml deleted file mode 100644 index aecefdcad5d..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/build.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/META-INF/services/com.sun.tools.jconsole.JConsolePlugin b/jdk/src/demo/share/scripting/jconsole-plugin/src/META-INF/services/com.sun.tools.jconsole.JConsolePlugin deleted file mode 100644 index 9e05f3c164f..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/META-INF/services/com.sun.tools.jconsole.JConsolePlugin +++ /dev/null @@ -1 +0,0 @@ -com.sun.demo.scripting.jconsole.ScriptJConsolePlugin diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/EditableAtEndDocument.java b/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/EditableAtEndDocument.java deleted file mode 100644 index 2552f5ea5a7..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/EditableAtEndDocument.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.demo.scripting.jconsole; - -import javax.swing.text.*; - -/** This class implements a special type of document in which edits - * can only be performed at the end, from "mark" to the end of the - * document. This is used in ScriptShellPanel class as document for editor. - */ -public class EditableAtEndDocument extends PlainDocument { - - private static final long serialVersionUID = 5358116444851502167L; - private int mark; - - @Override - public void insertString(int offset, String text, AttributeSet a) - throws BadLocationException { - int len = getLength(); - super.insertString(len, text, a); - } - - @Override - public void remove(int offs, int len) throws BadLocationException { - int start = offs; - int end = offs + len; - - int markStart = mark; - int markEnd = getLength(); - - if ((end < markStart) || (start > markEnd)) { - // no overlap - return; - } - - // Determine interval intersection - int cutStart = Math.max(start, markStart); - int cutEnd = Math.min(end, markEnd); - super.remove(cutStart, cutEnd - cutStart); - } - - public void setMark() { - mark = getLength(); - } - - public String getMarkedText() throws BadLocationException { - return getText(mark, getLength() - mark); - } - - /** Used to reset the contents of this document */ - public void clear() { - try { - super.remove(0, getLength()); - setMark(); - } catch (BadLocationException e) { - } - } -} diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptJConsolePlugin.java b/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptJConsolePlugin.java deleted file mode 100644 index c955a968dcf..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptJConsolePlugin.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.demo.scripting.jconsole; - -import com.sun.tools.jconsole.*; -import java.io.*; -import java.util.concurrent.CountDownLatch; -import javax.script.*; -import javax.swing.*; -import java.util.*; - -/** - * This is script console plugin. This class uses javax.script API to create - * interactive read-eval-print script shell within the jconsole GUI. - */ -public class ScriptJConsolePlugin extends JConsolePlugin - implements ScriptShellPanel.CommandProcessor { - // Panel for our tab - private volatile ScriptShellPanel window; - // Tabs that we add to jconsole GUI - private Map tabs; - - // Script engine that evaluates scripts - private volatile ScriptEngine engine; - - // script engine initialization occurs in background. - // This latch is used to coorrdinate engine init and eval. - private CountDownLatch engineReady = new CountDownLatch(1); - - // File extension used for scripts of chosen language. - // For eg. ".js" for JavaScript, ".bsh" for BeanShell. - private String extension; - - // Prompt to print in the read-eval-print loop. This is - // derived from the script file extension. - private volatile String prompt; - - /** - * Constructor to create this plugin - */ - public ScriptJConsolePlugin() { - } - - @Override public Map getTabs() { - // create ScriptEngine - createScriptEngine(); - - // create panel for tab - window = new ScriptShellPanel(this); - - // add tab to tabs map - tabs = new HashMap(); - tabs.put("Script Shell", window); - - new Thread(new Runnable() { - @Override - public void run() { - // initialize the script engine - initScriptEngine(); - engineReady.countDown(); - } - }).start(); - return tabs; - } - - @Override public SwingWorker newSwingWorker() { - return null; - } - - @Override public void dispose() { - window.dispose(); - } - - @Override - public String getPrompt() { - return prompt; - } - - @Override - public String executeCommand(String cmd) { - String res; - try { - engineReady.await(); - Object tmp = engine.eval(cmd); - res = (tmp == null)? null : tmp.toString(); - } catch (InterruptedException ie) { - res = ie.getMessage(); - } catch (ScriptException se) { - res = se.getMessage(); - } - return res; - } - - //-- Internals only below this point - private void createScriptEngine() { - ScriptEngineManager manager = new ScriptEngineManager(); - String language = getScriptLanguage(); - engine = manager.getEngineByName(language); - if (engine == null) { - throw new RuntimeException("cannot load " + language + " engine"); - } - extension = engine.getFactory().getExtensions().get(0); - prompt = extension + ">"; - engine.setBindings(createBindings(), ScriptContext.ENGINE_SCOPE); - } - - // Name of the System property used to select scripting language - private static final String LANGUAGE_KEY = "com.sun.demo.jconsole.console.language"; - - private String getScriptLanguage() { - // check whether explicit System property is set - String lang = System.getProperty(LANGUAGE_KEY); - if (lang == null) { - // default is JavaScript - lang = "JavaScript"; - } - return lang; - } - - // create Bindings that is backed by a synchronized HashMap - private Bindings createBindings() { - Map map = - Collections.synchronizedMap(new HashMap()); - return new SimpleBindings(map); - } - - // create and initialize script engine - private void initScriptEngine() { - // set pre-defined global variables - setGlobals(); - // load pre-defined initialization file - loadInitFile(); - // load current user's initialization file - loadUserInitFile(); - } - - // set pre-defined global variables for script - private void setGlobals() { - engine.put("engine", engine); - engine.put("window", window); - engine.put("plugin", this); - } - - // load initial script file (jconsole.) - private void loadInitFile() { - String oldFilename = (String) engine.get(ScriptEngine.FILENAME); - engine.put(ScriptEngine.FILENAME, ""); - try { - Class myClass = this.getClass(); - InputStream stream = myClass.getResourceAsStream("/resources/jconsole." + - extension); - if (stream != null) { - engine.eval(new InputStreamReader(new BufferedInputStream(stream))); - } - } catch (Exception exp) { - exp.printStackTrace(); - // FIXME: What else I can do here?? - } finally { - engine.put(ScriptEngine.FILENAME, oldFilename); - } - } - - // load user's initial script file (~/jconsole.) - private void loadUserInitFile() { - String oldFilename = (String) engine.get(ScriptEngine.FILENAME); - String home = System.getProperty("user.home"); - if (home == null) { - // no user.home?? should not happen?? - return; - } - String fileName = home + File.separator + "jconsole." + extension; - if (! (new File(fileName).exists())) { - // user does not have ~/jconsole. - return; - } - engine.put(ScriptEngine.FILENAME, fileName); - try { - engine.eval(new FileReader(fileName)); - } catch (Exception exp) { - exp.printStackTrace(); - // FIXME: What else I can do here?? - } finally { - engine.put(ScriptEngine.FILENAME, oldFilename); - } - } -} diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java b/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java deleted file mode 100644 index c7e4dee51bc..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.demo.scripting.jconsole; - -import java.awt.*; -import java.awt.event.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.text.*; - - -/** - * A JPanel subclass containing a scrollable text area displaying the - * jconsole's script console. - */ - -public class ScriptShellPanel extends JPanel { - - private static final long serialVersionUID = 4116273141148726319L; - - // interface to evaluate script command and script prompt - interface CommandProcessor { - // execute given String as script and return the result - public String executeCommand(String cmd); - // get prompt used for interactive read-eval-loop - public String getPrompt(); - } - - // my script command processor - private CommandProcessor commandProcessor; - // editor component for command editing - private JTextComponent editor; - - private final ExecutorService commandExecutor = - Executors.newSingleThreadExecutor(); - - // document management - private boolean updating; - - public ScriptShellPanel(CommandProcessor cmdProc) { - setLayout(new BorderLayout()); - this.commandProcessor = cmdProc; - this.editor = new JTextArea(); - editor.setDocument(new EditableAtEndDocument()); - JScrollPane scroller = new JScrollPane(); - scroller.getViewport().add(editor); - add(scroller, BorderLayout.CENTER); - - editor.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void changedUpdate(DocumentEvent e) { - } - - @Override - public void insertUpdate(DocumentEvent e) { - if (updating) return; - beginUpdate(); - editor.setCaretPosition(editor.getDocument().getLength()); - if (insertContains(e, '\n')) { - String cmd = getMarkedText(); - // Handle multi-line input - if ((cmd.length() == 0) || - (cmd.charAt(cmd.length() - 1) != '\\')) { - // Trim "\\n" combinations - final String cmd1 = trimContinuations(cmd); - commandExecutor.execute(new Runnable() { - @Override - public void run() { - final String result = executeCommand(cmd1); - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if (result != null) { - print(result + "\n"); - } - printPrompt(); - setMark(); - endUpdate(); - } - }); - } - }); - } else { - endUpdate(); - } - } else { - endUpdate(); - } - } - - @Override - public void removeUpdate(DocumentEvent e) { - } - }); - - // This is a bit of a hack but is probably better than relying on - // the JEditorPane to update the caret's position precisely the - // size of the insertion - editor.addCaretListener(new CaretListener() { - @Override - public void caretUpdate(CaretEvent e) { - int len = editor.getDocument().getLength(); - if (e.getDot() > len) { - editor.setCaretPosition(len); - } - } - }); - - Box hbox = Box.createHorizontalBox(); - hbox.add(Box.createGlue()); - JButton button = new JButton("Clear"); // FIXME: i18n? - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - clear(); - } - }); - hbox.add(button); - hbox.add(Box.createGlue()); - add(hbox, BorderLayout.SOUTH); - - clear(); - } - - public void dispose() { - commandExecutor.shutdown(); - } - - @Override - public void requestFocus() { - editor.requestFocus(); - } - - public void clear() { - clear(true); - } - - public void clear(boolean prompt) { - EditableAtEndDocument d = (EditableAtEndDocument) editor.getDocument(); - d.clear(); - if (prompt) printPrompt(); - setMark(); - editor.requestFocus(); - } - - public void setMark() { - ((EditableAtEndDocument) editor.getDocument()).setMark(); - } - - public String getMarkedText() { - try { - String s = ((EditableAtEndDocument) editor.getDocument()).getMarkedText(); - int i = s.length(); - while ((i > 0) && (s.charAt(i - 1) == '\n')) { - i--; - } - return s.substring(0, i); - } catch (BadLocationException e) { - e.printStackTrace(); - return null; - } - } - - public void print(String s) { - Document d = editor.getDocument(); - try { - d.insertString(d.getLength(), s, null); - } catch (BadLocationException e) { - e.printStackTrace(); - } - } - - - // - // Internals only below this point - // - - private String executeCommand(String cmd) { - return commandProcessor.executeCommand(cmd); - } - - private String getPrompt() { - return commandProcessor.getPrompt(); - } - - private void beginUpdate() { - editor.setEditable(false); - updating = true; - } - - private void endUpdate() { - editor.setEditable(true); - updating = false; - } - - private void printPrompt() { - print(getPrompt()); - } - - private boolean insertContains(DocumentEvent e, char c) { - String s = null; - try { - s = editor.getText(e.getOffset(), e.getLength()); - for (int i = 0; i < e.getLength(); i++) { - if (s.charAt(i) == c) { - return true; - } - } - } catch (BadLocationException ex) { - ex.printStackTrace(); - } - return false; - } - - private String trimContinuations(String text) { - int i; - while ((i = text.indexOf("\\\n")) >= 0) { - text = text.substring(0, i) + text.substring(i+1, text.length()); - } - return text; - } -} diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/resources/jconsole.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/resources/jconsole.js deleted file mode 100644 index f39dea30069..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/resources/jconsole.js +++ /dev/null @@ -1,891 +0,0 @@ -/* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * -Redistribution of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of Oracle nor the names of contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") - * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE - * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, - * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed, licensed or intended - * for use in the design, construction, operation or maintenance of any - * nuclear facility. - */ - -// This function depends on the pre-defined variable -// "plugin" of type com.sun.tools.jconsole.JConsolePlugin - -function jcontext() { - return plugin.getContext(); -} -jcontext.docString = "returns JConsoleContext for the current jconsole plugin"; - -function mbeanConnection() { - return jcontext().getMBeanServerConnection(); -} -mbeanConnection.docString = "returns current MBeanServer connection"; - -// check if there is a build in sync function, define one if missing -if (typeof sync === "undefined") { - var sync = function(func, obj) { - if (arguments.length < 1 || arguments.length > 2 ) { - throw "sync(function [,object]) parameter count mismatch"; - } - - var syncobj = (arguments.length == 2 ? obj : this); - - if (!syncobj._syncLock) { - syncobj._syncLock = new Lock(); - } - - return function() { - syncobj._syncLock.lock(); - try { - func.apply(null, arguments); - } finally { - syncobj._syncLock.unlock(); - } - }; - }; - sync.docString = "synchronize a function, optionally on an object"; -} - -/** - * Prints one liner help message for each function exposed here - * Note that this function depends on docString meta-data for - * each function - */ -function help() { - var i; - for (i in this) { - var func = this[i]; - if (typeof(func) == "function" && - ("docString" in func)) { - echo(i + " - " + func["docString"]); - } - } -} -help.docString = "prints help message for global functions"; - -function connectionState() { - return jcontext().connectionState; -} -connectionState.docString = "return connection state of the current jcontext"; - -/** - * Returns a platform MXBean proxy for given MXBean name and interface class - */ -function newPlatformMXBeanProxy(name, intf) { - var factory = java.lang.management.ManagementFactory; - return factory.newPlatformMXBeanProxy(mbeanConnection(), name, intf); -} -newPlatformMXBeanProxy.docString = "returns a proxy for a platform MXBean"; - -/** - * Wraps a string to ObjectName if needed. - */ -function objectName(objName) { - var ObjectName = Packages.javax.management.ObjectName; - if (objName instanceof ObjectName) { - return objName; - } else { - return new ObjectName(objName); - } -} -objectName.docString = "creates JMX ObjectName for a given String"; - - -/** - * Creates a new (M&M) Attribute object - * - * @param name name of the attribute - * @param value value of the attribute - */ -function attribute(name, value) { - var Attribute = Packages.javax.management.Attribute; - return new Attribute(name, value); -} -attribute.docString = "returns a new JMX Attribute using name and value given"; - -/** - * Returns MBeanInfo for given ObjectName. Strings are accepted. - */ -function mbeanInfo(objName) { - objName = objectName(objName); - return mbeanConnection().getMBeanInfo(objName); -} -mbeanInfo.docString = "returns MBeanInfo of a given ObjectName"; - -/** - * Returns ObjectInstance for a given ObjectName. - */ -function objectInstance(objName) { - objName = objectName(objName); - return mbeanConnection().objectInstance(objectName); -} -objectInstance.docString = "returns ObjectInstance for a given ObjectName"; - -/** - * Queries with given ObjectName and QueryExp. - * QueryExp may be null. - * - * @return set of ObjectNames. - */ -function queryNames(objName, query) { - objName = objectName(objName); - if (query == undefined) query = null; - return mbeanConnection().queryNames(objName, query); -} -queryNames.docString = "returns QueryNames using given ObjectName and optional query"; - - -/** - * Queries with given ObjectName and QueryExp. - * QueryExp may be null. - * - * @return set of ObjectInstances. - */ -function queryMBeans(objName, query) { - objName = objectName(objName); - if (query == undefined) query = null; - return mbeanConnection().queryMBeans(objName, query); -} -queryMBeans.docString = "return MBeans using given ObjectName and optional query"; - -// wraps a script array as java.lang.Object[] -function objectArray(array) { - return Java.to(array, "java.lang.Object[]"); -} - -// wraps a script (string) array as java.lang.String[] -function stringArray(array) { - return Java.to(array, "java.lang.String[]"); -} - -// script array to Java List -function toAttrList(array) { - var AttributeList = Packages.javax.management.AttributeList; - if (array instanceof AttributeList) { - return array; - } - var list = new AttributeList(array.length); - for (var index = 0; index < array.length; index++) { - list.add(array[index]); - } - return list; -} - -// Java Collection (Iterable) to script array -function toArray(collection) { - if (collection instanceof Array) { - return collection; - } - var itr = collection.iterator(); - var array = new Array(); - while (itr.hasNext()) { - array[array.length] = itr.next(); - } - return array; -} - -// gets MBean attributes -function getMBeanAttributes(objName, attributeNames) { - objName = objectName(objName); - return mbeanConnection().getAttributes(objName,stringArray(attributeNames)); -} -getMBeanAttributes.docString = "returns specified Attributes of given ObjectName"; - -// gets MBean attribute -function getMBeanAttribute(objName, attrName) { - objName = objectName(objName); - return mbeanConnection().getAttribute(objName, attrName); -} -getMBeanAttribute.docString = "returns a single Attribute of given ObjectName"; - - -// sets MBean attributes -function setMBeanAttributes(objName, attrList) { - objName = objectName(objName); - attrList = toAttrList(attrList); - return mbeanConnection().setAttributes(objName, attrList); -} -setMBeanAttributes.docString = "sets specified Attributes of given ObjectName"; - -// sets MBean attribute -function setMBeanAttribute(objName, attrName, attrValue) { - var Attribute = Packages.javax.management.Attribute; - objName = objectName(objName); - mbeanConnection().setAttribute(objName, new Attribute(attrName, attrValue)); -} -setMBeanAttribute.docString = "sets a single Attribute of given ObjectName"; - - -// invokes an operation on given MBean -function invokeMBean(objName, operation, params, signature) { - objName = objectName(objName); - params = objectArray(params); - signature = stringArray(signature); - return mbeanConnection().invoke(objName, operation, params, signature); -} -invokeMBean.docString = "invokes MBean operation on given ObjectName"; - -/** - * Wraps a MBean specified by ObjectName as a convenient - * script object -- so that setting/getting MBean attributes - * and invoking MBean method can be done with natural syntax. - * - * @param objName ObjectName of the MBean - * @param async asynchornous mode [optional, default is false] - * @return script wrapper for MBean - * - * With async mode, all field, operation access is async. Results - * will be of type FutureTask. When you need value, call 'get' on it. - */ -function mbean(objName, async) { - var index; - - objName = objectName(objName); - var info = mbeanInfo(objName); - var attrs = info.attributes; - var attrMap = new Object; - for (index in attrs) { - attrMap[attrs[index].name] = attrs[index]; - } - var opers = info.operations; - var operMap = new Object; - for (index in opers) { - operMap[opers[index].name] = opers[index]; - } - - function isAttribute(name) { - return name in attrMap; - } - - function isOperation(name) { - return name in operMap; - } - - return new JSAdapter() { - __has__: function (name) { - return isAttribute(name) || isOperation(name); - }, - __get__: function (name) { - if (isAttribute(name)) { - if (async) { - return getMBeanAttribute.future(objName, name); - } else { - return getMBeanAttribute(objName, name); - } - } else { - return undefined; - } - }, - __call__: function(name) { - if (isOperation(name)) { - var oper = operMap[name]; - - var params = []; - for (var j = 1; j < arguments.length; j++) { - params[j-1]= arguments[j]; - } - - var sigs = oper.signature; - - var sigNames = new Array(sigs.length); - for (var index in sigs) { - sigNames[index] = sigs[index].getType(); - } - - if (async) { - return invokeMBean.future(objName, name, params, sigNames); - } else { - return invokeMBean(objName, name, params, sigNames); - } - } else { - return undefined; - } - }, - __put__: function (name, value) { - if (isAttribute(name)) { - if (async) { - setMBeanAttribute.future(objName, name, value); - } else { - setMBeanAttribute(objName, name, value); - } - } else { - return undefined; - } - } - }; -} -mbean.docString = "returns a conveninent script wrapper for a MBean of given ObjectName"; - -/** - * load and evaluate script file. If no script file is - * specified, file dialog is shown to choose the script. - * - * @param file script file name [optional] - * @return value returned from evaluating script - */ -function load(file) { - if (file == undefined || file == null) { - // file not specified, show file dialog to choose - file = fileDialog(); - } - if (file == null) return; - - var reader = new java.io.FileReader(file); - var oldFilename = engine.get(engine.FILENAME); - engine.put(engine.FILENAME, file); - try { - engine.eval(reader); - } finally { - engine.put(engine.FILENAME, oldFilename); - } - reader.close(); -} -load.docString = "loads a script file and evaluates it"; - -/** - * Concurrency utilities for JavaScript. These are based on - * java.lang and java.util.concurrent API. The following functions - * provide a simpler API for scripts. Instead of directly using java.lang - * and java.util.concurrent classes, scripts can use functions and - * objects exported from here. - */ - -/** - * Wrapper for java.lang.Object.wait - * - * can be called only within a sync method - */ -function wait(object) { - var objClazz = java.lang.Class.forName('java.lang.Object'); - var waitMethod = objClazz.getMethod('wait', null); - waitMethod.invoke(object, null); -} -wait.docString = "convenient wrapper for java.lang.Object.wait method"; - - -/** - * Wrapper for java.lang.Object.notify - * - * can be called only within a sync method - */ -function notify(object) { - var objClazz = java.lang.Class.forName('java.lang.Object'); - var notifyMethod = objClazz.getMethod('notify', null); - notifyMethod.invoke(object, null); -} -notify.docString = "convenient wrapper for java.lang.Object.notify method"; - - -/** - * Wrapper for java.lang.Object.notifyAll - * - * can be called only within a sync method - */ -function notifyAll(object) { - var objClazz = java.lang.Class.forName('java.lang.Object'); - var notifyAllMethod = objClazz.getMethod('notifyAll', null); - notifyAllMethod.invoke(object, null); -} -notifyAll.docString = "convenient wrapper for java.lang.Object.notifyAll method"; - - -/** - * Creates a java.lang.Runnable from a given script - * function. - */ -Function.prototype.runnable = function() { - var args = arguments; - var func = this; - return new java.lang.Runnable() { - run: function() { - func.apply(null, args); - } - } -} - -/** - * Executes the function on a new Java Thread. - */ -Function.prototype.thread = function() { - var t = new java.lang.Thread(this.runnable.apply(this, arguments)); - t.start(); - return t; -} - -/** - * Executes the function on a new Java daemon Thread. - */ -Function.prototype.daemon = function() { - var t = new java.lang.Thread(this.runnable.apply(this, arguments)); - t.setDaemon(true); - t.start(); - return t; -} - -/** - * Creates a java.util.concurrent.Callable from a given script - * function. - */ -Function.prototype.callable = function() { - var args = arguments; - var func = this; - return new java.util.concurrent.Callable() { - call: function() { return func.apply(null, args); } - } -} - -/** - * Registers the script function so that it will be called exit. - */ -Function.prototype.atexit = function () { - var args = arguments; - java.lang.Runtime.getRuntime().addShutdownHook( - new java.lang.Thread(this.runnable.apply(this, args))); -} - -/** - * Executes the function asynchronously. - * - * @return a java.util.concurrent.FutureTask - */ -Function.prototype.future = (function() { - // default executor for future - var juc = java.util.concurrent; - var theExecutor = juc.Executors.newSingleThreadExecutor(); - // clean-up the default executor at exit - (function() { theExecutor.shutdown(); }).atexit(); - return function() { - return theExecutor.submit(this.callable.apply(this, arguments)); - } -})(); - -// shortcut for j.u.c lock classes -var Lock = java.util.concurrent.locks.ReentrantLock; -var RWLock = java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * Executes a function after acquiring given lock. On return, - * (normal or exceptional), lock is released. - * - * @param lock lock that is locked and unlocked - */ -Function.prototype.sync = function (lock) { - if (arguments.length == 0) { - throw "lock is missing"; - } - var res = new Array(arguments.length - 1); - for (var i = 0; i < res.length; i++) { - res[i] = arguments[i + 1]; - } - lock.lock(); - try { - this.apply(null, res); - } finally { - lock.unlock(); - } -}; - -/** - * Causes current thread to sleep for specified - * number of milliseconds - * - * @param interval in milliseconds - */ -function sleep(interval) { - java.lang.Thread.sleep(interval); -} -sleep.docString = "wrapper for java.lang.Thread.sleep method"; - -/** - * Schedules a task to be executed once in N milliseconds specified. - * - * @param callback function or expression to evaluate - * @param interval in milliseconds to sleep - * @return timeout ID (which is nothing but Thread instance) - */ -function setTimeout(callback, interval) { - if (! (callback instanceof Function)) { - callback = new Function(callback); - } - - // start a new thread that sleeps given time - // and calls callback in an infinite loop - return (function() { - try { - sleep(interval); - } catch (x) { } - callback(); - }).daemon(); -} -setTimeout.docString = "calls given callback once after specified interval"; - -/** - * Cancels a timeout set earlier. - * @param tid timeout ID returned from setTimeout - */ -function clearTimeout(tid) { - // we just interrupt the timer thread - tid.interrupt(); -} -clearTimeout.docString = "interrupt a setTimeout timer"; - -/** - * Schedules a task to be executed once in - * every N milliseconds specified. - * - * @param callback function or expression to evaluate - * @param interval in milliseconds to sleep - * @return timeout ID (which is nothing but Thread instance) - */ -function setInterval(callback, interval) { - if (! (callback instanceof Function)) { - callback = new Function(callback); - } - - // start a new thread that sleeps given time - // and calls callback in an infinite loop - return (function() { - while (true) { - try { - sleep(interval); - } catch (x) { - break; - } - callback(); - } - }).daemon(); -} -setInterval.docString = "calls given callback every specified interval"; - -/** - * Cancels a timeout set earlier. - * @param tid timeout ID returned from setTimeout - */ -function clearInterval(tid) { - // we just interrupt the timer thread - tid.interrupt(); -} -clearInterval.docString = "interrupt a setInterval timer"; - -/** - * Simple access to thread local storage. - * - * Script sample: - * - * __thread.x = 44; - * function f() { - * __thread.x = 'hello'; - * print(__thread.x); - * } - * f.thread(); // prints 'hello' - * print(__thread.x); // prints 44 in main thread - */ -var __thread = (function () { - var map = new Object(); - return new JSAdapter() { - __has__: function(name) { - return map[name] != undefined; - }, - __get__: function(name) { - if (map[name] != undefined) { - return map[name].get(); - } else { - return undefined; - } - }, - __put__: sync(function(name, value) { - if (map[name] == undefined) { - var tmp = new java.lang.ThreadLocal(); - tmp.set(value); - map[name] = tmp; - } else { - map[name].set(value); - } - }), - __delete__: function(name) { - if (map[name] != undefined) { - map[name].set(null); - } - } - } -})(); - -// user interface utilities - -/** - * Swing invokeLater - invokes given function in AWT event thread - */ -Function.prototype.invokeLater = function() { - var SwingUtilities = Packages.javax.swing.SwingUtilities; - SwingUtilities.invokeLater(this.runnable.apply(this, arguments)); -} - -/** - * Swing invokeAndWait - invokes given function in AWT event thread - * and waits for it's completion - */ -Function.prototype.invokeAndWait = function() { - var SwingUtilities = Packages.javax.swing.SwingUtilities; - SwingUtilities.invokeAndWait(this.runnable.apply(this, arguments)); -} - -/** - * Am I running in AWT event dispatcher thread? - */ -function isEventThread() { - var SwingUtilities = Packages.javax.swing.SwingUtilities; - return SwingUtilities.isEventDispatchThread(); -} -isEventThread.docString = "returns whether the current thread is GUI thread"; - -/** - * Opens a file dialog box - * - * @param curDir current directory [optional] - * @return absolute path if file selected or else null - */ -function fileDialog(curDir) { - var result; - function _fileDialog() { - if (curDir == undefined) curDir = undefined; - var JFileChooser = Packages.javax.swing.JFileChooser; - var dialog = new JFileChooser(curDir); - var res = dialog.showOpenDialog(null); - if (res == JFileChooser.APPROVE_OPTION) { - result = dialog.getSelectedFile().getAbsolutePath(); - } else { - result = null; - } - } - - if (isEventThread()) { - _fileDialog(); - } else { - _fileDialog.invokeAndWait(); - } - return result; -} -fileDialog.docString = "show a FileOpen dialog box"; - -/** - * Shows a message box - * - * @param msg message to be shown - * @param title title of message box [optional] - * @param msgType type of message box [constants in JOptionPane] - */ -function msgBox(msg, title, msgType) { - - function _msgBox() { - var JOptionPane = Packages.javax.swing.JOptionPane; - if (msg === undefined) msg = "undefined"; - if (msg === null) msg = "null"; - if (title == undefined) title = msg; - if (msgType == undefined) msgType = JOptionPane.INFORMATION_MESSAGE; - JOptionPane.showMessageDialog(window, msg, title, msgType); - } - if (isEventThread()) { - _msgBox(); - } else { - _msgBox.invokeAndWait(); - } -} -msgBox.docString = "shows MessageBox to the user"; - -/** - * Shows an information alert box - * - * @param msg message to be shown - * @param title title of message box [optional] - */ -function alert(msg, title) { - var JOptionPane = Packages.javax.swing.JOptionPane; - msgBox(msg, title, JOptionPane.INFORMATION_MESSAGE); -} -alert.docString = "shows an alert message box to the user"; - -/** - * Shows an error alert box - * - * @param msg message to be shown - * @param title title of message box [optional] - */ -function error(msg, title) { - var JOptionPane = Packages.javax.swing.JOptionPane; - msgBox(msg, title, JOptionPane.ERROR_MESSAGE); -} -error.docString = "shows an error message box to the user"; - - -/** - * Shows a warning alert box - * - * @param msg message to be shown - * @param title title of message box [optional] - */ -function warn(msg, title) { - var JOptionPane = Packages.javax.swing.JOptionPane; - msgBox(msg, title, JOptionPane.WARNING_MESSAGE); -} -warn.docString = "shows a warning message box to the user"; - - -/** - * Shows a prompt dialog box - * - * @param question question to be asked - * @param answer default answer suggested [optional] - * @return answer given by user - */ -function prompt(question, answer) { - var result; - function _prompt() { - var JOptionPane = Packages.javax.swing.JOptionPane; - if (answer == undefined) answer = ""; - result = JOptionPane.showInputDialog(window, question, answer); - } - if (isEventThread()) { - _prompt(); - } else { - _prompt.invokeAndWait(); - } - return result; -} -prompt.docString = "shows a prompt box to the user and returns the answer"; - -/** - * Shows a confirmation dialog box - * - * @param msg message to be shown - * @param title title of message box [optional] - * @return boolean (yes->true, no->false) - */ -function confirm(msg, title) { - var result; - var JOptionPane = Packages.javax.swing.JOptionPane; - function _confirm() { - if (title == undefined) title = msg; - var optionType = JOptionPane.YES_NO_OPTION; - result = JOptionPane.showConfirmDialog(null, msg, title, optionType); - } - if (isEventThread()) { - _confirm(); - } else { - _confirm.invokeAndWait(); - } - return result == JOptionPane.YES_OPTION; -} -confirm.docString = "shows a confirmation message box to the user"; - -/** - * Echoes zero or more arguments supplied to screen. - * This is print equivalent for GUI. - * - * @param zero or more items to echo. - */ -function echo() { - var args = arguments; - (function() { - var len = args.length; - for (var i = 0; i < len; i++) { - window.print(args[i]); - window.print(" "); - } - window.print("\n"); - }).invokeLater(); -} -echo.docString = "echoes arguments to interactive console screen"; - - -/** - * Clear the screen - */ -function clear() { - (function() { window.clear(false); }).invokeLater(); -} -clear.docString = "clears interactive console screen"; - - -// synonym for clear -var cls = clear; - - -/** - * Exit the process after confirmation from user - * - * @param exitCode return code to OS [optional] - */ -function exit(exitCode) { - if (exitCode == undefined) exitCode = 0; - if (confirm("Do you really want to exit?")) { - java.lang.System.exit(exitCode); - } -} -exit.docString = "exits jconsole"; - -// synonym to exit -var quit = exit; - diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/heapdump.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/heapdump.js deleted file mode 100644 index 7cb53225a11..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/heapdump.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * This file defines heapdump function to heap dump - * in binary format. User can call this function - * based on events. For example, a timer thread can - * keep checking heap threshold and depending on - * specific expected threshold value, it can call - * heapdump to dump the keep. File name can contain - * timestamp so that multiple heapdumps can be generated - * for the same process. - */ - -/** - * Function to dump heap in binary format. - * - * @param file heap dump file name [optional] - */ -function heapdump(file) { - // no file specified, show file open dialog - if (file == undefined) { - file = fileDialog(); - // check whether user cancelled the dialog - if (file == null) return; - } - - /* - * Get HotSpotDiagnostic MBean and wrap it as convenient - * script wrapper using 'mbean' function. Instead of using - * MBean proxies 'mbean' function creates a script wrapper - * that provides similar convenience but uses explicit - * invocation behind the scene. This implies that mbean - * wrapper would the same for dynamic MBeans as well. - */ - var diagBean = mbean("com.sun.management:type=HotSpotDiagnostic"); - - // dump the heap in the file - diagBean.dumpHeap(file, true); -} diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/hello.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/hello.js deleted file mode 100644 index 6c0acd36138..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/hello.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * This is sample JavaScript file that can be loaded into script console. - * This file prints "hello, world". - */ - -echo("hello, world"); diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/invoke.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/invoke.js deleted file mode 100644 index 919769bc493..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/invoke.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * This script demonstrates "invokeMBean" function. Instead - * of using MXBean proxy or script wrapper object returned by - * 'mbean' function, this file uses direct invoke on MBean. - * - * To use this particular script, load this script file in - * script console prompt and call resetPeakThreadCount(). - - */ - -/** - * Resets the peak thread count to the current number of live threads. - * - */ -function resetPeakThreadCount() { - return invokeMBean("java.lang:type=Threading", "resetPeakThreadCount", [], {}); -} - diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/jstack.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/jstack.js deleted file mode 100644 index aff7d7c04e1..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/jstack.js +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * This file defines 'jstack' function to print stack traces of - * threads.'jstack' function which can be called once or periodically - * from a timer thread (calling it periodically would slow down the target - * application). To call this once, just call 'jstack()' in script - * console prompt. To call jstack in a timer thread, you can use - * - * var t = setInterval(function () { jstack(print); }, 5000); - * - * The above call prints threads in sorted order for every 5 seconds. - * The print output goes to OS console window from which jconsole was - * started. The timer can be cancelled later by clearTimeout() function - * as shown below: - * - * clearInterval(t); - */ - - -/** - * print given ThreadInfo using given printFunc - */ -function printThreadInfo(ti, printFunc) { - printFunc(ti.threadId + " - " + ti.threadName + " - " + ti.threadState); - var stackTrace = ti.stackTrace; - for (var i in stackTrace) { - printFunc("\t" + stackTrace[i]); - } -} - -/** - * print stack traces of all threads. - * - * @param printFunc function called to print [optional] - * @param maxFrames maximum number of frames to print [optional] - */ -function jstack(printFunc, maxFrames) { - // by default use 'echo' to print. Other choices could be - // 'print' or custom function that writes in a text file - if (printFunc == undefined) { - printFunc = echo; - } - - // by default print 25 frames - if (maxFrames == undefined) { - maxFrames = 25; - } - - var tmbean = newPlatformMXBeanProxy( - "java.lang:type=Threading", - java.lang.management.ThreadMXBean.class); - - var tids = tmbean.allThreadIds; - var tinfos = tmbean["getThreadInfo(long[],int)"](tids, maxFrames); - - for (var i in tinfos) { - printThreadInfo(tinfos[i], printFunc); - } -} diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/jtop.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/jtop.js deleted file mode 100644 index 2733b12a69e..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/jtop.js +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * This code is "ported" from JTop demo. This file defines - * 'jtop' function. jtop prints threads sorting by CPU time. - * jtop can be called once or periodically from a timer thread. - * To call this once, just call 'jtop()' in script console prompt. - * To call jtop in a timer thread, you can use - * - * var t = setInterval(function () { jtop(print); }, 2000); - * - * The above call prints threads in sorted order for every 2 seconds. - * The print output goes to OS console window from which jconsole was - * started. The timer can be cancelled later by clearTimeout() function - * as shown below: - * - * clearInterval(t); - */ - -/** - * This function returns a List of Map.Entry objects - * in which each entry maps cpu time to ThreadInfo. - */ -function getThreadList() { - var tmbean = newPlatformMXBeanProxy( - "java.lang:type=Threading", - java.lang.management.ThreadMXBean.class); - - if (!tmbean.isThreadCpuTimeSupported()) { - return java.util.Collections.EMPTY_LIST; - } - - tmbean.setThreadCpuTimeEnabled(true); - - var tids = tmbean.allThreadIds; - var tinfos = tmbean["getThreadInfo(long[])"](tids); - - var map = new java.util.TreeMap(); - for (var i in tids) { - var cpuTime = tmbean.getThreadCpuTime(tids[i]); - if (cpuTime != -1 && tinfos[i] != null) { - map.put(cpuTime, tinfos[i]); - } - } - var list = new java.util.ArrayList(map.entrySet()); - java.util.Collections.reverse(list); - return list; -} - -/** - * This function prints threads sorted by CPU time. - * - * @param printFunc function called back to print [optional] - * - * By default, it uses 'echo' function to print in screen. - * Other choices could be 'print' (prints in console), 'alert' - * to show message box. Or you can define a function that writes - * the output to a text file. - */ -function jtop(printFunc) { - if (printFunc == undefined) { - printFunc = echo; - } - var list = getThreadList(); - var itr = list.iterator(); - printFunc("time - state - name"); - while (itr.hasNext()) { - var entry = itr.next(); - // time is in nanoseconds - convert to seconds - var time = entry.key / 1.0e9; - var name = entry.value.threadName; - var state = entry.value.threadState; - printFunc(time + " - " + state + " - " + name); - } -} diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/sysprops.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/sysprops.js deleted file mode 100644 index 5ff958d836e..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/sysprops.js +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * This file defines 'sysprops' function to print Java System - * properties.'sysprops' function which can be called once or periodically - * from a timer thread (calling it periodically would slow down the target - * application). To call this once, just call 'sysprops()' in script - * console prompt. To call sysprops in a timer thread, you can use - * - * var t = setInterval(function () { sysprops(print); }, 5000); - * - * The above call prints threads in sorted order for every 5 seconds. - * The print output goes to OS console window from which jconsole was - * started. The timer can be cancelled later by clearTimeout() function - * as shown below: - * - * clearInterval(t); - */ - - -/** - * Returns System properties as a Map - */ -function getSystemProps() { - var runtimeBean = newPlatformMXBeanProxy( - "java.lang:type=Runtime", - java.lang.management.RuntimeMXBean.class); - return runtimeBean.systemProperties; -} - -/** - * print System properties - * - * @param printFunc function called to print [optional] - */ -function sysprops(printFunc) { - // by default use 'echo' to print. Other choices could be - // 'print' or custom function that writes in a text file - if (printFunc == undefined) { - printFunc = echo; - } - - var map = getSystemProps(); - var keys = map.keySet().iterator(); - while (keys.hasNext()) { - var key = keys.next(); - var value = map.get(key); - printFunc(key + "=" + value); - } -} diff --git a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/verbose.js b/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/verbose.js deleted file mode 100644 index a749ce36c65..00000000000 --- a/jdk/src/demo/share/scripting/jconsole-plugin/src/scripts/verbose.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - * This script demonstrates "getMBeanAttribute" - * and "setMBeanAttribute" functions. Instead of using - * MXBean proxy or script wrapper object returned by - * 'mbean' function, this file uses direct get/set MBean - * attribute functions. - * - * To use this particular script, load this script file in - * script console prompt and call verboseGC or verboseClass - * functions. These functions based on events such as - * heap threshold crossing a given limit. i.e., A timer thread - * can keep checking for threshold event and then turn on - * verbose:gc or verbose:class based on expected event. - - */ - -/** - * Get or set verbose GC flag. - * - * @param flag verbose mode flag [optional] - * - * If flag is not passed verboseGC returns current - * flag value. - */ -function verboseGC(flag) { - if (flag == undefined) { - // no argument passed. interpret this as 'get' - return getMBeanAttribute("java.lang:type=Memory", "Verbose"); - } else { - return setMBeanAttribute("java.lang:type=Memory", "Verbose", flag); - } -} - -/** - * Get or set verbose class flag. - * - * @param flag verbose mode flag [optional] - * - * If flag is not passed verboseClass returns current - * flag value. - */ -function verboseClass(flag) { - if (flag == undefined) { - // no argument passed. interpret this as 'get' - return getMBeanAttribute("java.lang:type=ClassLoading", "Verbose"); - } else { - return setMBeanAttribute("java.lang:type=ClassLoading", "Verbose", flag); - } -} diff --git a/jdk/src/demo/solaris/jni/Poller/Client.java b/jdk/src/demo/solaris/jni/Poller/Client.java deleted file mode 100644 index ffa706eabc9..00000000000 --- a/jdk/src/demo/solaris/jni/Poller/Client.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -import java.util.*; -import java.net.*; -import java.io.*; - -public class Client -{ - private final static int BYTESPEROP= PollingServer.BYTESPEROP; - private final static int PORTNUM = PollingServer.PORTNUM; - private final static int MAXCONN = PollingServer.MAXCONN; - - private static Socket[] sockArr = new Socket[MAXCONN]; - private static int totalConn =10; - private static int bytesToSend =1024000; - private static int connections = 0; - private static int sends = 0; - - public static void main (String args[]) { - - String host = "localhost"; - - if (args.length < 1 || args.length > 3) { - System.out.println("Usage : java Client "); - System.out.println(" | java Client "); - System.out.println(" | java Client " + - " "); - System.exit(-1); - } - - if (args.length >= 1) - totalConn = java.lang.Integer.valueOf(args[0]).intValue(); - if (args.length >= 2) - host = args[1]; - if (args.length == 3) - bytesToSend = java.lang.Integer.valueOf(args[2]).intValue() * 1024; - - - if (totalConn <= 0 || totalConn > MAXCONN) { - System.out.println("Connections out of range. Terminating."); - System.exit(-1); - } - - System.out.println("Using " + totalConn + " connections for sending " + - bytesToSend + " bytes to " + host); - - - try { - Socket ctrlSock = new Socket (host, PORTNUM); - PrintStream ctrlStream = - new PrintStream(ctrlSock.getOutputStream()); - ctrlStream.println(bytesToSend); - ctrlStream.println(totalConn); - - while (connections < totalConn ) { - sockArr[connections] = new Socket (host, PORTNUM); - connections ++; - } - System.out.println("Connections made : " + connections); - - byte[] buff = new byte[BYTESPEROP]; - for (int i = 0; i < BYTESPEROP; i++) // just put some junk in! - buff[i] = (byte) i; - - Random rand = new Random(5321L); - while (sends < bytesToSend/BYTESPEROP) { - int idx = java.lang.Math.abs(rand.nextInt()) % totalConn; - sockArr[idx].getOutputStream().write(buff,0,BYTESPEROP); - sends++; - } - // Wait for server to say done. - int bytes = ctrlSock.getInputStream().read(buff, 0, BYTESPEROP); - System.out.println (" Total connections : " + connections + - " Bytes sent : " + sends * BYTESPEROP + - "...Done!"); - } catch (Exception e) { e.printStackTrace(); } - } -} diff --git a/jdk/src/demo/solaris/jni/Poller/LinkedQueue.java b/jdk/src/demo/solaris/jni/Poller/LinkedQueue.java deleted file mode 100644 index bc70554f3e7..00000000000 --- a/jdk/src/demo/solaris/jni/Poller/LinkedQueue.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - File: SLQ.java - Originally: LinkedQueue.java - - Originally written by Doug Lea and released into the public domain. - This may be used for any purposes whatsoever without acknowledgment. - Thanks for the assistance and support of Sun Microsystems Labs, - and everyone contributing, testing, and using this code. - - History: - Date Who What - 11Jun1998 dl Create public version - 25aug1998 dl added peek - 10dec1998 dl added isEmpty - 10jun1999 bc modified for isolated use -*/ - -// Original was in package EDU.oswego.cs.dl.util.concurrent; - -/** - * A linked list based channel implementation, - * adapted from the TwoLockQueue class from CPJ. - * The algorithm avoids contention between puts - * and takes when the queue is not empty. - * Normally a put and a take can proceed simultaneously. - * (Although it does not allow multiple concurrent puts or takes.) - * This class tends to perform more efficently than - * other Channel implementations in producer/consumer - * applications. - *

[ Introduction to this package. ] - **/ - -public class LinkedQueue { - - - /** - * Dummy header node of list. The first actual node, if it exists, is always - * at head_.next. After each take, the old first node becomes the head. - **/ - protected LinkedNode head_; - protected int count_; - /** - * Helper monitor for managing access to last node, in case it is also first. - * last_ and waitingForTake_ ONLY used with synch on appendMonitor_ - **/ - protected final Object lastMonitor_ = new Object(); - - /** - * The last node of list. Put() appends to list, so modifies last_ - **/ - protected LinkedNode last_; - - /** - * The number of threads waiting for a take. - * Notifications are provided in put only if greater than zero. - * The bookkeeping is worth it here since in reasonably balanced - * usages, the notifications will hardly ever be necessary, so - * the call overhead to notify can be eliminated. - **/ - protected int waitingForTake_ = 0; - - public LinkedQueue() { - head_ = new LinkedNode(null); - last_ = head_; - count_ = 0; - } - - /** Main mechanics for put/offer **/ - protected void insert(Object x) { - synchronized(lastMonitor_) { - LinkedNode p = new LinkedNode(x); - last_.next = p; - last_ = p; - count_++; - if (count_ > 1000 && (count_ % 1000 == 0)) - System.out.println("In Queue : " + count_); - if (waitingForTake_ > 0) - lastMonitor_.notify(); - } - } - - /** Main mechanics for take/poll **/ - protected synchronized Object extract() { - Object x = null; - LinkedNode first = head_.next; - if (first != null) { - x = first.value; - first.value = null; - head_ = first; - count_ --; - } - return x; - } - - - public void put(Object x) throws InterruptedException { - if (x == null) throw new IllegalArgumentException(); - if (Thread.interrupted()) throw new InterruptedException(); - insert(x); - } - - public boolean offer(Object x, long msecs) throws InterruptedException { - if (x == null) throw new IllegalArgumentException(); - if (Thread.interrupted()) throw new InterruptedException(); - insert(x); - return true; - } - - public Object take() throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - // try to extract. If fail, then enter wait-based retry loop - Object x = extract(); - if (x != null) - return x; - else { - synchronized(lastMonitor_) { - try { - ++waitingForTake_; - for (;;) { - x = extract(); - if (x != null) { - --waitingForTake_; - return x; - } - else { - lastMonitor_.wait(); - } - } - } - catch(InterruptedException ex) { - --waitingForTake_; - lastMonitor_.notify(); - throw ex; - } - } - } - } - - public synchronized Object peek() { - LinkedNode first = head_.next; - if (first != null) - return first.value; - else - return null; - } - - - public synchronized boolean isEmpty() { - return head_.next == null; - } - - public Object poll(long msecs) throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - Object x = extract(); - if (x != null) - return x; - else { - synchronized(lastMonitor_) { - try { - long waitTime = msecs; - long start = (msecs <= 0)? 0 : System.currentTimeMillis(); - ++waitingForTake_; - for (;;) { - x = extract(); - if (x != null || waitTime <= 0) { - --waitingForTake_; - return x; - } - else { - lastMonitor_.wait(waitTime); - waitTime = msecs - (System.currentTimeMillis() - start); - } - } - } - catch(InterruptedException ex) { - --waitingForTake_; - lastMonitor_.notify(); - throw ex; - } - } - } - } - - class LinkedNode { - Object value; - LinkedNode next = null; - LinkedNode(Object x) { value = x; } - LinkedNode(Object x, LinkedNode n) { value = x; next = n; } - } -} diff --git a/jdk/src/demo/solaris/jni/Poller/Poller.c b/jdk/src/demo/solaris/jni/Poller/Poller.c deleted file mode 100644 index 5c627ac57ca..00000000000 --- a/jdk/src/demo/solaris/jni/Poller/Poller.c +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* - ********************************************************************** - * Poller.c : - * JNI code for use with Poller.java, principally to take advantage - * of poll() or /dev/poll multiplexing. - * - * One will need Solaris 8 or Solaris 7 with adequate patches to take - * advantage of the /dev/poll performance enhancements, though any - * version of Solaris 7 will automatically use the kernel poll() - * caching. And poll() will function in 2.5.1 and 2.6 as well, but - * will not perform well for large numbers of file descriptors. - * - * Several assumptions have been made to simplify this code : - * 1> At most MAX_HANDLES (32) separate pollable entities are currently - * supported. - * 2> Global synchronization from Java is assumed for all init, create - * and destroy routines. Per Object (handle passed in) synchronization - * is required for all AddFd, RemoveFd, IsMember, and Wait routines. - * 3> It is currently up to the user to handle waking up an - * existing nativeWait() call to do an addfd or removefd on - * that set...could implement that here with an extra pipe, or - * with a pair of loopback sockets in Poller.java or user code. - * In most cases interruption is not necessary for deletions, - * so long as deletions are queued up outside the Poller class - * and then executed the next time waitMultiple() returns. - * 4> /dev/poll performance could be slightly improved by coalescing - * adds/removes so that a write() is only done before the ioctl - * (DP_POLL), but this complicates exception handling and sees - * only modest performance gains so wasn't done. - * 5> /dev/poll does not report errors on attempts to remove non- - * extant fds, but a future bug fix to the /dev/poll device driver - * should solve this problem. - * 6> Could add simpler code for pre-Solaris 7 releases which will - * perform slightly better on those OSs. But again there - * are only modest gains to be had from these new code paths, - * so they've been omitted here. - * - * Compile "cc -G -o /libpoller.so -I ${JAVA_HOME}/include " \ - * -I ${JAVA_HOME}/include/solaris Poller.c" and place the - * in your LD_LIBRARY_PATH - * - ********************************************************************** - */ - -#include -#include -#include -#include -#include -#include - - -/* - * Remove "_NOT"s to turn on features - * Append "_NOT" to turn off features. - * Use of /dev/poll requires both the include file and kernel driver. - */ -#define DEBUG_NOT -#define DEVPOLL_NOT - -#ifdef DEVPOLL -#include -#endif - -#include "Poller.h" - -#define MAX_HANDLES 32 - - -#ifdef DEBUG -#define DBGMSG(x) printf x -#define ASSERT(x) {if (!(x)) \ - printf("assertion(%s) failed at line : %d\n",#x,__LINE__);} -#define CHECK_HANDLE(x) check_handle(x) -#else -#define DBGMSG(x) -#define ASSERT(x) -#define CHECK_HANDLE(x) -#endif - -/* - * Globals ...protect all with a global synchronization object. - */ - -static int Current_handle = 0; -static int Use_devpoll = 0; -static int Max_index = 0; - -/* - * Per Poller object data. - * Must be synchronized on a per Poller object basis. - */ - -typedef struct ioevent { - int inuse; - int devpollfd; - int last_index; - int total_free; - int left_events; - int max_index; - pollfd_t *pfd; -} ioevent_t; - -static ioevent_t IOE_handles[MAX_HANDLES]; - - /* - * Exceptions to be thrown. - * Note : assuming all illegal argument and NULL pointer checks - * have already been done by the Java calling methods. - */ -static jint throwOutOfMemoryError(JNIEnv *env, const char * cause) -{ - (*env)->ThrowNew(env, (*env)->FindClass(env,"java/lang/OutOfMemoryError"), - cause); - return -1; -} -static jint throwInterruptedIOException(JNIEnv *env, const char * cause) -{ - (*env)->ThrowNew(env, - (*env)->FindClass(env,"java/io/InterruptedIOException"), - cause); - return -1; -} -static jint throwIllegalStateException(JNIEnv *env, const char * cause) -{ - (*env)->ThrowNew(env, - (*env)->FindClass(env,"java/lang/IllegalStateException"), - cause); - return -1; -} - -#define MEMORY_EXCEPTION(str) throwOutOfMemoryError(env, "Poller:" str) -#define STATE_EXCEPTION(str) throwIllegalStateException(env, "Poller:" str) -#define INTERRUPT_EXCEPTION(str) throwInterruptedIOException(env, \ - "Poller:" str) -jint addfd(JNIEnv *, ioevent_t *, jint, jshort); -jint removefd(JNIEnv *, ioevent_t *, jint); - - /* - * Class Poller - * Method: nativeInit - * Signature: ()I - * - * Only to be called once, right after this library is loaded, - * so no need to deal with reentrancy here. - * Could do as a pragma ini, but that isn't as portable. - */ -JNIEXPORT jint JNICALL Java_Poller_nativeInit(JNIEnv *env, jclass cls) -{ - int testdevpollfd; - int i; - -#ifdef DEVPOLL - /* - * See if we can use this much faster method - * Note : must have fix for BUGID # 4223353 or OS can crash! - */ - testdevpollfd = open("/dev/poll",O_RDWR); - if (testdevpollfd >= 0) { - /* - * If Solaris 7, we need a patch - * Until we know what string to search for, we'll play it - * safe and disable this for Solaris 7. - */ - - if (!strcmp(name.release,"5.7")) - { - Use_devpoll = 0; - } - else - { - Use_devpoll = 1; - } - } - - DBGMSG(("Use_devpoll=%d\n" ,Use_devpoll)); - close(testdevpollfd); -#endif - - /* - * For now, we optimize for Solaris 7 if /dev/poll isn't - * available, as it is only a small % hit for Solaris < 7. - * if ( (Use_devpoll == 0) && !strcmp(name.release,"5.6") ) - * Use_sol7opt = 0; - */ - Current_handle = 0; - for (i = 0; i < MAX_HANDLES; i++) { - IOE_handles[i].devpollfd = -1; - IOE_handles[i].pfd = NULL; - } - - /* - * this tells me the max number of open filedescriptors - */ - Max_index = sysconf(_SC_OPEN_MAX); - if (Max_index < 0) { - Max_index = 1024; - } - - DBGMSG(("got sysconf(_SC_OPEN_MAX)=%d file desc\n",Max_index)); - - return 0; -} - -JNIEXPORT jint JNICALL Java_Poller_getNumCPUs(JNIEnv *env, jclass cls) -{ - return sysconf(_SC_NPROCESSORS_ONLN); -} - - /* - * Class: Poller - * Method: nativeCreatePoller - * Signature: (I)I - * Note : in the case where /dev/poll doesn't exist, - * using more than one poll array could hurt - * Solaris 7 performance due to kernel caching. - */ - -JNIEXPORT jint JNICALL Java_Poller_nativeCreatePoller - (JNIEnv *env, jobject obj, jint maximum_fds) -{ - int handle, retval, i; - ioevent_t *ioeh; - - if (maximum_fds == -1) { - maximum_fds = Max_index; - } - handle = Current_handle; - if (Current_handle >= MAX_HANDLES) { - for (i = 0; i < MAX_HANDLES; i++) { - if (IOE_handles[i].inuse == 0) { - handle = i; - break; - } - } - if (handle >= MAX_HANDLES) { - return MEMORY_EXCEPTION("CreatePoller - MAX_HANDLES exceeded"); - } - } else { - Current_handle++; - } - - ioeh = &IOE_handles[handle]; - - ioeh->inuse = 1; - - ioeh->last_index = 0; - ioeh->total_free = 0; - ioeh->left_events = 0; - ioeh->max_index = maximum_fds; - - retval = handle; - if (Use_devpoll) { - ioeh->devpollfd = open("/dev/poll",O_RDWR); - DBGMSG(("Opened /dev/poll, set devpollfd = %d\n",ioeh->devpollfd)); - if (ioeh->devpollfd < 0) { - Current_handle--; - return MEMORY_EXCEPTION("CreatePoller - can\'t open /dev/poll"); - } - } - ioeh->pfd = malloc(maximum_fds * sizeof(pollfd_t)); - if (ioeh->pfd == NULL) { - Current_handle--; - return MEMORY_EXCEPTION("CreatePoller - malloc failure"); - } - - return retval; -} - - /* - * Class: Poller - * Method: nativeDestroyPoller - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_Poller_nativeDestroyPoller - (JNIEnv *env, jobject obj, jint handle) -{ - - ioevent_t *ioeh; - - if (handle < 0 || handle >= MAX_HANDLES) - { - STATE_EXCEPTION("DestroyPoller - handle out of range"); - return; - } - - ioeh = &IOE_handles[handle]; - ioeh->inuse = 0; - if (Use_devpoll) { - close(ioeh->devpollfd); - } - free(ioeh->pfd); -} - -#ifdef DEBUG -static void check_handle(ioevent_t *ioeh) -{ - int i,used,unused; - - used=unused=0; - for (i = 0; i < ioeh->last_index; i++) - { - if (ioeh->pfd[i].fd == -1) - unused++; - else - used++; - } - if (unused != ioeh->total_free) - printf("WARNING : found %d free, claimed %d. Used : %d\n", - unused, ioeh->total_free, used); -} -#endif - - /* - * Class: Poller - * Method: nativeAddFd - * Signature: (IIS)I - * - * Currently doesn't check to make sure we aren't adding - * an fd already added (no problem for /dev/poll...just - * an array waster for poll()). - */ -JNIEXPORT jint JNICALL Java_Poller_nativeAddFd - (JNIEnv *env, jobject obj, jint handle, jint fd, jshort events) -{ - int retval; - ioevent_t *ioeh; - - if (handle < 0 || handle >= MAX_HANDLES) - return STATE_EXCEPTION("AddFd - handle out of range"); - - ioeh = &IOE_handles[handle]; - - CHECK_HANDLE(ioeh); - - #ifdef DEVPOLL - if (Use_devpoll) - { - int i; - pollfd_t pollelt; - - /* - * use /dev/poll - */ - pollelt.fd = fd; - pollelt.events = events; - if ((i = write(ioeh->devpollfd, &pollelt, sizeof(pollfd_t))) != - sizeof(pollfd_t)) { - DBGMSG(("write to devpollfd=%d showed %d bytes out of %d\n", - ioeh->devpollfd,i,sizeof(pollfd_t))); - return STATE_EXCEPTION("AddFd - /dev/poll add failure"); - } - else - { - retval = fd; - } - } - else - #endif - { /* no /dev/poll available */ - retval = addfd(env, ioeh, fd, events); - } - return retval; -} - -/* - * Addfd to pollfd array...optimized for Solaris 7 - */ -jint addfd(JNIEnv *env, ioevent_t *ioeh, jint fd, jshort events) -{ - int idx; - - if (ioeh->total_free) - { - /* - * Traversing from end because that's where we pad. - */ - ioeh->total_free--; - for (idx = ioeh->last_index - 1; idx >= 0; idx--) { - if (ioeh->pfd[idx].fd == -1) - break; - } - } - else if (ioeh->last_index >= ioeh->max_index) - { - return MEMORY_EXCEPTION("AddFd - too many fds"); - } - else - { - int i; - int new_total; - /* - * For Solaris 7, want to add some growth space - * and fill extras with fd=-1. This allows for - * kernel poll() implementation to perform optimally. - */ - new_total = ioeh->last_index; - new_total += (new_total/10) + 1; /* bump size by 10% */ - if (new_total > ioeh->max_index) - new_total = ioeh->max_index; - for (i = ioeh->last_index; i <= new_total; i++) - { - ioeh->pfd[i].fd = -1; - } - idx = ioeh->last_index; - ioeh->total_free = new_total - ioeh->last_index - 1; - DBGMSG(("Just grew from %d to %d in size\n", - ioeh->last_index, new_total)); - ioeh->last_index = new_total; - } - ASSERT((idx >= 0) && (idx <= ioeh->max_index)); - ASSERT(ioeh->pfd[idx].fd == -1); - ioeh->pfd[idx].fd = fd; - ioeh->pfd[idx].events = events; - ioeh->pfd[idx].revents = 0; - - CHECK_HANDLE(ioeh); - - return fd; -} - -/* - * Class: Poller - * Method: nativeRemoveFd - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_Poller_nativeRemoveFd - (JNIEnv *env, jobject obj, jint handle, jint fd) -{ - ioevent_t *ioeh; - - if (handle < 0 || handle >= MAX_HANDLES) - return STATE_EXCEPTION("RemoveFd - handle out of range"); - - ioeh = &IOE_handles[handle]; - - #ifdef DEVPOLL - if (Use_devpoll) - { - /* - * use /dev/poll - currently no need for locking here. - */ - pollfd_t pollelt; - - pollelt.fd = fd; - pollelt.events = POLLREMOVE; - if (write(ioeh->devpollfd, &pollelt, - sizeof(pollfd_t) ) != sizeof(pollfd_t)) - { - return STATE_EXCEPTION("RemoveFd - /dev/poll failure"); - } - } - else - #endif DEVPOLL - { - return removefd(env, ioeh,fd); - } -} -/* - * remove from pollfd array...optimize for Solaris 7 - */ -jint removefd(JNIEnv *env, ioevent_t *ioeh, jint fd) -{ - int i; - int found = 0; - - { /* !Use_devpoll */ - for (i = 0; i < ioeh->last_index; i++) - { - if (ioeh->pfd[i].fd == fd) - { - ioeh->pfd[i].fd = -1; - found = 1; - break; - } - } - if (!found) - { - return STATE_EXCEPTION("RemoveFd - no such fd"); - } - ioeh->left_events = 0; /* Have to go back to the kernel */ - ioeh->total_free++; - /* - * Shrinking pool if > 33% empty. Just don't do this often! - */ - if ( (ioeh->last_index > 100) && - (ioeh->total_free > (ioeh->last_index / 3)) ) - { - int j; - /* - * we'll just bite the bullet here, since we're > 33% empty. - * walk through and eliminate -1 fd values, shrink total - * size to still have ~ 10 fd==-1 values at end. - * Start at end (since we pad here) and, when we find fd != -1, - * swap with an earlier fd == -1 until we have all -1 values - * at the end. - */ - CHECK_HANDLE(ioeh); - for (i = ioeh->last_index - 1, j = 0; i > j; i--) - { - if (ioeh->pfd[i].fd != -1) - { - while ( (j < i) && (ioeh->pfd[j].fd != -1) ) - j++; - DBGMSG( ("i=%d,j=%d,ioeh->pfd[j].fd=%d\n", - i, j, ioeh->pfd[j].fd) ); - if (j < i) - { - ASSERT(ioeh->pfd[j].fd == -1); - ioeh->pfd[j].fd = ioeh->pfd[i].fd; - ioeh->pfd[j].events = ioeh->pfd[i].events; - ioeh->pfd[i].fd = -1; - } - } - } - DBGMSG(("Just shrunk from %d to %d in size\n", - ioeh->last_index, j+11)); - ioeh->last_index = j + 11; /* last_index always 1 greater */ - ioeh->total_free = 10; - CHECK_HANDLE(ioeh); - } - } /* !Use_devpoll */ - - return 1; -} - - /* - * Class: Poller - * Method: nativeIsMember - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_Poller_nativeIsMember - (JNIEnv *env, jobject obj, jint handle, jint fd) -{ - int found = 0; - int i; - ioevent_t *ioeh; - - if (handle < 0 || handle >= MAX_HANDLES) - return STATE_EXCEPTION("IsMember - handle out of range"); - - ioeh = &IOE_handles[handle]; - - #ifdef DEVPOLL - if (Use_devpoll) - { - pollfd_t pfd; - /* - * DEVPOLL ioctl DP_ISPOLLED call to determine if fd is polled. - */ - pfd.fd = fd; - pfd.events = 0; - pfd.revents = 0; - found = ioctl(ioeh->devpollfd, DP_ISPOLLED, &pfd); - if (found == -1) - { - return STATE_EXCEPTION("IsMember - /dev/poll failure"); - } - } - else - #endif - { - for (i = 0; i < ioeh->last_index; i++) - { - if (fd == ioeh->pfd[i].fd) - { - found = 1; - break; - } - } - } - - return found; -} - - /* - * Class: Poller - * Method: nativeWait - * Signature: (II[I[SJ)I - */ -JNIEXPORT jint JNICALL Java_Poller_nativeWait - (JNIEnv *env, jobject obj, jint handle, jint maxEvents, - jintArray jfds, jshortArray jrevents, jlong timeout) -{ - int useEvents, count, idx; - short *reventp; - jint *fdp; - int retval; - ioevent_t *ioeh; - jboolean isCopy1,isCopy2; - - if (handle < 0 || handle >= MAX_HANDLES) - return STATE_EXCEPTION("nativeWait - handle out of range"); - - ioeh = &IOE_handles[handle]; - - if (maxEvents == 0) /* just doing a kernel delay! */ - { - useEvents = poll(NULL,0L,timeout); - return 0; - } - - #ifdef DEVPOLL - if (Use_devpoll) - { - struct dvpoll dopoll; - /* - * DEVPOLL ioctl DP_POLL call, reading - */ - dopoll.dp_timeout = timeout; - dopoll.dp_nfds=maxEvents; - dopoll.dp_fds=ioeh->pfd; - - useEvents = ioctl(ioeh->devpollfd, DP_POLL, &dopoll); - while ((useEvents == -1) && (errno == EAGAIN)) - useEvents = ioctl(ioeh->devpollfd, DP_POLL, &dopoll); - - if (useEvents == -1) - { - if (errno == EINTR) - return INTERRUPT_EXCEPTION("nativeWait - /dev/poll failure EINTR"); - else - return STATE_EXCEPTION("nativeWait - /dev/poll failure"); - } - - reventp =(*env)->GetShortArrayElements(env,jrevents,&isCopy1); - fdp =(*env)->GetIntArrayElements(env,jfds,&isCopy2); - for (idx = 0,count = 0; idx < useEvents; idx++) - { - if (ioeh->pfd[idx].revents) - { - fdp[count] = ioeh->pfd[idx].fd; - reventp[count] = ioeh->pfd[idx].revents; - count++; - } - } - if (count < useEvents) - return STATE_EXCEPTION("Wait - Corrupted internals"); - - if (isCopy1 == JNI_TRUE) - (*env)->ReleaseShortArrayElements(env,jrevents,reventp,0); - if (isCopy2 == JNI_TRUE) - (*env)->ReleaseIntArrayElements(env,jfds,fdp,0); - } - else - #endif - { /* !Use_devpoll */ - - /* no leftovers=>go to kernel */ - if (ioeh->left_events == 0) - { - useEvents = poll(ioeh->pfd,ioeh->last_index, timeout); - while ((useEvents == -1) && (errno == EAGAIN)) - useEvents = poll(ioeh->pfd,ioeh->last_index, timeout); - if (useEvents == -1) - { - if (errno == EINTR) - return INTERRUPT_EXCEPTION("Wait - poll() failure EINTR-" \ - "IO interrupted."); - else if (errno == EINVAL) - return STATE_EXCEPTION("Wait - poll() failure EINVAL-" \ - "invalid args (is fdlim cur < max?)"); - else - return STATE_EXCEPTION("Wait - poll() failure"); - } - ioeh->left_events = useEvents; - DBGMSG(("waitnative : poll returns : %d\n",useEvents)); - } - else - { /* left over from last call */ - useEvents = ioeh->left_events; - } - - if (useEvents > maxEvents) - { - useEvents = maxEvents; - } - - ioeh->left_events -= useEvents; /* left to process */ - - DBGMSG(("waitnative : left %d, use %d, max %d\n",ioeh->left_events, - useEvents,maxEvents)); - - if (useEvents > 0) - { - reventp =(*env)->GetShortArrayElements(env,jrevents,&isCopy1); - fdp =(*env)->GetIntArrayElements(env,jfds,&isCopy2); - for (idx = 0,count = 0; (idx < ioeh->last_index) && - (count < useEvents); idx++) - { - if (ioeh->pfd[idx].revents) - { - fdp[count] = ioeh->pfd[idx].fd; - reventp[count] = ioeh->pfd[idx].revents; - /* in case of leftover for next walk */ - ioeh->pfd[idx].revents = 0; - count++; - } - } - if (count < useEvents) - { - ioeh->left_events = 0; - return STATE_EXCEPTION("Wait - Corrupted internals"); - } - if (isCopy1 == JNI_TRUE) - (*env)->ReleaseShortArrayElements(env,jrevents,reventp,0); - if (isCopy2 == JNI_TRUE) - (*env)->ReleaseIntArrayElements(env,jfds,fdp,0); - } - } /* !Use_devpoll */ - - return useEvents; -} diff --git a/jdk/src/demo/solaris/jni/Poller/Poller.java b/jdk/src/demo/solaris/jni/Poller/Poller.java deleted file mode 100644 index a144dfbcb1f..00000000000 --- a/jdk/src/demo/solaris/jni/Poller/Poller.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -import java.lang.reflect.*; -import java.io.*; -import java.net.*; - -/** - * This class is provided for access to the underlying poll(2) - * or /dev/poll kernel interfaces. This may be needed for - * multiplexing IO when an application cannot afford to have - * a thread block on each outstanding IO request. - * - * It currently supports the same basic functionality as the - * C poll(2) API, although for efficiency we needed to avoid - * passing the entire pollfd array for every call. See man - * pages for poll(2) for info on C API and event types. - * - * - * @author Bruce Chapman - * @see java.io.FileDescriptor - * @see java.net.Socket - * @see attached README.txt - * @since 1.2 - */ - -public class Poller { - /** - * Solaris POLL event types. - */ - public final static short POLLERR = 0x08; - public final static short POLLHUP = 0x10; - public final static short POLLNVAL = 0x20; - public final static short POLLIN = 1; - public final static short POLLPRI = 2; - public final static short POLLOUT = 4; - public final static short POLLRDNORM = 0x40; - public final static short POLLWRNORM = POLLOUT ; - public final static short POLLRDBAND = 0x80; - public final static short POLLWRBAND = 0x100; - public final static short POLLNORM = POLLRDNORM; - - /* - * This global synchronization object must be used for all - * creation or destruction of Poller objects. - */ - private final static Object globalSync = new Object(); - - /* - * The handle for a Poller Object...is used in the JNI C code - * where all the associated data is kept. - */ - private int handle; - - /** - * Constructs an instance of a Poller object. - * Native code uses sysconf(_SC_OPEN_MAX) to determine how - * many fd/skt objects this Poller object can contain. - */ - public Poller() throws Exception { - synchronized(globalSync) { - this.handle = nativeCreatePoller(-1); - } - } - - /** - * Constructs an instance of a Poller object. - * @param maxFd the maximum number of FileDescriptors/Sockets - * this Poller object can contain. - */ - public Poller(int maxFd) throws Exception { - synchronized(globalSync) { - this.handle = nativeCreatePoller(maxFd); - } - } - - /** - * Needed to clean up at the JNI C level when object is GCd. - */ - protected void finalize() throws Throwable { - synchronized(globalSync) { - nativeDestroyPoller(handle); - super.finalize(); - } - } - - /** - * Since we can't guarantee WHEN finalize is called, we may - * recycle on our own. - * @param maxFd the maximum number of FileDescriptors/Sockets - * this Poller object can contain. - */ - public void reset(int maxFd) throws Exception { - synchronized(globalSync) { - nativeDestroyPoller(handle); - this.handle = nativeCreatePoller(maxFd); - } - } - /** - * Since we can't guarantee WHEN finalize is called, we may - * recycle on our own. - */ - public void reset() throws Exception { - synchronized(globalSync) { - nativeDestroyPoller(handle); - this.handle = nativeCreatePoller(-1); - } - } - - /** - * Add FileDescriptor to the set handled by this Poller object. - * - * @param fdObj the FileDescriptor, Socket, or ServerSocket to add. - * @param event the bitmask of events we are interested in. - * @return the OS level fd associated with this IO Object - * (which is what waitMultiple() stores in fds[]) - */ - public synchronized int add(Object fdObj, short event) throws Exception { - return nativeAddFd(handle,findfd(fdObj), event); - } - - /** - * Remove FileDescriptor from the set handled by this Poller object. - * - * Must be called before the fd/skt is closed. - * @param fdObj the FileDescriptor, Socket, or ServerSocket to remove. - * @return true if removal succeeded. - */ - public synchronized boolean remove(Object fdObj) throws Exception { - return (nativeRemoveFd(handle,findfd(fdObj)) == 1); - } - /** - * Check if fd or socket is already in the set handled by this Poller object - * - * @param fdObj the FileDescriptor or [Server]Socket to check. - * @return true if fd/skt is in the set for this Poller object. - */ - public synchronized boolean isMember(Object fdObj) throws Exception { - return (nativeIsMember(handle,findfd(fdObj)) == 1); - } - /** - * Wait on Multiple IO Objects. - * - * @param maxRet the maximum number of fds[] and revents[] to return. - * @param fds[] (return) an array of ints in which to store fds with - * available data upon a successful non-timeout return. - * fds.length must be >= maxRet - * @param revents[] (return) the actual events available on the - * same-indexed fds[] (i.e. fds[0] has events revents[0]) - * revents.length must be >= maxRet - * - * Note : both above arrays are "dense," i.e. only fds[] with events - * available are returned. - * - * @param timeout the maximum number of milliseconds to wait for - * events before timing out. - * @return the number of fds with triggered events. - * - * Note : convenience methods exist for skipping the timeout parameter - * or the maxRet parameter (in the case of no maxRet, fds.length - * must equal revents.length) - * - * obj.waitMultiple(null,null,timeout) can be used for pausing the LWP - * (much more reliable and scalable than Thread.sleep() or Object.wait()) - */ - public synchronized int waitMultiple(int maxRet, int[] fds,short[] revents, - long timeout) throws Exception - { - if ((revents == null) || (fds == null)) { - if (maxRet > 0) { - throw new NullPointerException("fds or revents is null"); - } - } else if ( (maxRet < 0) || - (maxRet > revents.length) || (maxRet > fds.length) ) { - throw new IllegalArgumentException("maxRet out of range"); - } - - int ret = nativeWait(handle, maxRet, fds, revents, timeout); - if (ret < 0) { - throw new InterruptedIOException(); - } - return ret; - } - - /** - * Wait on Multiple IO Objects (no timeout). - * A convenience method for waiting indefinitely on IO events - * - * @see Poller#waitMultiple - * - */ - public int waitMultiple(int maxRet, int[] fds, short[] revents) - throws Exception - { - return waitMultiple(maxRet, fds, revents,-1L); // already synchronized - } - - /** - * Wait on Multiple IO Objects (no maxRet). - * A convenience method for waiting on IO events when the fds - * and revents arrays are the same length and that specifies the - * maximum number of return events. - * - * @see Poller#waitMultiple - * - */ - public synchronized int waitMultiple(int[] fds, short[] revents, - long timeout) throws Exception - { - if ((revents == null) && (fds == null)) { - return nativeWait(handle,0,null,null,timeout); - } else if ((revents == null) || (fds == null)) { - throw new NullPointerException("revents or fds is null"); - } else if (fds.length == revents.length) { - return nativeWait(handle, fds.length, fds, revents, timeout); - } - throw new IllegalArgumentException("fds.length != revents.length"); - } - - - /** - * Wait on Multiple IO Objects (no maxRet/timeout). - * A convenience method for waiting on IO events when the fds - * and revents arrays are the same length and that specifies the - * maximum number of return events, and when waiting indefinitely - * for IO events to occur. - * - * @see Poller#waitMultiple - * - */ - public int waitMultiple(int[] fds, short[] revents) - throws Exception - { - if ((revents == null) || (fds == null)) { - throw new NullPointerException("fds or revents is null"); - } else if (fds.length == revents.length) { - return waitMultiple(revents.length,fds,revents,-1L); // already sync - } - throw new IllegalArgumentException("fds.length != revents.length"); - } - - // Utility - get (int) fd from FileDescriptor or [Server]Socket objects. - - private int findfd(Object fdObj) throws Exception { - Class cl; - Field f; - Object val, implVal; - - if ((fdObj instanceof java.net.Socket) || - (fdObj instanceof java.net.ServerSocket)) { - cl = fdObj.getClass(); - f = cl.getDeclaredField("impl"); - f.setAccessible(true); - val = f.get(fdObj); - cl = f.getType(); - f = cl.getDeclaredField("fd"); - f.setAccessible(true); - implVal = f.get(val); - cl = f.getType(); - f = cl.getDeclaredField("fd"); - f.setAccessible(true); - return ((Integer) f.get(implVal)).intValue(); - } else if ( fdObj instanceof java.io.FileDescriptor ) { - cl = fdObj.getClass(); - f = cl.getDeclaredField("fd"); - f.setAccessible(true); - return ((Integer) f.get(fdObj)).intValue(); - } - else { - throw new IllegalArgumentException("Illegal Object type."); - } - } - - // Actual NATIVE calls - - private static native int nativeInit(); - private native int nativeCreatePoller(int maxFd) throws Exception; - private native void nativeDestroyPoller(int handle) throws Exception; - private native int nativeAddFd(int handle, int fd, short events) - throws Exception; - private native int nativeRemoveFd(int handle, int fd) throws Exception; - private native int nativeRemoveIndex(int handle, int index) - throws Exception; - private native int nativeIsMember(int handle, int fd) throws Exception; - private native int nativeWait(int handle, int maxRet, int[] fds, - short[] events, long timeout) - throws Exception; - /** - * Get number of active CPUs in this machine - * to determine proper level of concurrency. - */ - public static native int getNumCPUs(); - - static { - System.loadLibrary("poller"); - nativeInit(); - } -} diff --git a/jdk/src/demo/solaris/jni/Poller/PollingServer.java b/jdk/src/demo/solaris/jni/Poller/PollingServer.java deleted file mode 100644 index 5cb26260398..00000000000 --- a/jdk/src/demo/solaris/jni/Poller/PollingServer.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -import java.io.*; -import java.net.*; -import java.lang.Byte; - -/** - * Simple Java "server" using the Poller class - * to multiplex on incoming connections. Note - * that handoff of events, via linked Q is not - * actually be a performance booster here, since - * the processing of events is cheaper than - * the overhead in scheduling/executing them. - * Although this demo does allow for concurrency - * in handling connections, it uses a rather - * primitive "gang scheduling" policy to keep - * the code simpler. - */ - -public class PollingServer -{ - public final static int MAXCONN = 10000; - public final static int PORTNUM = 4444; - public final static int BYTESPEROP = 10; - - /** - * This synchronization object protects access to certain - * data (bytesRead,eventsToProcess) by concurrent Consumer threads. - */ - private final static Object eventSync = new Object(); - - private static InputStream[] instr = new InputStream[MAXCONN]; - private static int[] mapping = new int[65535]; - private static LinkedQueue linkedQ = new LinkedQueue(); - private static int bytesRead = 0; - private static int bytesToRead; - private static int eventsToProcess=0; - - public PollingServer(int concurrency) { - Socket[] sockArr = new Socket[MAXCONN]; - long timestart, timestop; - short[] revents = new short[MAXCONN]; - int[] fds = new int[MAXCONN]; - int bytes; - Poller Mux; - int serverFd; - int totalConn=0; - int connects=0; - - System.out.println ("Serv: Initializing port " + PORTNUM); - try { - - ServerSocket skMain = new ServerSocket (PORTNUM); - /* - * Create the Poller object Mux, allow for up to MAXCONN - * sockets/filedescriptors to be polled. - */ - Mux = new Poller(MAXCONN); - serverFd = Mux.add(skMain, Poller.POLLIN); - - Socket ctrlSock = skMain.accept(); - - BufferedReader ctrlReader = - new BufferedReader(new InputStreamReader(ctrlSock.getInputStream())); - String ctrlString = ctrlReader.readLine(); - bytesToRead = Integer.valueOf(ctrlString).intValue(); - ctrlString = ctrlReader.readLine(); - totalConn = Integer.valueOf(ctrlString).intValue(); - - System.out.println("Receiving " + bytesToRead + " bytes from " + - totalConn + " client connections"); - - timestart = System.currentTimeMillis(); - - /* - * Start the consumer threads to read data. - */ - for (int consumerThread = 0; - consumerThread < concurrency; consumerThread++ ) { - new Consumer(consumerThread).start(); - } - - /* - * Take connections, read Data - */ - int numEvents=0; - - while ( bytesRead < bytesToRead ) { - - int loopWaits=0; - while (eventsToProcess > 0) { - synchronized (eventSync) { - loopWaits++; - if (eventsToProcess <= 0) break; - try { eventSync.wait(); } catch (Exception e) {e.printStackTrace();}; - } - } - if (loopWaits > 1) - System.out.println("Done waiting...loops = " + loopWaits + - " events " + numEvents + - " bytes read : " + bytesRead ); - - if (bytesRead >= bytesToRead) break; // may be done! - - /* - * Wait for events - */ - numEvents = Mux.waitMultiple(100, fds, revents); - synchronized (eventSync) { - eventsToProcess = numEvents; - } - /* - * Process all the events we got from Mux.waitMultiple - */ - int cnt = 0; - while ( (cnt < numEvents) && (bytesRead < bytesToRead) ) { - int fd = fds[cnt]; - - if (revents[cnt] == Poller.POLLIN) { - if (fd == serverFd) { - /* - * New connection coming in on the ServerSocket - * Add the socket to the Mux, keep track of mapping - * the fdval returned by Mux.add to the connection. - */ - sockArr[connects] = skMain.accept(); - instr[connects] = sockArr[connects].getInputStream(); - int fdval = Mux.add(sockArr[connects], Poller.POLLIN); - mapping[fdval] = connects; - synchronized(eventSync) { - eventsToProcess--; // just processed this one! - } - connects++; - } else { - /* - * We've got data from this client connection. - * Put it on the queue for the consumer threads to process. - */ - linkedQ.put(new Integer(fd)); - } - } else { - System.out.println("Got revents[" + cnt + "] == " + revents[cnt]); - } - cnt++; - } - } - timestop = System.currentTimeMillis(); - System.out.println("Time for all reads (" + totalConn + - " sockets) : " + (timestop-timestart)); - - // Tell the client it can now go away - byte[] buff = new byte[BYTESPEROP]; - ctrlSock.getOutputStream().write(buff,0,BYTESPEROP); - - // Tell the cunsumer threads they can exit. - for (int cThread = 0; cThread < concurrency; cThread++ ) { - linkedQ.put(new Integer(-1)); - } - } catch (Exception exc) { exc.printStackTrace(); } - } - - /* - * main ... just check if a concurrency was specified - */ - public static void main (String args[]) - { - int concurrency; - - if (args.length == 1) - concurrency = java.lang.Integer.valueOf(args[0]).intValue(); - else - concurrency = Poller.getNumCPUs() + 1; - PollingServer server = new PollingServer(concurrency); - } - - /* - * This class is for handling the Client data. - * The PollingServer spawns off a number of these based upon - * the number of CPUs (or concurrency argument). - * Each just loops grabbing events off the queue and - * processing them. - */ - class Consumer extends Thread { - private int threadNumber; - public Consumer(int i) { threadNumber = i; } - - public void run() { - byte[] buff = new byte[BYTESPEROP]; - int bytes = 0; - - InputStream instream; - while (bytesRead < bytesToRead) { - try { - Integer Fd = (Integer) linkedQ.take(); - int fd = Fd.intValue(); - if (fd == -1) break; /* got told we could exit */ - - /* - * We have to map the fd value returned from waitMultiple - * to the actual input stream associated with that fd. - * Take a look at how the Mux.add() was done to see how - * we stored that. - */ - int map = mapping[fd]; - instream = instr[map]; - bytes = instream.read(buff,0,BYTESPEROP); - } catch (Exception e) { System.out.println(e.toString()); } - - if (bytes > 0) { - /* - * Any real server would do some synchronized and some - * unsynchronized work on behalf of the client, and - * most likely send some data back...but this is a - * gross oversimplification. - */ - synchronized(eventSync) { - bytesRead += bytes; - eventsToProcess--; - if (eventsToProcess <= 0) { - eventSync.notify(); - } - } - } - } - } - } -} diff --git a/jdk/src/demo/solaris/jni/Poller/README.txt b/jdk/src/demo/solaris/jni/Poller/README.txt deleted file mode 100644 index d665c221e8b..00000000000 --- a/jdk/src/demo/solaris/jni/Poller/README.txt +++ /dev/null @@ -1,174 +0,0 @@ -README.txt - - -This Poller class demonstrates access to poll(2) functionality in Java. - -Requires Solaris production (native threads) JDK 1.2 or later, currently -the C code compiles only on Solaris (SPARC and Intel). - -Poller.java is the class, Poller.c is the supporting JNI code. - -PollingServer.java is a sample application which uses the Poller class -to multiplex sockets. - -SimpleServer.java is the functional equivalent that does not multiplex -but uses a single thread to handle each client connection. - -Client.java is a sample application to drive against either server. - -To build the Poller class and client/server demo : - javac PollingServer.java Client.java - javah Poller - cc -G -o libpoller.so -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/solaris\ - Poller.c - -You will need to set the environment variable LD_LIBRARY_PATH to search -the directory containing libpoller.so. - -To use client/server, bump up your fd limit to handle the connections you -want (need root access to go beyond 1024). For info on changing your file -descriptor limit, type "man limit". If you are using Solaris 2.6 -or later, a regression in loopback read() performance may hit you at low -numbers of connections, so run the client on another machine. - -BASICs of Poller class usage : - run "javadoc Poller" or see Poller.java for more details. - -{ - Poller Mux = new Poller(65535); // allow it to contain 64K IO objects - - int fd1 = Mux.add(socket1, Poller.POLLIN); - ... - int fdN = Mux.add(socketN, Poller.POLLIN); - - int[] fds = new int[100]; - short[] revents = new revents[100]; - - int numEvents = Mux.waitMultiple(100, fds, revents, timeout); - - for (int i = 0; i < numEvents; i++) { - /* - * Probably need more sophisticated mapping scheme than this! - */ - if (fds[i] == fd1) { - System.out.println("Got data on socket1"); - socket1.getInputStream().read(byteArray); - // Do something based upon state of fd1 connection - } - ... - } -} - -Poller class implementation notes : - - Currently all add(),remove(),isMember(), and waitMultiple() methods -are synchronized for each Poller object. If one thread is blocked in -pObj.waitMultiple(), another thread calling pObj.add(fd) will block -until waitMultiple() returns. There is no provided mechanism to -interrupt waitMultiple(), as one might expect a ServerSocket to be in -the list waited on (see PollingServer.java). - - One might also need to interrupt waitMultiple() to remove() -fds/sockets, in which case one could create a Pipe or loopback localhost -connection (at the level of PollingServer) and use a write() to that -connection to interrupt. Or, better, one could queue up deletions -until the next return of waitMultiple(). Or one could implement an -interrupt mechanism in the JNI C code using a pipe(), and expose that -at the Java level. - - If frequent deletions/re-additions of socks/fds is to be done with -very large sets of monitored fds, the Solaris 7 kernel cache will -likely perform poorly without some tuning. One could differentiate -between deleted (no longer cared for) fds/socks and those that are -merely being disabled while data is processed on their behalf. In -that case, re-enabling a disabled fd/sock could put it in it's -original position in the poll array, thereby increasing the kernel -cache performance. This would best be done in Poller.c. Of course -this is not necessary for optimal /dev/poll performance. - - Caution...the next paragraph gets a little technical for the -benefit of those who already understand poll()ing fairly well. Others -may choose to skip over it to read notes on the demo server. - - An optimal solution for frequent enabling/disabling of socks/fds -could involve a separately synchronized structure of "async" -operations. Using a simple array (0..64k) containing the action -(ADD,ENABLE,DISABLE, NONE), the events, and the index into the poll -array, and having nativeWait() wake up in the poll() call periodically -to process these async operations, I was able to speed up performance -of the PollingServer by a factor of 2x at 8000 connections. Of course -much of that gain was from the fact that I could (with the advent of -an asyncAdd() method) move the accept() loop into a separate thread -from the main poll() loop, and avoid the overhead of calling poll() -with up to 7999 fds just for an accept. In implementing the async -Disable/Enable, a further large optimization was to auto-disable fds -with events available (before return from nativeWait()), so I could -just call asyncEnable(fd) after processing (read()ing) the available -data. This removed the need for inefficient gang-scheduling the -attached PollingServer uses. In order to separately synchronize the -async structure, yet still be able to operate on it from within -nativeWait(), synchronization had to be done at the C level here. Due -to the new complexities this introduced, as well as the fact that it -was tuned specifically for Solaris 7 poll() improvements (not -/dev/poll), this extra logic was left out of this demo. - - -Client/Server Demo Notes : - - Do not run the sample client/server with high numbers of connections -unless you have a lot of free memory on your machine, as it can saturate -CPU and lock you out of CDE just by its very resource intensive nature -(much more so the SimpleServer than PollingServer). - - Different OS versions will behave very differently as far as poll() -performance (or /dev/poll existence) but, generally, real world applications -"hit the wall" much earlier when a separate thread is used to handle -each client connection. Issues of thread synchronization and locking -granularity become performance killers. There is some overhead associated -with multiplexing, such as keeping track of the state of each connection; as -the number of connections gets very large, however, this overhead is more -than made up for by the reduced synchronization overhead. - - As an example, running the servers on a Solaris 7 PC (Pentium II-350 x -2 CPUS) with 1 GB RAM, and the client on an Ultra-2, I got the following -times (shorter is better) : - - 1000 connections : - -PollingServer took 11 seconds -SimpleServer took 12 seconds - - 4000 connections : - -PollingServer took 20 seconds -SimpleServer took 37 seconds - - 8000 connections : - -PollingServer took 39 seconds -SimpleServer took 1:48 seconds - - This demo is not, however, meant to be considered some form of proof -that multiplexing with the Poller class will gain you performance; this -code is actually very heavily biased towards the non-polling server as -very little synchronization is done, and most of the overhead is in the -kernel IO for both servers. Use of multiplexing may be helpful in -many, but certainly not all, circumstances. - - Benchmarking a major Java server application which can run -in a single-thread-per-client mode or using the new Poller class showed -Poller provided a 253% improvement in throughput at a moderate load, as -well as a 300% improvement in peak capacity. It also yielded a 21% -smaller memory footprint at the lower load level. - - Finally, there is code in Poller.c to take advantage of /dev/poll -on OS versions that have that device; however, DEVPOLL must be defined -in compiling Poller.c (and it must be compiled on a machine with -/usr/include/sys/devpoll.h) to use it. Code compiled with DEVPOLL -turned on will work on machines that don't have kernel support for -the device, as it will fall back to using poll() in those cases. -Currently /dev/poll does not correctly return an error if you attempt -to remove() an object that was never added, but this should be fixed -in an upcoming /dev/poll patch. The binary as shipped is not built with -/dev/poll support as our build machine does not have devpoll.h. - diff --git a/jdk/src/demo/solaris/jni/Poller/SimpleServer.java b/jdk/src/demo/solaris/jni/Poller/SimpleServer.java deleted file mode 100644 index 6a099c67071..00000000000 --- a/jdk/src/demo/solaris/jni/Poller/SimpleServer.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -import java.io.*; -import java.net.*; -import java.lang.Byte; - -/** - * Simple Java "server" using a single thread to handle each connection. - */ - -public class SimpleServer -{ - private final static int BYTESPEROP= PollingServer.BYTESPEROP; - private final static int PORTNUM = PollingServer.PORTNUM; - private final static int MAXCONN = PollingServer.MAXCONN; - - /* - * This synchronization object protects access to certain - * data (bytesRead,eventsToProcess) by concurrent Consumer threads. - */ - private final static Object eventSync = new Object(); - - private static InputStream[] instr = new InputStream[MAXCONN]; - private static int bytesRead; - private static int bytesToRead; - - public SimpleServer() { - Socket[] sockArr = new Socket[MAXCONN]; - long timestart, timestop; - int bytes; - int totalConn=0; - - - System.out.println ("Serv: Initializing port " + PORTNUM); - try { - - ServerSocket skMain = new ServerSocket (PORTNUM); - - bytesRead = 0; - Socket ctrlSock = skMain.accept(); - - BufferedReader ctrlReader = - new BufferedReader(new InputStreamReader(ctrlSock.getInputStream())); - String ctrlString = ctrlReader.readLine(); - bytesToRead = Integer.valueOf(ctrlString).intValue(); - ctrlString = ctrlReader.readLine(); - totalConn = Integer.valueOf(ctrlString).intValue(); - - System.out.println("Receiving " + bytesToRead + " bytes from " + - totalConn + " client connections"); - - timestart = System.currentTimeMillis(); - - /* - * Take connections, spawn off connection handling threads - */ - ConnHandler[] connHA = new ConnHandler[MAXCONN]; - int conn = 0; - while ( conn < totalConn ) { - Socket sock = skMain.accept(); - connHA[conn] = new ConnHandler(sock.getInputStream()); - connHA[conn].start(); - conn++; - } - - while ( bytesRead < bytesToRead ) { - java.lang.Thread.sleep(500); - } - timestop = System.currentTimeMillis(); - System.out.println("Time for all reads (" + totalConn + - " sockets) : " + (timestop-timestart)); - // Tell the client it can now go away - byte[] buff = new byte[BYTESPEROP]; - ctrlSock.getOutputStream().write(buff,0,BYTESPEROP); - } catch (Exception exc) { exc.printStackTrace(); } - } - - /* - * main ... just create invoke the SimpleServer constructor. - */ - public static void main (String args[]) - { - SimpleServer server = new SimpleServer(); - } - - /* - * Connection Handler inner class...one of these per client connection. - */ - class ConnHandler extends Thread { - private InputStream instr; - public ConnHandler(InputStream inputStr) { instr = inputStr; } - - public void run() { - try { - int bytes; - byte[] buff = new byte[BYTESPEROP]; - - while ( bytesRead < bytesToRead ) { - bytes = instr.read (buff, 0, BYTESPEROP); - if (bytes > 0 ) { - synchronized(eventSync) { - bytesRead += bytes; - } - /* - * Any real server would do some synchronized and some - * unsynchronized work on behalf of the client, and - * most likely send some data back...but this is a - * gross oversimplification. - */ - } - else { - if (bytesRead < bytesToRead) - System.out.println("instr.read returned : " + bytes); - } - } - } - catch (Exception e) {e.printStackTrace();} - } - } -} diff --git a/jdk/src/java.base/macosx/native/launcher/Info-privileged.plist b/jdk/src/java.base/macosx/native/launcher/Info-privileged.plist index 776967ab384..9b2fc0a32fc 100644 --- a/jdk/src/java.base/macosx/native/launcher/Info-privileged.plist +++ b/jdk/src/java.base/macosx/native/launcher/Info-privileged.plist @@ -7,7 +7,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - OpenJDK 7 Command + OpenJDK Command CFBundleShortVersionString 1.0 CFBundleVersion diff --git a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java index 5c36b7fec01..15d735e88c3 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1797,12 +1797,19 @@ public class ObjectInputStream } catch (ClassNotFoundException ex) { resolveEx = ex; } + + // Call filterCheck on the class before reading anything else + filterCheck(cl, -1); + skipCustomData(); - desc.initProxy(cl, resolveEx, readClassDesc(false)); - - // Call filterCheck on the definition - filterCheck(desc.forClass(), -1); + try { + totalObjectRefs++; + depth++; + desc.initProxy(cl, resolveEx, readClassDesc(false)); + } finally { + depth--; + } handles.finish(descHandle); passHandle = descHandle; @@ -1847,12 +1854,19 @@ public class ObjectInputStream } catch (ClassNotFoundException ex) { resolveEx = ex; } + + // Call filterCheck on the class before reading anything else + filterCheck(cl, -1); + skipCustomData(); - desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); - - // Call filterCheck on the definition - filterCheck(desc.forClass(), -1); + try { + totalObjectRefs++; + depth++; + desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); + } finally { + depth--; + } handles.finish(descHandle); passHandle = descHandle; diff --git a/jdk/src/java.base/share/classes/java/lang/Comparable.java b/jdk/src/java.base/share/classes/java/lang/Comparable.java index b1c27f1911d..f9be4c440ca 100644 --- a/jdk/src/java.base/share/classes/java/lang/Comparable.java +++ b/jdk/src/java.base/share/classes/java/lang/Comparable.java @@ -84,7 +84,7 @@ import java.util.*; * {(x, y) such that x.equals(y)}.

* * This interface is a member of the - * + * * Java Collections Framework. * * @param the type of objects that this object may be compared to diff --git a/jdk/src/java.base/share/classes/java/lang/UnsupportedOperationException.java b/jdk/src/java.base/share/classes/java/lang/UnsupportedOperationException.java index 2d9c7a00cbf..eebc580e6f1 100644 --- a/jdk/src/java.base/share/classes/java/lang/UnsupportedOperationException.java +++ b/jdk/src/java.base/share/classes/java/lang/UnsupportedOperationException.java @@ -29,7 +29,7 @@ package java.lang; * Thrown to indicate that the requested operation is not supported.

* * This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java index d66fe1a0c34..5125e7cb553 100644 --- a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java +++ b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java @@ -143,8 +143,10 @@ public abstract class Reference { /* * system property to disable clearing before enqueuing. */ - private static final boolean disableClearBeforeEnqueue - = Boolean.getBoolean("jdk.lang.ref.disableClearBeforeEnqueue"); + private static final class ClearBeforeEnqueue { + static final boolean DISABLE = + Boolean.getBoolean("jdk.lang.ref.disableClearBeforeEnqueue"); + } /* * Atomically get and clear (set to null) the VM's pending list. @@ -297,7 +299,7 @@ public abstract class Reference { * it was not registered with a queue when it was created */ public boolean enqueue() { - if (!disableClearBeforeEnqueue) + if (!ClearBeforeEnqueue.DISABLE) this.referent = null; return this.queue.enqueue(this); } diff --git a/jdk/src/java.base/share/classes/java/net/SocketPermission.java b/jdk/src/java.base/share/classes/java/net/SocketPermission.java index b1a94154af0..a7eec857cbc 100644 --- a/jdk/src/java.base/share/classes/java/net/SocketPermission.java +++ b/jdk/src/java.base/share/classes/java/net/SocketPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, 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 @@ -44,8 +44,8 @@ import java.util.StringJoiner; import java.util.StringTokenizer; import java.util.concurrent.ConcurrentSkipListMap; import sun.net.util.IPAddressUtil; -import sun.net.RegisteredDomain; import sun.net.PortConfig; +import sun.security.util.RegisteredDomain; import sun.security.util.SecurityConstants; import sun.security.util.Debug; @@ -678,13 +678,18 @@ public final class SocketPermission extends Permission String a = cname.toLowerCase(); String b = hname.toLowerCase(); if (a.startsWith(b) && - ((a.length() == b.length()) || (a.charAt(b.length()) == '.'))) + ((a.length() == b.length()) || (a.charAt(b.length()) == '.'))) { return true; + } if (cdomain == null) { - cdomain = RegisteredDomain.getRegisteredDomain(a); + cdomain = RegisteredDomain.from(a) + .map(RegisteredDomain::name) + .orElse(a); } if (hdomain == null) { - hdomain = RegisteredDomain.getRegisteredDomain(b); + hdomain = RegisteredDomain.from(b) + .map(RegisteredDomain::name) + .orElse(b); } return cdomain.length() != 0 && hdomain.length() != 0 diff --git a/jdk/src/java.base/share/classes/java/util/AbstractCollection.java b/jdk/src/java.base/share/classes/java/util/AbstractCollection.java index 6f344f8befe..9845c0f031b 100644 --- a/jdk/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/jdk/src/java.base/share/classes/java/util/AbstractCollection.java @@ -49,7 +49,7 @@ package java.util; * the collection being implemented admits a more efficient implementation.

* * This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/AbstractList.java b/jdk/src/java.base/share/classes/java/util/AbstractList.java index c8c160de6a4..6d819368a24 100644 --- a/jdk/src/java.base/share/classes/java/util/AbstractList.java +++ b/jdk/src/java.base/share/classes/java/util/AbstractList.java @@ -62,7 +62,7 @@ import java.util.function.Consumer; * collection being implemented admits a more efficient implementation. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/AbstractMap.java b/jdk/src/java.base/share/classes/java/util/AbstractMap.java index 0b76ddd76b1..ed39bcacbca 100644 --- a/jdk/src/java.base/share/classes/java/util/AbstractMap.java +++ b/jdk/src/java.base/share/classes/java/util/AbstractMap.java @@ -52,7 +52,7 @@ import java.util.Map.Entry; * map being implemented admits a more efficient implementation. * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of keys maintained by this map diff --git a/jdk/src/java.base/share/classes/java/util/AbstractQueue.java b/jdk/src/java.base/share/classes/java/util/AbstractQueue.java index 6c1442b09f6..789151642d6 100644 --- a/jdk/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/jdk/src/java.base/share/classes/java/util/AbstractQueue.java @@ -54,7 +54,7 @@ package java.util; * instead subclassing {@link AbstractCollection}. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/AbstractSequentialList.java b/jdk/src/java.base/share/classes/java/util/AbstractSequentialList.java index bd6736ba63c..0e7cb01938a 100644 --- a/jdk/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/jdk/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -54,7 +54,7 @@ package java.util; * specification.

* * This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/AbstractSet.java b/jdk/src/java.base/share/classes/java/util/AbstractSet.java index 35e2ba4ec99..534ef775db1 100644 --- a/jdk/src/java.base/share/classes/java/util/AbstractSet.java +++ b/jdk/src/java.base/share/classes/java/util/AbstractSet.java @@ -42,7 +42,7 @@ package java.util; * for {@code equals} and {@code hashCode}.

* * This class is a member of the - * + * * Java Collections Framework. * * @param the type of elements maintained by this set diff --git a/jdk/src/java.base/share/classes/java/util/ArrayDeque.java b/jdk/src/java.base/share/classes/java/util/ArrayDeque.java index de78bdc9e9a..53cdeffa846 100644 --- a/jdk/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/jdk/src/java.base/share/classes/java/util/ArrayDeque.java @@ -79,7 +79,7 @@ import java.util.function.UnaryOperator; * Iterator} interfaces. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch and Doug Lea diff --git a/jdk/src/java.base/share/classes/java/util/ArrayList.java b/jdk/src/java.base/share/classes/java/util/ArrayList.java index dbaa725dacb..f63ef493dc0 100644 --- a/jdk/src/java.base/share/classes/java/util/ArrayList.java +++ b/jdk/src/java.base/share/classes/java/util/ArrayList.java @@ -91,7 +91,7 @@ import java.util.function.UnaryOperator; * should be used only to detect bugs. * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of elements in this list diff --git a/jdk/src/java.base/share/classes/java/util/Arrays.java b/jdk/src/java.base/share/classes/java/util/Arrays.java index 6d7e858fbed..e1571cc613f 100644 --- a/jdk/src/java.base/share/classes/java/util/Arrays.java +++ b/jdk/src/java.base/share/classes/java/util/Arrays.java @@ -62,7 +62,7 @@ import java.util.stream.StreamSupport; * a MergeSort, but it does have to be stable.) * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch @@ -8899,4 +8899,4 @@ public class Arrays { return aLength != bLength ? length : -1; } -} \ No newline at end of file +} diff --git a/jdk/src/java.base/share/classes/java/util/Collection.java b/jdk/src/java.base/share/classes/java/util/Collection.java index f92b9f6153f..a1fc025c89f 100644 --- a/jdk/src/java.base/share/classes/java/util/Collection.java +++ b/jdk/src/java.base/share/classes/java/util/Collection.java @@ -112,7 +112,7 @@ import java.util.stream.StreamSupport; * however most current implementations do not do so. * *

This interface is a member of the - * + * * Java Collections Framework. * * @implSpec diff --git a/jdk/src/java.base/share/classes/java/util/Collections.java b/jdk/src/java.base/share/classes/java/util/Collections.java index 22b4557ae2f..8aa9c53c455 100644 --- a/jdk/src/java.base/share/classes/java/util/Collections.java +++ b/jdk/src/java.base/share/classes/java/util/Collections.java @@ -65,7 +65,7 @@ import java.util.stream.StreamSupport; * already sorted may or may not throw {@code UnsupportedOperationException}. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/Comparator.java b/jdk/src/java.base/share/classes/java/util/Comparator.java index 85f25beaf63..1e95e6279bb 100644 --- a/jdk/src/java.base/share/classes/java/util/Comparator.java +++ b/jdk/src/java.base/share/classes/java/util/Comparator.java @@ -94,7 +94,7 @@ import java.util.Comparators; * an equivalence relation. * *

This interface is a member of the - * + * * Java Collections Framework. * * @param the type of objects that may be compared by this comparator diff --git a/jdk/src/java.base/share/classes/java/util/Deque.java b/jdk/src/java.base/share/classes/java/util/Deque.java index 2714373fe63..5ff6e03ed70 100644 --- a/jdk/src/java.base/share/classes/java/util/Deque.java +++ b/jdk/src/java.base/share/classes/java/util/Deque.java @@ -181,9 +181,9 @@ package java.util; * methods, but instead inherit the identity-based versions from class * {@code Object}. * - *

This interface is a member of the Java Collections - * Framework. + *

This interface is a member of the + * + * Java Collections Framework. * * @author Doug Lea * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/EnumMap.java b/jdk/src/java.base/share/classes/java/util/EnumMap.java index e6d63cf4ae8..3eff9a6fd3a 100644 --- a/jdk/src/java.base/share/classes/java/util/EnumMap.java +++ b/jdk/src/java.base/share/classes/java/util/EnumMap.java @@ -68,7 +68,7 @@ import jdk.internal.misc.SharedSecrets; * {@link HashMap} counterparts. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/EnumSet.java b/jdk/src/java.base/share/classes/java/util/EnumSet.java index 0ca61870976..0adeab410b0 100644 --- a/jdk/src/java.base/share/classes/java/util/EnumSet.java +++ b/jdk/src/java.base/share/classes/java/util/EnumSet.java @@ -69,7 +69,7 @@ import jdk.internal.misc.SharedSecrets; * constant time if their argument is also an enum set. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/HashMap.java b/jdk/src/java.base/share/classes/java/util/HashMap.java index 5cc36296aa8..4f0e8e6c7d6 100644 --- a/jdk/src/java.base/share/classes/java/util/HashMap.java +++ b/jdk/src/java.base/share/classes/java/util/HashMap.java @@ -117,7 +117,7 @@ import java.util.function.Function; * should be used only to detect bugs. * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of keys maintained by this map diff --git a/jdk/src/java.base/share/classes/java/util/HashSet.java b/jdk/src/java.base/share/classes/java/util/HashSet.java index 172cb37ad06..360de8119d6 100644 --- a/jdk/src/java.base/share/classes/java/util/HashSet.java +++ b/jdk/src/java.base/share/classes/java/util/HashSet.java @@ -72,7 +72,7 @@ import java.io.InvalidObjectException; * should be used only to detect bugs. * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of elements maintained by this set diff --git a/jdk/src/java.base/share/classes/java/util/Hashtable.java b/jdk/src/java.base/share/classes/java/util/Hashtable.java index b541ca12a06..f97303be2b3 100644 --- a/jdk/src/java.base/share/classes/java/util/Hashtable.java +++ b/jdk/src/java.base/share/classes/java/util/Hashtable.java @@ -106,7 +106,7 @@ import java.util.function.BiFunction; * *

As of the Java 2 platform v1.2, this class was retrofitted to * implement the {@link Map} interface, making it a member of the - * + * * * Java Collections Framework. Unlike the new collection * implementations, {@code Hashtable} is synchronized. If a diff --git a/jdk/src/java.base/share/classes/java/util/IdentityHashMap.java b/jdk/src/java.base/share/classes/java/util/IdentityHashMap.java index bd1e217e7ff..f749774e78e 100644 --- a/jdk/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/jdk/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -122,7 +122,7 @@ import java.util.function.Consumer; * {@link HashMap} (which uses chaining rather than linear-probing). * *

This class is a member of the - * + * * Java Collections Framework. * * @see System#identityHashCode(Object) diff --git a/jdk/src/java.base/share/classes/java/util/Iterator.java b/jdk/src/java.base/share/classes/java/util/Iterator.java index a5d89293a2c..5f7b1de8b85 100644 --- a/jdk/src/java.base/share/classes/java/util/Iterator.java +++ b/jdk/src/java.base/share/classes/java/util/Iterator.java @@ -40,7 +40,7 @@ import java.util.function.Consumer; * * *

This interface is a member of the - * + * * Java Collections Framework. * * @apiNote diff --git a/jdk/src/java.base/share/classes/java/util/LinkedHashMap.java b/jdk/src/java.base/share/classes/java/util/LinkedHashMap.java index bd21f5bf6d4..252a5437353 100644 --- a/jdk/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/jdk/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -140,7 +140,7 @@ import java.io.IOException; * fail-fast, and additionally report {@link Spliterator#ORDERED}. * *

This class is a member of the - * + * * Java Collections Framework. * * @implNote diff --git a/jdk/src/java.base/share/classes/java/util/LinkedHashSet.java b/jdk/src/java.base/share/classes/java/util/LinkedHashSet.java index c0e1f2eb8e4..0d0f927166e 100644 --- a/jdk/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/jdk/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -100,7 +100,7 @@ package java.util; * should be used only to detect bugs. * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of elements maintained by this set diff --git a/jdk/src/java.base/share/classes/java/util/LinkedList.java b/jdk/src/java.base/share/classes/java/util/LinkedList.java index 2d21ff145c3..fce19cad553 100644 --- a/jdk/src/java.base/share/classes/java/util/LinkedList.java +++ b/jdk/src/java.base/share/classes/java/util/LinkedList.java @@ -70,7 +70,7 @@ import java.util.function.Consumer; * should be used only to detect bugs. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/List.java b/jdk/src/java.base/share/classes/java/util/List.java index dda514b313f..c0a9b31ba2f 100644 --- a/jdk/src/java.base/share/classes/java/util/List.java +++ b/jdk/src/java.base/share/classes/java/util/List.java @@ -114,7 +114,7 @@ import java.util.function.UnaryOperator; * * *

This interface is a member of the - * + * * Java Collections Framework. * * @param the type of elements in this list diff --git a/jdk/src/java.base/share/classes/java/util/ListIterator.java b/jdk/src/java.base/share/classes/java/util/ListIterator.java index 6ad98fe3fa3..2ec555754ea 100644 --- a/jdk/src/java.base/share/classes/java/util/ListIterator.java +++ b/jdk/src/java.base/share/classes/java/util/ListIterator.java @@ -46,7 +46,7 @@ package java.util; * {@link #previous()}. * *

This interface is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch diff --git a/jdk/src/java.base/share/classes/java/util/Map.java b/jdk/src/java.base/share/classes/java/util/Map.java index 153b86b8084..9b03346a72e 100644 --- a/jdk/src/java.base/share/classes/java/util/Map.java +++ b/jdk/src/java.base/share/classes/java/util/Map.java @@ -140,7 +140,7 @@ import java.io.Serializable; * * *

This interface is a member of the - * + * * Java Collections Framework. * * @param the type of keys maintained by this map diff --git a/jdk/src/java.base/share/classes/java/util/NavigableMap.java b/jdk/src/java.base/share/classes/java/util/NavigableMap.java index 6045ee2b48f..8a2af7a7a2a 100644 --- a/jdk/src/java.base/share/classes/java/util/NavigableMap.java +++ b/jdk/src/java.base/share/classes/java/util/NavigableMap.java @@ -85,7 +85,7 @@ package java.util; * {@link #keySet()} can be overridden to return {@link NavigableSet}. * *

This interface is a member of the - * + * * Java Collections Framework. * * @author Doug Lea diff --git a/jdk/src/java.base/share/classes/java/util/NavigableSet.java b/jdk/src/java.base/share/classes/java/util/NavigableSet.java index 40843905271..4f1f0d510a9 100644 --- a/jdk/src/java.base/share/classes/java/util/NavigableSet.java +++ b/jdk/src/java.base/share/classes/java/util/NavigableSet.java @@ -79,7 +79,7 @@ package java.util; * {@code NavigableSet}. * *

This interface is a member of the - * + * * Java Collections Framework. * * @author Doug Lea diff --git a/jdk/src/java.base/share/classes/java/util/PriorityQueue.java b/jdk/src/java.base/share/classes/java/util/PriorityQueue.java index 829eb01efea..28111ae16bf 100644 --- a/jdk/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/jdk/src/java.base/share/classes/java/util/PriorityQueue.java @@ -73,7 +73,7 @@ import java.util.function.Consumer; * ({@code peek}, {@code element}, and {@code size}). * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/Queue.java b/jdk/src/java.base/share/classes/java/util/Queue.java index e94b22c7fb2..1a46d9e723c 100644 --- a/jdk/src/java.base/share/classes/java/util/Queue.java +++ b/jdk/src/java.base/share/classes/java/util/Queue.java @@ -125,7 +125,7 @@ package java.util; * ordering properties. * *

This interface is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/RandomAccess.java b/jdk/src/java.base/share/classes/java/util/RandomAccess.java index a4d489313de..09793e633f6 100644 --- a/jdk/src/java.base/share/classes/java/util/RandomAccess.java +++ b/jdk/src/java.base/share/classes/java/util/RandomAccess.java @@ -59,7 +59,7 @@ package java.util; * * *

This interface is a member of the - * + * * Java Collections Framework. * * @since 1.4 diff --git a/jdk/src/java.base/share/classes/java/util/Set.java b/jdk/src/java.base/share/classes/java/util/Set.java index 2dd9060f7df..38be624cbef 100644 --- a/jdk/src/java.base/share/classes/java/util/Set.java +++ b/jdk/src/java.base/share/classes/java/util/Set.java @@ -91,7 +91,7 @@ package java.util; * * *

This interface is a member of the - * + * * Java Collections Framework. * * @param the type of elements maintained by this set diff --git a/jdk/src/java.base/share/classes/java/util/SortedMap.java b/jdk/src/java.base/share/classes/java/util/SortedMap.java index 7f98152253c..3a57088859b 100644 --- a/jdk/src/java.base/share/classes/java/util/SortedMap.java +++ b/jdk/src/java.base/share/classes/java/util/SortedMap.java @@ -93,7 +93,7 @@ package java.util; * SortedMap<String, V> sub = m.subMap(low+"\0", high); * *

This interface is a member of the - * + * * Java Collections Framework. * * @param the type of keys maintained by this map diff --git a/jdk/src/java.base/share/classes/java/util/SortedSet.java b/jdk/src/java.base/share/classes/java/util/SortedSet.java index 5eb7f76117d..e95a9775b61 100644 --- a/jdk/src/java.base/share/classes/java/util/SortedSet.java +++ b/jdk/src/java.base/share/classes/java/util/SortedSet.java @@ -89,7 +89,7 @@ package java.util; * SortedSet<String> sub = s.subSet(low+"\0", high); * *

This interface is a member of the - * + * * Java Collections Framework. * * @param the type of elements maintained by this set diff --git a/jdk/src/java.base/share/classes/java/util/TreeMap.java b/jdk/src/java.base/share/classes/java/util/TreeMap.java index 2da0a5e8b28..5051282a9c9 100644 --- a/jdk/src/java.base/share/classes/java/util/TreeMap.java +++ b/jdk/src/java.base/share/classes/java/util/TreeMap.java @@ -92,7 +92,7 @@ import java.util.function.Consumer; * associated map using {@code put}.) * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of keys maintained by this map diff --git a/jdk/src/java.base/share/classes/java/util/TreeSet.java b/jdk/src/java.base/share/classes/java/util/TreeSet.java index b80021e738e..8b110ef3b10 100644 --- a/jdk/src/java.base/share/classes/java/util/TreeSet.java +++ b/jdk/src/java.base/share/classes/java/util/TreeSet.java @@ -74,7 +74,7 @@ package java.util; * should be used only to detect bugs. * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of elements maintained by this set diff --git a/jdk/src/java.base/share/classes/java/util/Vector.java b/jdk/src/java.base/share/classes/java/util/Vector.java index fb6c938c226..fac073b1116 100644 --- a/jdk/src/java.base/share/classes/java/util/Vector.java +++ b/jdk/src/java.base/share/classes/java/util/Vector.java @@ -70,7 +70,7 @@ import java.util.function.UnaryOperator; * *

As of the Java 2 platform v1.2, this class was retrofitted to * implement the {@link List} interface, making it a member of the - * + * * Java Collections Framework. Unlike the new collection * implementations, {@code Vector} is synchronized. If a thread-safe * implementation is not needed, it is recommended to use {@link diff --git a/jdk/src/java.base/share/classes/java/util/WeakHashMap.java b/jdk/src/java.base/share/classes/java/util/WeakHashMap.java index 1aa8ec4396d..183b4c39729 100644 --- a/jdk/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/jdk/src/java.base/share/classes/java/util/WeakHashMap.java @@ -120,7 +120,7 @@ import java.util.function.Consumer; * should be used only to detect bugs. * *

This class is a member of the - * + * * Java Collections Framework. * * @param the type of keys maintained by this map diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java index 4e73c087ce4..557ce73a7a3 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -76,7 +76,7 @@ import java.util.function.Predicate; * methods of the {@link Collection} and {@link Iterator} interfaces. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java b/jdk/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java index 27b05bf711b..12b088bb6f7 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java @@ -193,7 +193,7 @@ import java.util.NoSuchElementException; * the {@code BlockingDeque} in another thread. * *

This interface is a member of the - * + * * Java Collections Framework. * * @since 1.6 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java index 03ca56d8791..7bae2ba0437 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java @@ -170,7 +170,7 @@ import java.util.Queue; * the {@code BlockingQueue} in another thread. * *

This interface is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 1d80077b58c..77c42efd6fd 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -254,7 +254,7 @@ import jdk.internal.misc.Unsafe; *

All arguments to all task methods must be non-null. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 58e16ae83b8..8546bfb3f46 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -85,7 +85,7 @@ import java.util.function.Predicate; * the {@code ConcurrentLinkedDeque} in another thread. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.7 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 6ce61b8f4ab..ac70f00bac6 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -99,7 +99,7 @@ import java.util.function.Predicate; * the {@code ConcurrentLinkedQueue} in another thread. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index d301de9eee6..0a5cda1d81f 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -61,7 +61,7 @@ import java.util.function.Function; * the {@code ConcurrentMap} in another thread. * *

This interface is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index 0d763b6e9ea..5040e2ec4af 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -43,7 +43,7 @@ import java.util.NavigableSet; * and recursively so for its navigable sub-maps. * *

This interface is a member of the - * + * * Java Collections Framework. * * @author Doug Lea diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 2ae29aa42f3..8be87529539 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -106,7 +106,7 @@ import java.util.function.Predicate; * elements. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Doug Lea diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 86be622c78b..d61fb2170cc 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -87,7 +87,7 @@ import java.util.Spliterator; * distinguished from the absence of elements. * *

This class is a member of the - * + * * Java Collections Framework. * * @author Doug Lea diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java index 63bd252868d..592f9a51cd2 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -82,7 +82,7 @@ import java.util.function.UnaryOperator; * the {@code CopyOnWriteArrayList} in another thread. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java index 6e4ad018d2f..c8e984fab96 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -87,7 +87,7 @@ import java.util.function.Predicate; * }} * *

This class is a member of the - * + * * Java Collections Framework. * * @see CopyOnWriteArrayList diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 50997f7abda..73d66b9e64c 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -67,7 +67,7 @@ import java.util.concurrent.locks.ReentrantLock; * particular order. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java index 1db30b3b440..ec7b7eee5ce 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -68,7 +68,7 @@ import java.util.function.Predicate; * methods of the {@link Collection} and {@link Iterator} interfaces. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.6 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java index 7a1a2138073..368f6014dfa 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -71,7 +71,7 @@ import java.util.function.Predicate; * methods of the {@link Collection} and {@link Iterator} interfaces. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 3a919c1efad..c7ad85b9fc1 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -81,7 +81,7 @@ import java.util.function.Predicate; * the {@code LinkedTransferQueue} in another thread. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.7 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index cdb1548eb61..8b0b3fec285 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -101,7 +101,7 @@ import java.util.function.Consumer; * }} * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index 165198f97f8..0a4049b6628 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -80,7 +80,7 @@ import java.util.concurrent.locks.ReentrantLock; * methods of the {@link Collection} and {@link Iterator} interfaces. * *

This class is a member of the - * + * * Java Collections Framework. * * @since 1.5 diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/TransferQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/TransferQueue.java index 43d8f0c1395..0621bce2b76 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/TransferQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/TransferQueue.java @@ -58,7 +58,7 @@ package java.util.concurrent; * and {@code transfer} are effectively synonymous. * *

This interface is a member of the - * + * * Java Collections Framework. * * @since 1.7 diff --git a/jdk/src/java.base/share/classes/java/util/package-info.java b/jdk/src/java.base/share/classes/java/util/package-info.java index ab706e0d179..e6406f14d3d 100644 --- a/jdk/src/java.base/share/classes/java/util/package-info.java +++ b/jdk/src/java.base/share/classes/java/util/package-info.java @@ -29,7 +29,7 @@ * miscellaneous utility classes (a string tokenizer, a random-number * generator, and a bit array). * - *

Package Specification

+ *

{@index "Java Collections Framework"}

*