# HG changeset patch # User sla # Date 1439204935 -7200 # Node ID fed421ad9b7037166a151c86a0d3c9d1becc2af6 # Parent 602c828cf7dcb16de5d2189fb113263e30fa1b1d 8076470: Remove the JVM TI hprof Agent Reviewed-by: sspitsyn, mchung, erikj diff -r 602c828cf7dc -r fed421ad9b70 jdk/make/copy/Copy-jdk.hprof.agent.gmk --- a/jdk/make/copy/Copy-jdk.hprof.agent.gmk Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -# -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -include CopyCommon.gmk - -################################################################################ - -HPROF_SRC := $(JDK_TOPDIR)/src/jdk.hprof.agent/share/native/libhprof/jvm.hprof.txt - -$(LIB_DST_DIR)/jvm.hprof.txt: $(HPROF_SRC) - $(call install-file) - -TARGETS := $(LIB_DST_DIR)/jvm.hprof.txt - -################################################################################ diff -r 602c828cf7dc -r fed421ad9b70 jdk/make/lib/Lib-jdk.hprof.agent.gmk --- a/jdk/make/lib/Lib-jdk.hprof.agent.gmk Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -# -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -include LibCommon.gmk - -################################################################################ - -BUILD_LIBHPROF_SRC := $(call FindSrcDirsForLib, jdk.hprof.agent, hprof) - -BUILD_LIBHPROF_CFLAGS := $(addprefix -I, $(BUILD_LIBHPROF_SRC)) \ - -I$(JDK_TOPDIR)/src/demo/share/jvmti/java_crw_demo - -BUILD_LIBHPROF_LDFLAGS := - -LIBHPROF_OPTIMIZATION := HIGHEST -ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) - ifeq ($(ENABLE_DEBUG_SYMBOLS), true) - LIBHPROF_OPTIMIZATION := LOW - endif -endif - -$(eval $(call SetupNativeCompilation,BUILD_LIBHPROF, \ - LIBRARY := hprof, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBHPROF_SRC), \ - OPTIMIZATION := $(LIBHPROF_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(BUILD_LIBHPROF_CFLAGS), \ - CFLAGS_debug := -DHPROF_LOGGING, \ - MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libhprof/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_windows := wsock32.lib winmm.lib advapi32.lib, \ - LDFLAGS_SUFFIX_linux := $(LIBDL), \ - LDFLAGS_SUFFIX_macosx := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lsocket -lnsl $(LIBDL) -lc, \ - VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=hprof.dll" \ - -D "JDK_INTERNAL_NAME=hprof" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libhprof_jvmti, \ - DEBUG_SYMBOLS := true)) - -TARGETS += $(BUILD_LIBHPROF) - -################################################################################ - -LIBJAVA_CRW_DEMO_SRC := $(JDK_TOPDIR)/src/demo/share/jvmti/java_crw_demo - -$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA_CRW_DEMO, \ - LIBRARY := java_crw_demo, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBJAVA_CRW_DEMO_SRC), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(addprefix -I, $(LIBJAVA_CRW_DEMO_SRC)), \ - MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjava_crw_demo/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=java_crw_demo.dll" \ - -D "JDK_INTERNAL_NAME=java_crw_demo" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava_crw_demo, \ - DEBUG_SYMBOLS := true)) - -TARGETS += $(BUILD_LIBJAVA_CRW_DEMO) - -################################################################################ diff -r 602c828cf7dc -r fed421ad9b70 jdk/make/mapfiles/libhprof/mapfile-vers --- a/jdk/make/mapfiles/libhprof/mapfile-vers Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -# -# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# Define public interface. - -SUNWprivate_1.1 { - global: - Agent_OnLoad; - Agent_OnUnload; - local: - *; -}; diff -r 602c828cf7dc -r fed421ad9b70 jdk/make/mapfiles/libjava_crw_demo/mapfile-vers --- a/jdk/make/mapfiles/libjava_crw_demo/mapfile-vers Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -# -# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# Define public interface. - -SUNWprivate_1.1 { - global: - java_crw_demo; - java_crw_demo_classname; - local: - *; -}; diff -r 602c828cf7dc -r fed421ad9b70 jdk/make/src/classes/build/tools/module/boot.modules --- a/jdk/make/src/classes/build/tools/module/boot.modules Wed Aug 05 03:43:31 2015 +0200 +++ b/jdk/make/src/classes/build/tools/module/boot.modules Mon Aug 10 13:08:55 2015 +0200 @@ -19,7 +19,6 @@ jdk.charsets jdk.deploy jdk.deploy.osx -jdk.hprof.agent jdk.httpserver jdk.jfr jdk.management diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/java.base/share/native/libjli/java.c --- a/jdk/src/java.base/share/native/libjli/java.c Wed Aug 05 03:43:31 2015 +0200 +++ b/jdk/src/java.base/share/native/libjli/java.c Mon Aug 10 13:08:55 2015 +0200 @@ -1082,15 +1082,6 @@ AddOption("-Xverify:remote", NULL); } else if (JLI_StrCmp(arg, "-noverify") == 0) { AddOption("-Xverify:none", NULL); - } else if (JLI_StrCCmp(arg, "-prof") == 0) { - char *p = arg + 5; - char *tmp = JLI_MemAlloc(JLI_StrLen(arg) + 50); - if (*p) { - sprintf(tmp, "-Xrunhprof:cpu=old,file=%s", p + 1); - } else { - sprintf(tmp, "-Xrunhprof:cpu=old,file=java.prof"); - } - AddOption(tmp, NULL); } else if (JLI_StrCCmp(arg, "-ss") == 0 || JLI_StrCCmp(arg, "-oss") == 0 || JLI_StrCCmp(arg, "-ms") == 0 || diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/aix/native/libhprof/porting_aix.c --- a/jdk/src/jdk.hprof.agent/aix/native/libhprof/porting_aix.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright 2012, 2013 SAP AG. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include -#include -#include - -#include "porting_aix.h" - -static unsigned char dladdr_buffer[0x4000]; - -static void fill_dll_info(void) { - int rc = loadquery(L_GETINFO,dladdr_buffer, sizeof(dladdr_buffer)); - if (rc == -1) { - fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno)); - fflush(stderr); - } -} - -static int dladdr_dont_reload(void* addr, Dl_info* info) { - const struct ld_info* p = (struct ld_info*) dladdr_buffer; - info->dli_fbase = 0; info->dli_fname = 0; - info->dli_sname = 0; info->dli_saddr = 0; - for (;;) { - if (addr >= p->ldinfo_textorg && - addr < (((char*)p->ldinfo_textorg) + p->ldinfo_textsize)) { - info->dli_fname = p->ldinfo_filename; - info->dli_fbase = p->ldinfo_textorg; - return 1; /* [sic] */ - } - if (!p->ldinfo_next) { - break; - } - p = (struct ld_info*)(((char*)p) + p->ldinfo_next); - } - return 0; /* [sic] */ -} - -#ifdef __cplusplus -extern "C" -#endif -int dladdr(void *addr, Dl_info *info) { - static int loaded = 0; - if (!loaded) { - fill_dll_info(); - loaded = 1; - } - if (!addr) { - return 0; /* [sic] */ - } - /* Address could be AIX function descriptor? */ - void* const addr0 = *( (void**) addr ); - int rc = dladdr_dont_reload(addr, info); - if (rc == 0) { - rc = dladdr_dont_reload(addr0, info); - if (rc == 0) { /* [sic] */ - fill_dll_info(); /* refill, maybe loadquery info is outdated */ - rc = dladdr_dont_reload(addr, info); - if (rc == 0) { - rc = dladdr_dont_reload(addr0, info); - } - } - } - return rc; -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/aix/native/libhprof/porting_aix.h --- a/jdk/src/jdk.hprof.agent/aix/native/libhprof/porting_aix.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright 2012, 2013 SAP AG. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -/* - * Header file to contain porting-relevant code which does not have a - * home anywhere else. - * This is intially based on hotspot/src/os/aix/vm/{loadlib,porting}_aix.{hpp,cpp} - */ - -/* - * Aix' own version of dladdr(). - * This function tries to mimick dladdr(3) on Linux - * (see http://linux.die.net/man/3/dladdr) - * dladdr(3) is not POSIX but a GNU extension, and is not available on AIX. - * - * Differences between AIX dladdr and Linux dladdr: - * - * 1) Dl_info.dli_fbase: can never work, is disabled. - * A loaded image on AIX is divided in multiple segments, at least two - * (text and data) but potentially also far more. This is because the loader may - * load each member into an own segment, as for instance happens with the libC.a - * 2) Dl_info.dli_sname: This only works for code symbols (functions); for data, a - * zero-length string is returned (""). - * 3) Dl_info.dli_saddr: For code, this will return the entry point of the function, - * not the function descriptor. - */ - -typedef struct { - const char *dli_fname; /* file path of loaded library */ - void *dli_fbase; /* doesn't make sence on AIX */ - const char *dli_sname; /* symbol name; "" if not known */ - void *dli_saddr; /* address of *entry* of function; not function descriptor; */ -} Dl_info; - -#ifdef __cplusplus -extern "C" -#endif -int dladdr(void *addr, Dl_info *info); diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/classes/com/sun/demo/jvmti/hprof/Tracker.java --- a/jdk/src/jdk.hprof.agent/share/classes/com/sun/demo/jvmti/hprof/Tracker.java Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2004, 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. - */ - -package com.sun.demo.jvmti.hprof; - -/* This class and it's methods are used by hprof when injecting bytecodes - * into class file images. - * See the directory src/share/demo/jvmti/hprof and the file README.txt - * for more details. - */ - -public class Tracker { - - /* Master switch that activates calls to native functions. */ - - private static int engaged = 0; - - /* To track memory allocated, we need to catch object init's and arrays. */ - - /* At the beginning of java.jang.Object.(), a call to - * Tracker.ObjectInit() is injected. - */ - - private static native void nativeObjectInit(Object thr, Object obj); - - public static void ObjectInit(Object obj) - { - if ( engaged != 0) { - if (obj == null) { - throw new IllegalArgumentException("Null object."); - } - nativeObjectInit(Thread.currentThread(), obj); - } - } - - /* Immediately following any of the newarray bytecodes, a call to - * Tracker.NewArray() is injected. - */ - - private static native void nativeNewArray(Object thr, Object obj); - - public static void NewArray(Object obj) - { - if ( engaged != 0) { - if (obj == null) { - throw new IllegalArgumentException("Null object."); - } - nativeNewArray(Thread.currentThread(), obj); - } - } - - /* For cpu time spent in methods, we need to inject for every method. */ - - /* At the very beginning of every method, a call to - * Tracker.CallSite() is injected. - */ - - private static native void nativeCallSite(Object thr, int cnum, int mnum); - - public static void CallSite(int cnum, int mnum) - { - if ( engaged != 0 ) { - if (cnum < 0) { - throw new IllegalArgumentException("Negative class index"); - } - - if (mnum < 0) { - throw new IllegalArgumentException("Negative method index"); - } - - nativeCallSite(Thread.currentThread(), cnum, mnum); - } - } - - /* Before any of the return bytecodes, a call to - * Tracker.ReturnSite() is injected. - */ - - private static native void nativeReturnSite(Object thr, int cnum, int mnum); - - public static void ReturnSite(int cnum, int mnum) - { - if ( engaged != 0 ) { - if (cnum < 0) { - throw new IllegalArgumentException("Negative class index"); - } - - if (mnum < 0) { - throw new IllegalArgumentException("Negative method index"); - } - - nativeReturnSite(Thread.currentThread(), cnum, mnum); - } - } - -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/README.txt --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/README.txt Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2003, 2005, 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. - */ - -README ------- - -Design and Implementation: - - * The Tracker Class (Tracker.java & hprof_tracker.c) - It was added to the sun.tools.hprof.Tracker in JDK 5.0 FCS, then - moved to a package that didn't cause classload errors due to - the security manager not liking the sun.* package name. - 5091195 detected that this class needs to be in com.sun.demo.jvmti.hprof. - The BCI code will call these static methods, which will in turn - (if engaged) call matching native methods in the hprof library, - with the additional current Thread argument (Thread.currentThread()). - Doing the currentThread call on the Java side was necessary due - to the difficulty of getting the current thread while inside one - of these Tracker native methods. This class lives in rt.jar. - - * Byte Code Instrumentation (BCI) - Using the ClassFileLoadHook feature and a C language - implementation of a byte code injection transformer, the following - bytecodes get injections: - - On entry to the java.lang.Object method, - a invokestatic call to - Tracker.ObjectInit(this); - is injected. - - On any newarray type opcode, immediately following it, - the array object is duplicated on the stack and an - invokestatic call to - Tracker.NewArray(obj); - is injected. - - On entry to all methods, a invokestatic call to - Tracker.CallSite(cnum,mnum); - is injected. The hprof agent can map the two integers - (cnum,mnum) to a method in a class. This is the BCI based - "method entry" event. - - On return from any method (any return opcode), - a invokestatic call to - Tracker.ReturnSite(cnum,mnum); - is injected. - All classes found via ClassFileLoadHook are injected with the - exception of some system class methods "" and "finalize" - whose length is 1 and system class methods with name "", - and also java.lang.Thread.currentThread() which is used in the - class Tracker (preventing nasty recursion issue). - System classes are currently defined as any class seen by the - ClassFileLoadHook prior to VM_INIT. This does mean that - objects created in the system classes inside might not - get tracked initially. - See the java_crw_demo source and documentation for more info. - The injections are based on what the hprof options - are requesting, e.g. if heap=sites or heap=all is requested, the - newarray and Object. method injections happen. - If cpu=times is requested, all methods get their entries and - returns tracked. Options like cpu=samples or monitor=y - do not require BCI. - - * BCI Allocation Tags (hprof_tag.c) - The current jlong tag being used on allocated objects - is an ObjectIndex, or an index into the object table inside - the hprof code. Depending on whether heap=sites or heap=dump - was asked for, these ObjectIndex's might represent unique - objects, or unique allocation sites for types of objects. - The heap=dump option requires considerable more space - due to the one jobject per ObjectIndex mapping. - - * BCI Performance - The cpu=times seems to have the most negative affect on - performance, this could be improved by not having the - Tracker class methods call native code directly, but accumulate - the data in a file or memory somehow and letting it buffer down - to the agent. The cpu=samples is probably a better way to - measure cpu usage, varying the interval as needed. - The heap=dump seems to use memory like crazy, but that's - partially the way it has always been. - - * Sources in the JDK workspace - The sources and Makefiles live in: - src/jdk.hprof.agent/* - src/share/demo/jvmti/java_crw_demo/* - make/lib/Lib-jdk.hprof.agent.gmk - --------- diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/debug_malloc.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/debug_malloc.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,769 +0,0 @@ -/* - * Copyright (c) 2004, 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. - */ - - -/* ************************************************************************** - * - * Set of malloc/realloc/calloc/strdup/free replacement macros that - * insert some extra words around each allocation for debugging purposes - * and also attempt to detect invalid uses of the malloc heap through - * various tricks like inserting clobber words at the head and tail of - * the user's area, delayed free() calls, and setting the memory to - * a fixed pattern on allocation and when freed. The allocations also - * can include warrants so that when an area is clobbered, this - * package can report where the allocation took place. - * The macros included are: - * malloc(size) - * realloc(ptr,size) - * calloc(nelem,elsize) - * strdup(s1) - * free(ptr) - * malloc_police() <--- Not a system function - * The above macros match the standard behavior of the system functions. - * - * They should be used through the include file "debug_malloc.h". - * - * IMPORTANT: All source files that call any of these macros - * should include debug_malloc.h. This package will - * not work if the memory isn't allocated and freed - * by the macros in debug_malloc.h. The important issue - * is that any malloc() from debug_malloc.h must be - * freed by the free() in debug_malloc.h. - * - * The macros in debug_malloc.h will override the normal use of - * malloc, realloc, calloc, strdup, and free with the functions below. - * - * These functions include: - * void *debug_malloc(size_t, void*, int); - * void *debug_realloc(void*, size_t, void*, int); - * void *debug_calloc(size_t, size_t, void*, int); - * void debug_free(void *, void*, int); - * - * In addition the function debug_malloc_police() can be called to - * tell you what memory has not been freed. - * void debug_malloc_police(void*, int); - * The function debug_malloc_police() is available through the macro - * malloc_police(). Normally you would want to call this at exit() - * time to find out what memory is still allocated. - * - * The variable malloc_watch determines if the warrants are generated. - * warrants are structures that include the filename and line number - * of the caller who allocated the memory. This structure is stored - * at the tail of the malloc space, which is allocated large enough - * to hold some clobber words at the head and tail, the user's request - * and the warrant record (if malloc_watch is non-zero). - * - * The macro LEFT_OVER_CHAR is what the trailing bytes of an allocation - * are set to (when the allocation is not a multiple of 8) on allocation. - * At free(0 time, these bytes are double checked to make sure they were - * not clobbered. To remove this feature #undef LEFT_OVER_CHAR. - * - * The memory freed will have the FREED_CHAR put into it. To remove this - * feature #undef FREED_CHAR. - * - * The memory allocated (not calloc'd) will have the ALLOC_CHAR put into it - * at the time of allocation. To remove this feature #undef ALLOC_CHAR. - * - * The macro MAX_FREE_DELAY_COUNT controls how many free blocks will - * be kept around before being freed. This creates a delayed affect - * so that free space that gets clobbered just might get detected. - * The free() call will immediately set the user space to the FREED_CHAR, - * leaving the clobber words and warrant in place (making sure they - * haven't been clobbered). Then the free() pointer is added to a - * queue of MAX_FREE_DELAY_COUNT long, and if the queue was full, the - * oldest free()'d memory is actually freed, getting it's entire - * memory length set to the FREED_CHAR. - * - * WARNING: This can significantly slow down an application, depending - * on how many allocations are made. Also the additional memory - * needed for the clobber words and the warrants can be significant - * again, depending on how many allocations are made. - * In addition, the delayed free calls can create situations - * where you might run out of memory prematurely. - * - * ************************************************************************** - */ - -#ifdef DEBUG - -#include -#include -#include -#include -#include -#include "hprof.h" - -/* *************************************************************************** - * Space normally looks like (clobber Word is 64 bits and aligned to 8 bytes): - * - * ----------------- - * malloc/free get->| clobber Word | ---> contains -size requested by user - * ----------------- - * User gets --->| user space | - * | | - * | | left_over | ---> left_over bytes will be <= 7 - * ----------------- - * | clobber Word | ---> contains -size requested by user - * ----------------- - * | Warrant | ---> Optional (malloc_watch!=0) - * | | Contains filename and line number - * | | where allocation happened - * | | - * ----------------- - ***************************************************************************/ - -/* - * Flag that tells debug_malloc/debug_free/debug_realloc to police - * heap space usage. (This is a dynamic flag that can be turned on/off) - */ -static int malloc_watch = 1; - -/* Character to stuff into freed space */ -#define FREED_CHAR 'F' - -/* Character to stuff into allocated space */ -#define ALLOC_CHAR 'A' - -/* Character to stuff into left over trailing bytes */ -#define LEFT_OVER_CHAR 'Z' - -/* Number of 'free' calls that will be delayed until the end */ -#define MAX_FREE_DELAY_COUNT 1 -#undef MAX_FREE_DELAY_COUNT - -/* Maximum name of __FILE_ stored in each malloc'd area */ -#define WARRANT_NAME_MAX (32-1) /* 1 less than multiple of 8 is best */ - -/* Macro to convert a user pointer to the malloc pointer */ -#define user2malloc_(uptr) (((char*)(void*)uptr)-sizeof(Word)) - -/* Macro to convert a macro pointer to the user pointer */ -#define malloc2user_(mptr) (((char*)(void*)(mptr))+sizeof(Word)) - -/* Size of the warrant record (this is dynamic) */ -#define warrant_space ( malloc_watch?sizeof(Warrant_Record):0 ) - -/* Macro to round up a number of bytes to a multiple of sizeof(Word) bytes */ -#define round_up_(n) \ - ((n)==0?0:(sizeof(Word)+(((n)-1)/sizeof(Word))*sizeof(Word))) - -/* Macro to calculate the needed malloc bytes from the user's request. */ -#define rbytes_(nbytes) \ - (size_t)( sizeof(Word) + round_up_(nbytes) + sizeof(Word) + warrant_space ) - -/* Macro to get the -size stored in space through the malloc pointer */ -#define nsize1_(mptr) (((Word*)(void*)(mptr))->nsize1) -#define nsize2_(mptr) (((Word*)(void*)(mptr))->nsize2) - -/* Macro to get the -size stored in the tail of the space through */ -/* the malloc pointer */ -#define tail_nsize1_(mptr) \ - nsize1_(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word)) -#define tail_nsize2_(mptr) \ - nsize2_(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word)) - -/* Macro to get the -size stored in space through the user pointer */ -#define user_nsize1_(uptr) nsize1_(user2malloc_(uptr)) -#define user_nsize2_(uptr) nsize2_(user2malloc_(uptr)) - -/* Macro to get the -size stored in the tail of the space through */ -/* the user pointer */ -#define user_tail_nsize1_(uptr) tail_nsize1_(user2malloc_(uptr)) -#define user_tail_nsize2_(uptr) tail_nsize2_(user2malloc_(uptr)) - -/* Macro to get the int* of the last 32bit word of user space */ -#define last_user_word_(mptr) \ - ((int*)(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr)))) - -/* Macros to get at the warrant contents from the malloc pointer */ -#define warrant_(mptr) \ - (*((Warrant_Record*)(void*)(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word)*2))) - -/* This struct is allocated after the tail clobber word if malloc_watch */ -/* is true. */ -typedef struct { - void *link; /* Next mptr in list */ - char name[WARRANT_NAME_MAX + 1]; /* Name of allocator */ - int line; /* Line number where allocated */ - int id; /* Nth allocation */ -} Warrant_Record; -#define warrant_link_(mptr) warrant_(mptr).link -#define warrant_name_(mptr) warrant_(mptr).name -#define warrant_line_(mptr) warrant_(mptr).line -#define warrant_id_(mptr) warrant_(mptr).id -#define MFILE(mptr) (malloc_watch?warrant_name_(mptr):"?") -#define MLINE(mptr) (malloc_watch?warrant_line_(mptr):0) -#define MID(mptr) (malloc_watch?warrant_id_(mptr):0) - -/* This should be one machine word and is also the clobber word struct */ -typedef struct { - int nsize1; - int nsize2; -} Word; /* Largest basic type , sizeof(double)? */ - -/* The first malloc pointer for the warrants */ -static void *first_warrant_mptr = NULL; - -/* Counter of allocations */ -static int id_counter = 0; -static int largest_size = 0; -static void * largest_addr = NULL; -static void * smallest_addr = NULL; - -/* Used to isolate what the error is */ -static char *debug_check; -static void *clobbered_ptr; - -/* Minimum macro */ -#define minimum(a,b) ((a)<(b)?(a):(b)) - -/* Message routine */ -static void -error_message(const char * format, ...) -{ - FILE *error_fp = stderr; /* All debug_malloc.c messages */ - va_list ap; - va_start(ap, format); - (void)fprintf(error_fp, "debug_malloc: "); - (void)vfprintf(error_fp, format, ap); - (void)fprintf(error_fp, "\n"); - (void)fflush(error_fp); - va_end(ap); -} - -/* This function prints out a memory error for the memory function - * 'name' which was called in file 'file' at line number 'line'. The malloc - * pointer with the error is in 'mptr'. - */ -static void -memory_error(void *mptr, const char *name, int mid, const char *mfile, int mline, const char *file, int line) -{ - char nice_words[512]; - char temp[256]; - int len; - void *mptr_walk; - - if (name == NULL) - name = "UNKNOWN_NAME"; - if (file == NULL) - file = "UNKNOWN_FILE"; - md_system_error(temp, (int)sizeof(temp)); - (void)strcpy(nice_words, temp); - if ( debug_check!=NULL ) { - (void)md_snprintf(nice_words, sizeof(nice_words), - "%s The %s at %p appears to have been hit.", - temp, debug_check, clobbered_ptr); - } - len = -nsize1_(mptr); - error_message("Error: " - "%s The malloc space #%d is at %p [user size=%d(0x%x)]," - " and was allocated from file \"%s\" at line %d." - " [The debug function %s() detected this error " - "in file \"%s\" at line %d.]", - nice_words, mid, mptr, len, len, mfile, mline, - name, file, line); - - /* Print out contents of this allocation */ - { - int i; - void *uptr = malloc2user_(mptr); - char *pmess; - pmess = temp; - for(i=0;i<(int)sizeof(temp);i++) { - int ch = ((unsigned char*)uptr)[i]; - if ( isprint(ch) ) { - *pmess++ = ch; - } else { - *pmess++ = '\\'; - *pmess++ = 'x'; - (void)sprintf(pmess,"%02x",ch); - pmess+=2; - } - } - *pmess = 0; - error_message("Error: %p contains user data: %s", uptr, temp); - } - - /* Try and print out table */ - if (!malloc_watch) { - return; - } - mptr_walk = first_warrant_mptr; - if (mptr_walk != NULL) { - error_message("Active allocations: " - "count=%d, largest_size=%d, address range (%p,%p)", - id_counter, largest_size, smallest_addr, largest_addr); - do { - int size1; - int size2; - char *mfile_walk; - - if ( mptr_walk > largest_addr || mptr_walk < smallest_addr ) { - error_message("Terminating list due to pointer corruption"); - break; - } - size1 = -nsize1_(mptr_walk); - size2 = -nsize2_(mptr_walk); - mfile_walk = MFILE(mptr_walk); - error_message("#%d: addr=%p size1=%d size2=%d file=\"%.*s\" line=%d", - MID(mptr_walk), mptr_walk, size1, size2, - WARRANT_NAME_MAX, mfile_walk, MLINE(mptr_walk)); - if ( size1 != size2 || size1 > largest_size || size1 < 0 ) { - error_message("Terminating list due to size corruption"); - break; - } - mptr_walk = warrant_link_(mptr_walk); - } while (mptr_walk != NULL); - } - abort(); -} - -/* This function sets the clobber word and sets up the warrant for the input - * malloc pointer "mptr". - */ -static void -setup_space_and_issue_warrant(void *mptr, size_t size, const char *file, int line) -{ - register int nbytes; - - /*LINTED*/ - nbytes = (int)size; - if ( nbytes > largest_size || largest_addr == NULL ) largest_size = nbytes; - /*LINTED*/ - if ( mptr > largest_addr ) largest_addr = mptr; - /*LINTED*/ - if ( mptr < smallest_addr || smallest_addr == NULL ) smallest_addr = mptr; - - /* Must be done first: */ - nsize1_(mptr) = -nbytes; - nsize2_(mptr) = -nbytes; - tail_nsize1_(mptr) = -nbytes; - tail_nsize2_(mptr) = -nbytes; - -#ifdef LEFT_OVER_CHAR - /* Fill in those few extra bytes just before the tail Word structure */ - { - register int trailing_extra_bytes; - /* LINTED */ - trailing_extra_bytes = (int) (round_up_(nbytes) - nbytes); - if ( trailing_extra_bytes > 0 ) { - register char *p; - register int i; - p = ((char *) mptr) + sizeof(Word) + nbytes; - for (i = 0; i < trailing_extra_bytes; i++) - p[i] = LEFT_OVER_CHAR; - } - } -#endif - - /* Fill out warrant */ - if (malloc_watch) { - static Warrant_Record zero_warrant; - register void *p1, - *p2; - size_t len; - int start_pos = 0; - warrant_(mptr) = zero_warrant; - p1 = warrant_name_(mptr); - len = strlen(file); - if ( len > WARRANT_NAME_MAX ) { - /*LINTED*/ - start_pos = (int)len - WARRANT_NAME_MAX; - } - p2 = ((char*)file) + start_pos; - /*LINTED*/ - (void) memcpy(p1, p2, minimum(((int)len), WARRANT_NAME_MAX)); - warrant_line_(mptr) = line; - warrant_id_(mptr) = ++id_counter; - warrant_link_(mptr) = first_warrant_mptr; - first_warrant_mptr = mptr; - } -} - -/* This function checks the clobber words at the beginning and end of the - * allocated space. - */ -static void -memory_check(void *uptr, int mid, const char *mfile, int mline, const char *file, int line) -{ - int neg_nbytes; - int nbytes; - - debug_check = "pointer value itself"; - clobbered_ptr = uptr; - if (uptr == NULL) - memory_error((void *) NULL, "memory_check", mid, mfile, mline, file, line); - - /* Check both Word structures */ - - debug_check = "first beginning clobber word"; - clobbered_ptr = (char*)&user_nsize1_(uptr); - neg_nbytes = user_nsize1_(uptr); - if (neg_nbytes >= 0) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - debug_check = "second beginning clobber word"; - clobbered_ptr = (char*)&user_nsize2_(uptr); - if (neg_nbytes != user_nsize2_(uptr)) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - debug_check = "first ending clobber word"; - clobbered_ptr = (char*)&user_tail_nsize1_(uptr); - if (neg_nbytes != user_tail_nsize1_(uptr)) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - debug_check = "second ending clobber word"; - clobbered_ptr = (char*)&user_tail_nsize2_(uptr); - if (neg_nbytes != user_tail_nsize2_(uptr)) - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - - /* Get a positive count of bytes */ - nbytes = -neg_nbytes; - -#ifdef LEFT_OVER_CHAR - { - /* Check those few extra bytes just before the tail Word structure */ - register int trailing_extra_bytes; - register int i; - register char *p; - /* LINTED */ - trailing_extra_bytes = (int) (round_up_(nbytes) - nbytes); - p = ((char *) (uptr)) + nbytes; - debug_check = "trailing left over area"; - for (i = 0; i < trailing_extra_bytes; i++) { - clobbered_ptr = p+1; - if (p[i] != LEFT_OVER_CHAR) { - memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line); - } - } - } -#endif - - /* Make sure debug_check is cleared */ - debug_check = NULL; -} - -/* This function looks for the given malloc pointer in the police line up - * and removes it from the warrant list. - * mptr The pointer to the malloc space being removed - */ -static int -remove_warrant(void *mptr) -{ - void *mptr1, - *last_mptr1; - - /* Free it up from the list */ - if (malloc_watch && mptr != NULL) { - int found; - - found = 0; - last_mptr1 = NULL; - mptr1 = first_warrant_mptr; - while (mptr1 != NULL) { - if (mptr1 == mptr) { - if (last_mptr1 == NULL) - first_warrant_mptr = warrant_link_(mptr1); - else - warrant_link_(last_mptr1) = warrant_link_(mptr1); - found = 1; - break; - } - last_mptr1 = mptr1; - mptr1 = warrant_link_(mptr1); - } - return found; - } - return 1; -} - -static void -actual_free(void *uptr, const char *file, int line) -{ - void *mptr; - const char *mfile; - int mline; - int mid; - if ( uptr == NULL ) - return; - mptr = user2malloc_(uptr); - memory_check(uptr, (mid=MID(mptr)), (mfile=MFILE(mptr)), (mline=MLINE(mptr)), file, line); - if (malloc_watch && remove_warrant(mptr)==0 ) - memory_check(uptr, mid, mfile, mline, file, line); -#ifdef FREED_CHAR - if ( mptr!=NULL ) { - size_t nbytes = -nsize1_(mptr); - /* LINTED */ - (void)memset(mptr, FREED_CHAR, rbytes_(nbytes)); - } -#endif - free(mptr); -} - -#ifdef MAX_FREE_DELAY_COUNT - -static void *free_delay[MAX_FREE_DELAY_COUNT]; -static int free_delay_pos = 0; - -static void -delayed_free(void *uptr, const char* file, int line) -{ - void *mptr; - void *olduptr = free_delay[free_delay_pos]; - size_t nbytes; - if ( uptr==NULL ) - return; - mptr = user2malloc_(uptr); - memory_check(uptr, MID(mptr), MFILE(mptr), MLINE(mptr), file, line); - if ( olduptr!=NULL ) { - actual_free(olduptr, file, line); - } - free_delay[free_delay_pos] = uptr; - free_delay_pos++; - free_delay_pos = free_delay_pos % MAX_FREE_DELAY_COUNT; - nbytes = -user_nsize1_(uptr); -#ifdef FREED_CHAR - (void)memset(uptr, FREED_CHAR, (size_t)nbytes); -#endif -} - -static void -delayed_free_all(const char *file, int line) -{ - int i; - for ( i=0; i< MAX_FREE_DELAY_COUNT; i++) { - void *olduptr = free_delay[i]; - free_delay[i] = NULL; - if ( olduptr!=NULL ) { - actual_free(olduptr, file, line); - } - } -} - -#endif - -void -debug_free(void *uptr, const char *file, int line) -{ - int mid = 0; - - if (uptr == NULL) - memory_error((void *) NULL, "debug_free", mid, file, line, file, line); -#ifdef MAX_FREE_DELAY_COUNT - delayed_free(uptr, file, line); -#else - actual_free(uptr, file, line); -#endif -} - -/* This function calls malloc(). */ -void * -debug_malloc(size_t nbytes, const char *file, int line) -{ - void *mptr; - void *uptr; - int mid = id_counter; - - /*LINTED*/ - if ((int)nbytes <= 0) - memory_error((void *) NULL, "debug_malloc", mid, file, line, file, line); - /* LINTED */ - mptr = malloc(rbytes_(nbytes)); - if (mptr == NULL) - memory_error((void *) NULL, "debug_malloc", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - uptr = malloc2user_(mptr); -#ifdef ALLOC_CHAR - (void)memset(uptr, ALLOC_CHAR, (size_t)nbytes); -#endif - return uptr; -} - -void * -debug_realloc(void *uptr, size_t nbytes, const char *file, int line) -{ - void *mptr; - void *oldmptr; - void *newuptr; - size_t oldnbytes; - int mid = id_counter; - - oldmptr = user2malloc_(uptr); - oldnbytes = 0; - if ((int)nbytes <= 0) - memory_error(oldmptr, "debug_realloc", mid, file, line, file, line); - if (uptr != NULL) { - memory_check(uptr, MID(oldmptr), MFILE(oldmptr), MLINE(oldmptr), file, line); - oldnbytes = -user_nsize1_(uptr); - if ( malloc_watch && remove_warrant(oldmptr)==0 ) - memory_check(uptr, MID(oldmptr), MFILE(oldmptr), MLINE(oldmptr), file, line); - } - if (uptr == NULL) { - /* LINTED */ - mptr = malloc(rbytes_(nbytes)); - } else { - /* LINTED */ - mptr = realloc(oldmptr, rbytes_(nbytes)); - } - if (mptr == NULL) - memory_error(oldmptr, "debug_realloc", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - newuptr = malloc2user_(mptr); -#ifdef ALLOC_CHAR - if (uptr == NULL) - (void)memset(newuptr, ALLOC_CHAR, (size_t)nbytes); - else if ( nbytes > oldnbytes ) - (void)memset(((char*)newuptr)+oldnbytes, ALLOC_CHAR, (size_t)nbytes-oldnbytes); -#endif - return newuptr; -} - -/* This function calls calloc(). */ -void * -debug_calloc(size_t nelem, size_t elsize, const char *file, int line) -{ - void *mptr; - size_t nbytes; - int mid = id_counter; - - nbytes = nelem*elsize; - /*LINTED*/ - if ((int)nbytes <= 0) - memory_error((void *) NULL, "debug_calloc", mid, file, line, file, line); - /* LINTED */ - mptr = calloc(rbytes_(nbytes),1); - if (mptr == NULL) - memory_error((void *) NULL, "debug_calloc", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - return malloc2user_(mptr); -} - -/* This function replaces strdup(). */ -char * -debug_strdup(const char *s1, const char *file, int line) -{ - void *mptr; - void *uptr; - size_t nbytes; - int mid = id_counter; - - if (s1 == NULL) - memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line); - nbytes = strlen(s1)+1; - /*LINTED*/ - if ((int)nbytes < 0) - memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line); - /* LINTED */ - mptr = malloc(rbytes_(nbytes)); - if (mptr == NULL) - memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line); - setup_space_and_issue_warrant(mptr, nbytes, file, line); - uptr = malloc2user_(mptr); - (void)strcpy((char*)uptr, s1); - return (char*)uptr; -} - -void -debug_malloc_verify(const char *file, int line) -{ - void *mptr; - -#ifdef MAX_FREE_DELAY_COUNT - delayed_free_all(file,line); -#endif - - if (!malloc_watch) { - return; - } - mptr = first_warrant_mptr; - if (mptr != NULL) { - /* Check all this memory first */ - do { - memory_check(malloc2user_(mptr), MID(mptr), MFILE(mptr), MLINE(mptr), file, line); - mptr = warrant_link_(mptr); - } while (mptr != NULL); - } -} - -/* Report outstanding space warrants to console. */ -void -debug_malloc_police(const char *file, int line) -{ - void *mptr; - -#ifdef MAX_FREE_DELAY_COUNT - delayed_free_all(file,line); -#endif - - if (!malloc_watch) { - return; - } - - mptr = first_warrant_mptr; - if (mptr != NULL) { - debug_malloc_verify(file, line); - /* Now issue warrants */ - mptr = first_warrant_mptr; - do { - error_message("Outstanding space warrant: %p (%d bytes) allocated by %s at line %d, allocation #%d", - mptr, -nsize1_(mptr), warrant_name_(mptr), - warrant_line_(mptr), warrant_id_(mptr)); - - mptr = warrant_link_(mptr); - } while (mptr != NULL); - } -} - -#else - -void -debug_malloc_verify(const char *file, int line) -{ - file = file; - line = line; -} - -void -debug_malloc_police(const char *file, int line) -{ - file = file; - line = line; -} - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/debug_malloc.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/debug_malloc.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +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. - */ - - -/* *********************************************************************** - * - * The source file debug_malloc.c should be included with your sources. - * - * The object file debug_malloc.o should be included with your object files. - * - * WARNING: Any memory allocattion from things like memalign(), valloc(), - * or any memory not coming from these macros (malloc, realloc, - * calloc, and strdup) will fail miserably. - * - * *********************************************************************** - */ - -#ifndef _DEBUG_MALLOC_H -#define _DEBUG_MALLOC_H - -#ifdef DEBUG - -#include -#include - -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - -/* The real functions behind the macro curtains. */ - -void *debug_malloc(size_t, const char *, int); -void *debug_realloc(void *, size_t, const char *, int); -void *debug_calloc(size_t, size_t, const char *, int); -char *debug_strdup(const char *, const char *, int); -void debug_free(void *, const char *, int); - -#endif - -void debug_malloc_verify(const char*, int); -#undef malloc_verify -#define malloc_verify() debug_malloc_verify(THIS_FILE, __LINE__) - -void debug_malloc_police(const char*, int); -#undef malloc_police -#define malloc_police() debug_malloc_police(THIS_FILE, __LINE__) - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2003, 2014, 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 hprof #include file, should be included by most if not - * all hprof source files. Gives access to the global data structure - * and all global macros, and everything declared in the #include - * files of each of the source files. - */ - -#ifndef HPROF_H -#define HPROF_H - -/* Standard C functions used throughout. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* General JVM/Java functions, types and macros. */ - -#include -#include "jni.h" -#include "jvmti.h" -#include "classfile_constants.h" -#include "jvm_md.h" - -/* Macros to extract the upper and lower 32 bits of a jlong */ - -#define jlong_high(a) ((jint)((a)>>32)) -#define jlong_low(a) ((jint)(a)) -#define jlong_to_jint(a) ((jint)(a)) -#define jint_to_jlong(a) ((jlong)(a)) - -#define jlong_add(a, b) ((a) + (b)) - - -/* The type used to contain a generic 32bit "serial number". */ - -typedef unsigned SerialNumber; - -/* How the options get to OnLoad: */ - -#define AGENTNAME "hprof" -#define XRUN "-Xrun" AGENTNAME -#define AGENTLIB "-agentlib:" AGENTNAME - -/* Name of prelude file, found at runtime relative to java binary location */ - -#define PRELUDE_FILE "jvm.hprof.txt" - -/* File I/O buffer size to be used with any file i/o operation */ - -#define FILE_IO_BUFFER_SIZE (1024*64) - -/* Machine dependent functions. */ - -#include "hprof_md.h" - -/* Table index types */ - -typedef unsigned TableIndex; -typedef TableIndex ClassIndex; -typedef TableIndex FrameIndex; -typedef TableIndex IoNameIndex; -typedef TableIndex MonitorIndex; -typedef TableIndex ObjectIndex; -typedef TableIndex LoaderIndex; -typedef TableIndex RefIndex; -typedef TableIndex SiteIndex; -typedef TableIndex StringIndex; -typedef TableIndex TlsIndex; -typedef TableIndex TraceIndex; - -/* Index for method tables in classes */ - -typedef int MethodIndex; - -/* The different kinds of class status bits. */ - -enum ClassStatus { - CLASS_PREPARED = 0x00000001, - CLASS_LOADED = 0x00000002, - CLASS_UNLOADED = 0x00000004, - CLASS_SPECIAL = 0x00000008, - CLASS_IN_LOAD_LIST = 0x00000010, - CLASS_SYSTEM = 0x00000020, - CLASS_DUMPED = 0x00000040 -}; -typedef jint ClassStatus; - -/* The different kind of objects we track with heap=dump */ - -typedef unsigned char ObjectKind; -enum { - OBJECT_NORMAL = 1, - OBJECT_CLASS = 2, - OBJECT_SYSTEM = 3, - OBJECT_HPROF = 4, - OBJECT_LOADER = 5 -}; - -/* Used by site_write() when writing out the heap=sites data. */ - -enum { - SITE_DUMP_INCREMENTAL = 0x01, - SITE_SORT_BY_ALLOC = 0x02, - SITE_FORCE_GC = 0x04 -}; - -/* Used to hold information about a field, and potentially a value too. */ - -typedef struct FieldInfo { - ClassIndex cnum; - StringIndex name_index; - StringIndex sig_index; - unsigned short modifiers; - unsigned char primType; - unsigned char primSize; -} FieldInfo; - -/* Used to hold information about a constant pool entry value for a class. */ - -typedef struct ConstantPoolValue { - unsigned constant_pool_index; - StringIndex sig_index; - jvalue value; -} ConstantPoolValue; - -/* All machine independent functions */ - -#include "hprof_error.h" -#include "hprof_util.h" -#include "hprof_blocks.h" -#include "hprof_stack.h" -#include "hprof_init.h" -#include "hprof_table.h" -#include "hprof_string.h" -#include "hprof_class.h" -#include "hprof_tracker.h" -#include "hprof_frame.h" -#include "hprof_monitor.h" -#include "hprof_trace.h" -#include "hprof_site.h" -#include "hprof_event.h" -#include "hprof_reference.h" -#include "hprof_object.h" -#include "hprof_loader.h" -#include "hprof_tls.h" -#include "hprof_check.h" -#include "hprof_io.h" -#include "hprof_listener.h" -#include "hprof_cpu.h" -#include "hprof_tag.h" - -/* Global data structure */ - -struct LineTable; - -typedef struct { - - jvmtiEnv *jvmti; /* JVMTI env for this session */ - JavaVM *jvm; /* JavaVM* for this session */ - jint cachedJvmtiVersion; /* JVMTI version number */ - - char *header; /* "JAVA PROFILE 1.0.[12]" */ - jboolean segmented; /* JNI_TRUE if 1.0.2 */ - jlong maxHeapSegment; - jlong maxMemory; - - /* Option settings */ - char * options; /* option string copy */ - char * utf8_output_filename;/* file=filename */ - int net_port; /* net=hostname:port */ - char * net_hostname; /* net=hostname:port */ - char output_format; /* format=a|b */ - int max_trace_depth; /* depth=max_trace_depth */ - int prof_trace_depth; /* max_trace_depth or 2 (old) */ - int sample_interval; /* interval=sample_interval (ms) */ - double cutoff_point; /* cutoff=cutoff_point */ - jboolean cpu_sampling; /* cpu=samples|y */ - jboolean cpu_timing; /* cpu=times */ - jboolean old_timing_format; /* cpu=old (old) output format */ - jboolean heap_dump; /* heap=dump|all */ - jboolean alloc_sites; /* heap=sites|all */ - jboolean thread_in_traces; /* thread=y|n */ - jboolean lineno_in_traces; /* lineno=y|n */ - jboolean dump_on_exit; /* doe=y|n */ - jboolean micro_state_accounting; /* msa=y|n */ - jboolean force_output; /* force=y|n */ - jboolean monitor_tracing; /* monitor=y|n */ - jboolean gc_okay; /* gc_okay=y|n (Not used) */ - - unsigned logflags; /* logflags=bitmask */ - - #define DEBUGFLAG_UNPREPARED_CLASSES 0x001 - unsigned debugflags; /* debugflags=bitmask */ - - jboolean coredump; /* coredump=y|n */ - jboolean errorexit; /* errorexit=y|n */ - jboolean pause; /* pause=y|n */ - jboolean debug; /* debug=y|n */ - jboolean verbose; /* verbose=y|n */ - jboolean primfields; /* primfields=y|n */ - jboolean primarrays; /* primarrays=y|n */ - jint experiment; /* X=NUMBER */ - - int fd; /* file or socket (net=addr). */ - jboolean socket; /* True if fd is a socket (net=addr). */ - jboolean bci; /* True if any kind of BCI being done */ - jboolean obj_watch; /* True if bci and watching allocs */ - - int bci_counter; /* Class BCI counter */ - - int heap_fd; - char *output_filename; /* file=filename */ - char *heapfilename; - - int check_fd; - char *checkfilename; - - volatile jboolean dump_in_process; /* Dump in process */ - volatile jboolean jvm_initializing; /* VMInit happening */ - volatile jboolean jvm_initialized; /* VMInit happened */ - volatile jboolean jvm_shut_down; /* VMDeath happened */ - jboolean vm_death_callback_active; /* VMDeath happening */ - - /* Stack of objects freed during GC */ - Stack * object_free_stack; - jrawMonitorID object_free_lock; - - /* Lock for debug_malloc() */ - jrawMonitorID debug_malloc_lock; - - /* Count of classes that JVMTI thinks are active */ - jint class_count; - - /* Used to track callbacks for VM_DEATH */ - jrawMonitorID callbackBlock; - jrawMonitorID callbackLock; - jint active_callbacks; - - /* Running totals on all bytes allocated */ - jlong total_alloced_bytes; - jlong total_alloced_instances; - jint total_live_bytes; - jint total_live_instances; - - /* Running total on all time spent in GC (very rough estimate) */ - jlong gc_start_time; - jlong time_in_gc; - - /* Global Data access Lock */ - jrawMonitorID data_access_lock; - - /* Global Dump lock */ - jrawMonitorID dump_lock; - - /* Milli-second clock when hprof onload started */ - jlong micro_sec_ticks; - - /* Thread class (for starting agent threads) */ - ClassIndex thread_cnum; - - /* Agent threads started information */ - jboolean listener_loop_running; - jrawMonitorID listener_loop_lock; - jboolean cpu_loop_running; - jrawMonitorID cpu_loop_lock; - jrawMonitorID cpu_sample_lock; /* cpu=samples loop */ - jint gc_finish; /* Count of GC finish events */ - jboolean gc_finish_active; /* True if thread active */ - jboolean gc_finish_stop_request; /* True if we want it to stop */ - jrawMonitorID gc_finish_lock; - - jboolean pause_cpu_sampling; /* temp pause in cpu sampling */ - - /* Output buffer, position, size, and position in dump if reading */ - char * write_buffer; - int write_buffer_index; - int write_buffer_size; - char * heap_buffer; - int heap_buffer_index; - int heap_buffer_size; - jlong heap_last_tag_position; - jlong heap_write_count; - char * check_buffer; - int check_buffer_index; - int check_buffer_size; - - /* Serial number counters for tables (see hprof_table.c), classes, - * tls (thread local storage), and traces. - */ - SerialNumber table_serial_number_start; - SerialNumber class_serial_number_start; - SerialNumber thread_serial_number_start; - SerialNumber trace_serial_number_start; - SerialNumber object_serial_number_start; - SerialNumber frame_serial_number_start; - SerialNumber gref_serial_number_start; - - SerialNumber table_serial_number_counter; - SerialNumber class_serial_number_counter; - SerialNumber thread_serial_number_counter; - SerialNumber trace_serial_number_counter; - SerialNumber object_serial_number_counter; - SerialNumber frame_serial_number_counter; - SerialNumber gref_serial_number_counter; - - /* The methodID for the Object method. */ - jmethodID object_init_method; - - /* Keeping track of the tracker class and it's methods */ - volatile jint tracking_engaged; /* !=0 means it's on */ - ClassIndex tracker_cnum; - int tracker_method_count; - struct { - StringIndex name; /* String index for name */ - StringIndex sig; /* String index for signature */ - jmethodID method; /* Method ID */ - } tracker_methods[12]; /* MAX 12 Tracker class methods */ - - /* Index to some common items */ - LoaderIndex system_loader; - SerialNumber unknown_thread_serial_num; - TraceIndex system_trace_index; - SiteIndex system_object_site_index; - jint system_class_size; - TraceIndex hprof_trace_index; - SiteIndex hprof_site_index; - - /* Tables for strings, classes, sites, etc. */ - struct LookupTable * string_table; - struct LookupTable * ioname_table; - struct LookupTable * class_table; - struct LookupTable * site_table; - struct LookupTable * object_table; - struct LookupTable * reference_table; - struct LookupTable * frame_table; - struct LookupTable * trace_table; - struct LookupTable * monitor_table; - struct LookupTable * tls_table; - struct LookupTable * loader_table; - - /* Handles to java_crw_demo library */ - void * java_crw_demo_library; - void * java_crw_demo_function; - void * java_crw_demo_classname_function; - - /* Indication that the agent has been loaded */ - jboolean isLoaded; - -} GlobalData; - -/* This should be the only 'extern' in the library (not exported). */ - -extern GlobalData * gdata; - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_b_spec.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_b_spec.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -#ifndef HPROF_B_SPEC_H -#define HPROF_B_SPEC_H - -/* Hprof binary format enums and spec. */ - -/* Need to #define or typedef HprofId before including this file. - * hprof used ObjectIndex or 4 bytes, but it can be 4 or 8 byte type. - */ - -/* -------------------------------------------------------------------- */ -/* -------------------------------------------------------------------- */ -/* -------------------------------------------------------------------- */ - -/* - * hprof binary format: (result either written to a file or sent over - * the network). - * - * WARNING: This format is still under development, and is subject to - * change without notice. - * - * header "JAVA PROFILE 1.0.1" or "JAVA PROFILE 1.0.2" (0-terminated) - * u4 size of identifiers. Identifiers are used to represent - * UTF8 strings, objects, stack traces, etc. They usually - * have the same size as host pointers. For example, on - * Solaris and Win32, the size is 4. - * u4 high word - * u4 low word number of milliseconds since 0:00 GMT, 1/1/70 - * [record]* a sequence of records. - */ - -/* - * Record format: - * - * u1 a TAG denoting the type of the record - * u4 number of *microseconds* since the time stamp in the - * header. (wraps around in a little more than an hour) - * u4 number of bytes *remaining* in the record. Note that - * this number excludes the tag and the length field itself. - * [u1]* BODY of the record (a sequence of bytes) - */ - -/* - * The following TAGs are supported: - * - * TAG BODY notes - *---------------------------------------------------------- - * HPROF_UTF8 a UTF8-encoded name - * - * id name ID - * [u1]* UTF8 characters (no trailing zero) - * - * HPROF_LOAD_CLASS a newly loaded class - * - * u4 class serial number (> 0) - * id class object ID - * u4 stack trace serial number - * id class name ID - * - * HPROF_UNLOAD_CLASS an unloading class - * - * u4 class serial_number - * - * HPROF_FRAME a Java stack frame - * - * id stack frame ID - * id method name ID - * id method signature ID - * id source file name ID - * u4 class serial number - * i4 line number. >0: normal - * -1: unknown - * -2: compiled method - * -3: native method - * - * HPROF_TRACE a Java stack trace - * - * u4 stack trace serial number - * u4 thread serial number - * u4 number of frames - * [id]* stack frame IDs - * - * - * HPROF_ALLOC_SITES a set of heap allocation sites, obtained after GC - * - * u2 flags 0x0001: incremental vs. complete - * 0x0002: sorted by allocation vs. live - * 0x0004: whether to force a GC - * u4 cutoff ratio - * u4 total live bytes - * u4 total live instances - * u8 total bytes allocated - * u8 total instances allocated - * u4 number of sites that follow - * [u1 is_array: 0: normal object - * 2: object array - * 4: boolean array - * 5: char array - * 6: float array - * 7: double array - * 8: byte array - * 9: short array - * 10: int array - * 11: long array - * u4 class serial number (may be zero during startup) - * u4 stack trace serial number - * u4 number of bytes alive - * u4 number of instances alive - * u4 number of bytes allocated - * u4]* number of instance allocated - * - * HPROF_START_THREAD a newly started thread. - * - * u4 thread serial number (> 0) - * id thread object ID - * u4 stack trace serial number - * id thread name ID - * id thread group name ID - * id thread group parent name ID - * - * HPROF_END_THREAD a terminating thread. - * - * u4 thread serial number - * - * HPROF_HEAP_SUMMARY heap summary - * - * u4 total live bytes - * u4 total live instances - * u8 total bytes allocated - * u8 total instances allocated - * - * HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT denote a heap dump - * - * [heap dump sub-records]* - * - * There are four kinds of heap dump sub-records: - * - * u1 sub-record type - * - * HPROF_GC_ROOT_UNKNOWN unknown root - * - * id object ID - * - * HPROF_GC_ROOT_THREAD_OBJ thread object - * - * id thread object ID (may be 0 for a - * thread newly attached through JNI) - * u4 thread sequence number - * u4 stack trace sequence number - * - * HPROF_GC_ROOT_JNI_GLOBAL JNI global ref root - * - * id object ID - * id JNI global ref ID - * - * HPROF_GC_ROOT_JNI_LOCAL JNI local ref - * - * id object ID - * u4 thread serial number - * u4 frame # in stack trace (-1 for empty) - * - * HPROF_GC_ROOT_JAVA_FRAME Java stack frame - * - * id object ID - * u4 thread serial number - * u4 frame # in stack trace (-1 for empty) - * - * HPROF_GC_ROOT_NATIVE_STACK Native stack - * - * id object ID - * u4 thread serial number - * - * HPROF_GC_ROOT_STICKY_CLASS System class - * - * id object ID - * - * HPROF_GC_ROOT_THREAD_BLOCK Reference from thread block - * - * id object ID - * u4 thread serial number - * - * HPROF_GC_ROOT_MONITOR_USED Busy monitor - * - * id object ID - * - * HPROF_GC_CLASS_DUMP dump of a class object - * - * id class object ID - * u4 stack trace serial number - * id super class object ID - * id class loader object ID - * id signers object ID - * id protection domain object ID - * id reserved - * id reserved - * - * u4 instance size (in bytes) - * - * u2 size of constant pool - * [u2, constant pool index, - * ty, type - * 2: object - * 4: boolean - * 5: char - * 6: float - * 7: double - * 8: byte - * 9: short - * 10: int - * 11: long - * vl]* and value - * - * u2 number of static fields - * [id, static field name, - * ty, type, - * vl]* and value - * - * u2 number of inst. fields (not inc. super) - * [id, instance field name, - * ty]* type - * - * HPROF_GC_INSTANCE_DUMP dump of a normal object - * - * id object ID - * u4 stack trace serial number - * id class object ID - * u4 number of bytes that follow - * [vl]* instance field values (class, followed - * by super, super's super ...) - * - * HPROF_GC_OBJ_ARRAY_DUMP dump of an object array - * - * id array object ID - * u4 stack trace serial number - * u4 number of elements - * id array class ID - * [id]* elements - * - * HPROF_GC_PRIM_ARRAY_DUMP dump of a primitive array - * - * id array object ID - * u4 stack trace serial number - * u4 number of elements - * u1 element type - * 4: boolean array - * 5: char array - * 6: float array - * 7: double array - * 8: byte array - * 9: short array - * 10: int array - * 11: long array - * [u1]* elements - * - * HPROF_HEAP_DUMP_END terminates series of heap dump segments - * - * HPROF_CPU_SAMPLES a set of sample traces of running threads - * - * u4 total number of samples - * u4 # of traces - * [u4 # of samples - * u4]* stack trace serial number - * - * HPROF_CONTROL_SETTINGS the settings of on/off switches - * - * u4 0x00000001: alloc traces on/off - * 0x00000002: cpu sampling on/off - * u2 stack trace depth - * - */ - -typedef enum HprofTag { - HPROF_UTF8 = 0x01, - HPROF_LOAD_CLASS = 0x02, - HPROF_UNLOAD_CLASS = 0x03, - HPROF_FRAME = 0x04, - HPROF_TRACE = 0x05, - HPROF_ALLOC_SITES = 0x06, - HPROF_HEAP_SUMMARY = 0x07, - HPROF_START_THREAD = 0x0A, - HPROF_END_THREAD = 0x0B, - HPROF_HEAP_DUMP = 0x0C, - HPROF_HEAP_DUMP_SEGMENT = 0x1C, /* 1.0.2 only */ - HPROF_HEAP_DUMP_END = 0x2C, /* 1.0.2 only */ - HPROF_CPU_SAMPLES = 0x0D, - HPROF_CONTROL_SETTINGS = 0x0E -} HprofTag; - -/* - * Heap dump constants - */ - -typedef enum HprofGcTag { - HPROF_GC_ROOT_UNKNOWN = 0xFF, - HPROF_GC_ROOT_JNI_GLOBAL = 0x01, - HPROF_GC_ROOT_JNI_LOCAL = 0x02, - HPROF_GC_ROOT_JAVA_FRAME = 0x03, - HPROF_GC_ROOT_NATIVE_STACK = 0x04, - HPROF_GC_ROOT_STICKY_CLASS = 0x05, - HPROF_GC_ROOT_THREAD_BLOCK = 0x06, - HPROF_GC_ROOT_MONITOR_USED = 0x07, - HPROF_GC_ROOT_THREAD_OBJ = 0x08, - HPROF_GC_CLASS_DUMP = 0x20, - HPROF_GC_INSTANCE_DUMP = 0x21, - HPROF_GC_OBJ_ARRAY_DUMP = 0x22, - HPROF_GC_PRIM_ARRAY_DUMP = 0x23 -} HprofGcTag; - -enum HprofType { - HPROF_ARRAY_OBJECT = 1, - HPROF_NORMAL_OBJECT = 2, - HPROF_BOOLEAN = 4, - HPROF_CHAR = 5, - HPROF_FLOAT = 6, - HPROF_DOUBLE = 7, - HPROF_BYTE = 8, - HPROF_SHORT = 9, - HPROF_INT = 10, - HPROF_LONG = 11 -}; -typedef unsigned char HprofType; - -#define HPROF_TYPE_SIZES \ - { \ - /*Object?*/ sizeof(HprofId), \ - /*Object?*/ sizeof(HprofId), \ - /*Array*/ sizeof(HprofId), \ - /*Object?*/ sizeof(HprofId), \ - /*jboolean*/ 1, \ - /*jchar*/ 2, \ - /*jfloat*/ 4, \ - /*jdouble*/ 8, \ - /*jbyte*/ 1, \ - /*jshort*/ 2, \ - /*jint*/ 4, \ - /*jlong*/ 8 \ - } - -#define HPROF_TYPE_IS_PRIMITIVE(ty) ((ty)>=HPROF_BOOLEAN) - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +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. - */ - - -/* Allocations from large blocks, no individual free's */ - -#include "hprof.h" - -/* - * This file contains some allocation code that allows you - * to have space allocated via larger blocks of space. - * The only free allowed is of all the blocks and all the elements. - * Elements can be of different alignments and fixed or variable sized. - * The space allocated never moves. - * - */ - -/* Get the real size allocated based on alignment and bytes needed */ -static int -real_size(int alignment, int nbytes) -{ - if ( alignment > 1 ) { - int wasted; - - wasted = alignment - ( nbytes % alignment ); - if ( wasted != alignment ) { - nbytes += wasted; - } - } - return nbytes; -} - -/* Add a new current_block to the Blocks* chain, adjust size if nbytes big. */ -static void -add_block(Blocks *blocks, int nbytes) -{ - int header_size; - int block_size; - BlockHeader *block_header; - - HPROF_ASSERT(blocks!=NULL); - HPROF_ASSERT(nbytes>0); - - header_size = real_size(blocks->alignment, sizeof(BlockHeader)); - block_size = blocks->elem_size*blocks->population; - if ( nbytes > block_size ) { - block_size = real_size(blocks->alignment, nbytes); - } - block_header = (BlockHeader*)HPROF_MALLOC(block_size+header_size); - block_header->next = NULL; - block_header->bytes_left = block_size; - block_header->next_pos = header_size; - - /* Link in new block */ - if ( blocks->current_block != NULL ) { - blocks->current_block->next = block_header; - } - blocks->current_block = block_header; - if ( blocks->first_block == NULL ) { - blocks->first_block = block_header; - } -} - -/* Initialize a new Blocks */ -Blocks * -blocks_init(int alignment, int elem_size, int population) -{ - Blocks *blocks; - - HPROF_ASSERT(alignment>0); - HPROF_ASSERT(elem_size>0); - HPROF_ASSERT(population>0); - - blocks = (Blocks*)HPROF_MALLOC(sizeof(Blocks)); - blocks->alignment = alignment; - blocks->elem_size = elem_size; - blocks->population = population; - blocks->first_block = NULL; - blocks->current_block = NULL; - return blocks; -} - -/* Allocate bytes from a Blocks area. */ -void * -blocks_alloc(Blocks *blocks, int nbytes) -{ - BlockHeader *block; - int pos; - void *ptr; - - HPROF_ASSERT(blocks!=NULL); - HPROF_ASSERT(nbytes>=0); - if ( nbytes == 0 ) { - return NULL; - } - - block = blocks->current_block; - nbytes = real_size(blocks->alignment, nbytes); - if ( block == NULL || block->bytes_left < nbytes ) { - add_block(blocks, nbytes); - block = blocks->current_block; - } - pos = block->next_pos; - ptr = (void*)(((char*)block)+pos); - block->next_pos += nbytes; - block->bytes_left -= nbytes; - return ptr; -} - -/* Terminate the Blocks */ -void -blocks_term(Blocks *blocks) -{ - BlockHeader *block; - - HPROF_ASSERT(blocks!=NULL); - - block = blocks->first_block; - while ( block != NULL ) { - BlockHeader *next_block; - - next_block = block->next; - HPROF_FREE(block); - block = next_block; - } - HPROF_FREE(blocks); -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +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. - */ - - -#ifndef HPROF_BLOCKS_H -#define HPROF_BLOCKS_H - -typedef struct BlockHeader { - struct BlockHeader *next; - int bytes_left; - int next_pos; -} BlockHeader; - -typedef struct Blocks { - BlockHeader *first_block; /* Pointer to first BlockHeader */ - BlockHeader *current_block; /* Pointer to current BlockHeader */ - int alignment; /* Data alignment, 1, 2, 4, 8, 16 */ - int elem_size; /* Size in bytes, ==1 means variable sizes */ - int population; /* Number of elements to allow for per Block */ -} Blocks; - -Blocks * blocks_init(int alignment, int elem_size, int population); -void * blocks_alloc(Blocks *blocks, int nbytes); -void blocks_term(Blocks *blocks); - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1152 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - - -/* Functionality for checking hprof format=b output. */ - -/* ONLY used with logflags=4. */ - -/* Verifies and write a verbose textual version of a format=b file. - * Textual output file is gdata->checkfilename, fd is gdata->check_fd. - * Buffer is in gdata too, see gdata->check* variables. - * Could probably be isolated to a separate library or utility. - */ - -#include "hprof.h" - -typedef TableIndex HprofId; - -#include "hprof_b_spec.h" - -static int type_size[ /*HprofType*/ ] = HPROF_TYPE_SIZES; - -/* For map from HPROF_UTF8 to a string */ -typedef struct UmapInfo { - char *str; -} UmapInfo; - -/* Field information */ -typedef struct Finfo { - HprofId id; - HprofType ty; -} Finfo; - -/* Class information map from class ID (ClassIndex) to class information */ -typedef struct CmapInfo { - int max_finfo; - int n_finfo; - Finfo *finfo; - int inst_size; - HprofId sup; -} CmapInfo; - -/* Read raw bytes from the file image, update the pointer */ -static void -read_raw(unsigned char **pp, unsigned char *buf, int len) -{ - while ( len > 0 ) { - *buf = **pp; - buf++; - (*pp)++; - len--; - } -} - -/* Read various sized elements, properly converted from big to right endian. - * File will contain big endian format. - */ -static unsigned -read_u1(unsigned char **pp) -{ - unsigned char b; - - read_raw(pp, &b, 1); - return b; -} -static unsigned -read_u2(unsigned char **pp) -{ - unsigned short s; - - read_raw(pp, (void*)&s, 2); - return md_htons(s); -} -static unsigned -read_u4(unsigned char **pp) -{ - unsigned int u; - - read_raw(pp, (void*)&u, 4); - return md_htonl(u); -} -static jlong -read_u8(unsigned char **pp) -{ - unsigned int high; - unsigned int low; - jlong x; - - high = read_u4(pp); - low = read_u4(pp); - x = high; - x = (x << 32) | low; - return x; -} -static HprofId -read_id(unsigned char **pp) -{ - return (HprofId)read_u4(pp); -} - -/* System error routine */ -static void -system_error(const char *system_call, int rc, int errnum) -{ - char buf[256]; - char details[256]; - - details[0] = 0; - if ( errnum != 0 ) { - md_system_error(details, (int)sizeof(details)); - } else if ( rc >= 0 ) { - (void)strcpy(details,"Only part of buffer processed"); - } - if ( details[0] == 0 ) { - (void)strcpy(details,"Unknown system error condition"); - } - (void)md_snprintf(buf, sizeof(buf), "System %s failed: %s\n", - system_call, details); - HPROF_ERROR(JNI_TRUE, buf); -} - -/* Write to a fd */ -static void -system_write(int fd, void *buf, int len) -{ - int res; - - HPROF_ASSERT(fd>=0); - res = md_write(fd, buf, len); - if (res < 0 || res!=len) { - system_error("write", res, errno); - } -} - -/* Flush check buffer */ -static void -check_flush(void) -{ - if ( gdata->check_fd < 0 ) { - return; - } - if (gdata->check_buffer_index) { - system_write(gdata->check_fd, gdata->check_buffer, gdata->check_buffer_index); - gdata->check_buffer_index = 0; - } -} - -/* Read out a given typed element */ -static jvalue -read_val(unsigned char **pp, HprofType ty) -{ - jvalue val; - static jvalue empty_val; - - val = empty_val; - switch ( ty ) { - case 0: - case HPROF_ARRAY_OBJECT: - case HPROF_NORMAL_OBJECT: - val.i = read_id(pp); - break; - case HPROF_BYTE: - case HPROF_BOOLEAN: - val.b = read_u1(pp); - break; - case HPROF_CHAR: - case HPROF_SHORT: - val.s = read_u2(pp); - break; - case HPROF_FLOAT: - case HPROF_INT: - val.i = read_u4(pp); - break; - case HPROF_DOUBLE: - case HPROF_LONG: - val.j = read_u8(pp); - break; - default: - HPROF_ERROR(JNI_TRUE, "bad type number"); - break; - } - return val; -} - -/* Move arbitrary byte stream into gdata->check_fd */ -static void -check_raw(void *buf, int len) -{ - if ( gdata->check_fd < 0 ) { - return; - } - - if ( len <= 0 ) { - return; - } - - if (gdata->check_buffer_index + len > gdata->check_buffer_size) { - check_flush(); - if (len > gdata->check_buffer_size) { - system_write(gdata->check_fd, buf, len); - return; - } - } - (void)memcpy(gdata->check_buffer + gdata->check_buffer_index, buf, len); - gdata->check_buffer_index += len; -} - -/* Printf for gdata->check_fd */ -static void -check_printf(char *fmt, ...) -{ - char buf[1024]; - va_list args; - - if ( gdata->check_fd < 0 ) { - return; - } - - va_start(args, fmt); - (void)md_vsnprintf(buf, sizeof(buf), fmt, args); - buf[sizeof(buf)-1] = 0; - check_raw(buf, (int)strlen(buf)); - va_end(args); -} - -/* Printf of an element for gdata->check_fd */ -static void -check_printf_val(HprofType ty, jvalue val, int long_form) -{ - jint low; - jint high; - - switch ( ty ) { - case HPROF_ARRAY_OBJECT: - check_printf("0x%08x", val.i); - break; - case HPROF_NORMAL_OBJECT: - check_printf("0x%08x", val.i); - break; - case HPROF_BOOLEAN: - check_printf("0x%02x", val.b); - break; - case HPROF_CHAR: - if ( long_form ) { - if ( val.s < 0 || val.s > 0x7f || !isprint(val.s) ) { - check_printf("0x%04x", val.s); - } else { - check_printf("0x%04x(%c)", val.s, val.s); - } - } else { - if ( val.s < 0 || val.s > 0x7f || !isprint(val.s) ) { - check_printf("\\u%04x", val.s); - } else { - check_printf("%c", val.s); - } - } - break; - case HPROF_FLOAT: - low = jlong_low(val.j); - check_printf("0x%08x(%f)", low, (double)val.f); - break; - case HPROF_DOUBLE: - high = jlong_high(val.j); - low = jlong_low(val.j); - check_printf("0x%08x%08x(%f)", high, low, val.d); - break; - case HPROF_BYTE: - check_printf("0x%02x", val.b); - break; - case HPROF_SHORT: - check_printf("0x%04x", val.s); - break; - case HPROF_INT: - check_printf("0x%08x", val.i); - break; - case HPROF_LONG: - high = jlong_high(val.j); - low = jlong_low(val.j); - check_printf("0x%08x%08x", high, low); - break; - } -} - -/* Printf of a string for gdata->check_fd */ -static void -check_printf_str(char *str) -{ - int len; - int i; - - if ( str == NULL ) { - check_printf(""); - } - check_printf("\""); - len = (int)strlen(str); - for (i = 0; i < len; i++) { - unsigned char c; - c = str[i]; - if ( isprint(c) ) { - check_printf("%c", c); - } else { - check_printf("\\x%02x", c); - } - } - check_printf("\""); -} - -/* Printf of a utf8 id for gdata->check_fd */ -static void -check_print_utf8(struct LookupTable *utab, char *prefix, HprofId id) -{ - TableIndex uindex; - - if ( id == 0 ) { - check_printf("%s0x%x", prefix, id); - } else { - uindex = table_find_entry(utab, &id, sizeof(id)); - if ( uindex == 0 ) { - check_printf("%s0x%x", prefix, id); - } else { - UmapInfo *umap; - - umap = (UmapInfo*)table_get_info(utab, uindex); - HPROF_ASSERT(umap!=NULL); - HPROF_ASSERT(umap->str!=NULL); - check_printf("%s0x%x->", prefix, id); - check_printf_str(umap->str); - } - } -} - -/* Add a instance field information to this cmap. */ -static void -add_inst_field_to_cmap(CmapInfo *cmap, HprofId id, HprofType ty) -{ - int i; - - HPROF_ASSERT(cmap!=NULL); - i = cmap->n_finfo++; - if ( i+1 >= cmap->max_finfo ) { - int osize; - Finfo *new_finfo; - - osize = cmap->max_finfo; - cmap->max_finfo += 12; - new_finfo = (Finfo*)HPROF_MALLOC(cmap->max_finfo*(int)sizeof(Finfo)); - (void)memset(new_finfo,0,cmap->max_finfo*(int)sizeof(Finfo)); - if ( i == 0 ) { - cmap->finfo = new_finfo; - } else { - (void)memcpy(new_finfo,cmap->finfo,osize*(int)sizeof(Finfo)); - HPROF_FREE(cmap->finfo); - cmap->finfo = new_finfo; - } - } - cmap->finfo[i].id = id; - cmap->finfo[i].ty = ty; -} - -/* LookupTable callback for cmap entry cleanup */ -static void -cmap_cleanup(TableIndex i, void *key_ptr, int key_len, void*info, void*data) -{ - CmapInfo *cmap = info; - - if ( cmap == NULL ) { - return; - } - if ( cmap->finfo != NULL ) { - HPROF_FREE(cmap->finfo); - cmap->finfo = NULL; - } -} - -/* Case label for a switch on hprof heap dump elements */ -#define CASE_HEAP(name) case name: label = #name; - -/* Given the heap dump data and the utf8 map, check/write the heap dump. */ -static int -check_heap_tags(struct LookupTable *utab, unsigned char *pstart, int nbytes) -{ - int nrecords; - unsigned char *p; - unsigned char *psave; - struct LookupTable *ctab; - CmapInfo cmap; - char *label; - unsigned tag; - HprofType ty; - HprofId id, id2, fr, sup; - int num_elements; - int num_bytes; - SerialNumber trace_serial_num; - SerialNumber thread_serial_num; - int npos; - int i; - int inst_size; - - ctab = table_initialize("temp ctab", 64, 64, 512, sizeof(CmapInfo)); - - /* First pass over heap records just fills in the CmapInfo table */ - nrecords = 0; - p = pstart; - while ( p < (pstart+nbytes) ) { - nrecords++; - /*LINTED*/ - npos = (int)(p - pstart); - tag = read_u1(&p); - switch ( tag ) { - CASE_HEAP(HPROF_GC_ROOT_UNKNOWN) - id = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_JNI_GLOBAL) - id = read_id(&p); - id2 = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_JNI_LOCAL) - id = read_id(&p); - thread_serial_num = read_u4(&p); - fr = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_JAVA_FRAME) - id = read_id(&p); - thread_serial_num = read_u4(&p); - fr = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_NATIVE_STACK) - id = read_id(&p); - thread_serial_num = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_STICKY_CLASS) - id = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_THREAD_BLOCK) - id = read_id(&p); - thread_serial_num = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_MONITOR_USED) - id = read_id(&p); - break; - CASE_HEAP(HPROF_GC_ROOT_THREAD_OBJ) - id = read_id(&p); - thread_serial_num = read_u4(&p); - trace_serial_num = read_u4(&p); - break; - CASE_HEAP(HPROF_GC_CLASS_DUMP) - (void)memset((void*)&cmap, 0, sizeof(cmap)); - id = read_id(&p); - trace_serial_num = read_u4(&p); - { - HprofId ld, si, pr, re1, re2; - - sup = read_id(&p); - ld = read_id(&p); - si = read_id(&p); - pr = read_id(&p); - re1 = read_id(&p); - re2 = read_id(&p); - cmap.sup = sup; - } - inst_size = read_u4(&p); - cmap.inst_size = inst_size; - num_elements = read_u2(&p); - for(i=0; i 0 ) { - TableIndex cindex; - int ifield; - CmapInfo *map; - - cindex = table_find_entry(ctab, &id2, sizeof(id2)); - HPROF_ASSERT(cindex!=0); - map = (CmapInfo*)table_get_info(ctab, cindex); - HPROF_ASSERT(map!=NULL); - HPROF_ASSERT(num_bytes==map->inst_size); - - psave = p; - ifield = 0; - - do { - for(i=0;in_finfo;i++) { - HprofType ty; - HprofId id; - jvalue val; - - ty = map->finfo[i].ty; - id = map->finfo[i].id; - HPROF_ASSERT(ty!=0); - HPROF_ASSERT(id!=0); - val = read_val(&p, ty); - check_printf(" field %d: ", ifield); - check_print_utf8(utab, "id=", id); - check_printf(", ty=%d, val=", ty); - check_printf_val(ty, val, 1); - check_printf("\n"); - ifield++; - } - id2 = map->sup; - map = NULL; - cindex = 0; - if ( id2 != 0 ) { - cindex = table_find_entry(ctab, &id2, sizeof(id2)); - HPROF_ASSERT(cindex!=0); - map = (CmapInfo*)table_get_info(ctab, cindex); - HPROF_ASSERT(map!=NULL); - } - } while ( map != NULL ); - HPROF_ASSERT(num_bytes==(p-psave)); - } - break; - CASE_HEAP(HPROF_GC_OBJ_ARRAY_DUMP) - id = read_id(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - num_elements = read_u4(&p); - id2 = read_id(&p); - check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u, nelems=%d, eid=0x%x\n", - nrecords, npos, label, id, trace_serial_num, num_elements, id2); - for(i=0; i 0 ) { - int count; - int long_form; - int max_count; - char *quote; - - quote = ""; - long_form = 1; - max_count = 8; - count = 0; - switch ( ty ) { - case HPROF_CHAR: - long_form = 0; - max_count = 72; - quote = "\""; - /*FALLTHRU*/ - case HPROF_INT: - case HPROF_DOUBLE: - case HPROF_LONG: - case HPROF_BYTE: - case HPROF_BOOLEAN: - case HPROF_SHORT: - case HPROF_FLOAT: - check_printf(" val=%s", quote); - for(i=0; i 0 && count == 0 ) { - check_printf(" %s", quote); - } - val = read_val(&p, ty); - check_printf_val(ty, val, long_form); - count += 1; - if ( count >= max_count ) { - check_printf("\"\n"); - count = 0; - } - } - if ( count != 0 ) { - check_printf("%s\n", quote); - } - break; - } - } - HPROF_ASSERT(type_size[ty]*num_elements==(p-psave)); - break; - default: - label = "UNKNOWN"; - check_printf("H#%d@%d %s: ERROR!\n", - nrecords, npos, label); - HPROF_ERROR(JNI_TRUE, "unknown heap record type"); - break; - } - } - CHECK_FOR_ERROR(p==pstart+nbytes); - - table_cleanup(ctab, &cmap_cleanup, NULL); - - return nrecords; -} - -/* LookupTable cleanup callback for utab */ -static void -utab_cleanup(TableIndex i, void *key_ptr, int key_len, void*info, void*data) -{ - UmapInfo *umap = info; - - if ( umap == NULL ) { - return; - } - if ( umap->str != NULL ) { - HPROF_FREE(umap->str); - umap->str = NULL; - } -} - -/* Check all the heap tags in a heap dump */ -static int -check_tags(unsigned char *pstart, int nbytes) -{ - unsigned char *p; - int nrecord; - struct LookupTable *utab; - UmapInfo umap; - - check_printf("\nCHECK TAGS: starting\n"); - - utab = table_initialize("temp utf8 map", 64, 64, 512, sizeof(UmapInfo)); - - /* Walk the tags, assumes UTF8 tags are defined before used */ - p = pstart; - nrecord = 0; - while ( p < (pstart+nbytes) ) { - unsigned tag; - unsigned size; - int nheap_records; - int npos; - char *label; - HprofId id, nm, sg, so, gr, gn; - int i, li, num_elements; - HprofType ty; - SerialNumber trace_serial_num; - SerialNumber thread_serial_num; - SerialNumber class_serial_num; - unsigned flags; - unsigned depth; - float cutoff; - unsigned temp; - jint nblive; - jint nilive; - jlong tbytes; - jlong tinsts; - jint total_samples; - jint trace_count; - - nrecord++; - /*LINTED*/ - npos = (int)(p - pstart); - tag = read_u1(&p); - (void)read_u4(&p); /* microsecs */ - size = read_u4(&p); - #define CASE_TAG(name) case name: label = #name; - switch ( tag ) { - CASE_TAG(HPROF_UTF8) - CHECK_FOR_ERROR(size>=(int)sizeof(HprofId)); - id = read_id(&p); - check_printf("#%d@%d: %s, sz=%d, name_id=0x%x, \"", - nrecord, npos, label, size, id); - num_elements = size-(int)sizeof(HprofId); - check_raw(p, num_elements); - check_printf("\"\n"); - /* Create entry in umap */ - umap.str = HPROF_MALLOC(num_elements+1); - (void)strncpy(umap.str, (char*)p, (size_t)num_elements); - umap.str[num_elements] = 0; - (void)table_create_entry(utab, &id, sizeof(id), &umap); - p += num_elements; - break; - CASE_TAG(HPROF_LOAD_CLASS) - CHECK_FOR_ERROR(size==2*4+2*(int)sizeof(HprofId)); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - id = read_id(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - nm = read_id(&p); - check_printf("#%d@%d: %s, sz=%d, class_serial_num=%u," - " id=0x%x, trace_serial_num=%u, name_id=0x%x\n", - nrecord, npos, label, size, class_serial_num, - id, trace_serial_num, nm); - break; - CASE_TAG(HPROF_UNLOAD_CLASS) - CHECK_FOR_ERROR(size==4); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - check_printf("#%d@%d: %s, sz=%d, class_serial_num=%u\n", - nrecord, npos, label, size, class_serial_num); - break; - CASE_TAG(HPROF_FRAME) - CHECK_FOR_ERROR(size==2*4+4*(int)sizeof(HprofId)); - id = read_id(&p); - nm = read_id(&p); - sg = read_id(&p); - so = read_id(&p); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - li = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, ", nrecord, npos, label, size); - check_print_utf8(utab, "id=", id); - check_printf(" name_id=0x%x, sig_id=0x%x, source_id=0x%x," - " class_serial_num=%u, lineno=%d\n", - nm, sg, so, class_serial_num, li); - break; - CASE_TAG(HPROF_TRACE) - CHECK_FOR_ERROR(size>=3*4); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - thread_serial_num = read_u4(&p); /* Can be 0 */ - num_elements = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, trace_serial_num=%u," - " thread_serial_num=%u, nelems=%d [", - nrecord, npos, label, size, - trace_serial_num, thread_serial_num, num_elements); - for(i=0; i< num_elements; i++) { - check_printf("0x%x,", read_id(&p)); - } - check_printf("]\n"); - break; - CASE_TAG(HPROF_ALLOC_SITES) - CHECK_FOR_ERROR(size>=2+4*4+2*8); - flags = read_u2(&p); - temp = read_u4(&p); - cutoff = *((float*)&temp); - nblive = read_u4(&p); - nilive = read_u4(&p); - tbytes = read_u8(&p); - tinsts = read_u8(&p); - num_elements = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, flags=0x%x, cutoff=%g," - " nblive=%d, nilive=%d, tbytes=(%d,%d)," - " tinsts=(%d,%d), num_elements=%d\n", - nrecord, npos, label, size, - flags, cutoff, nblive, nilive, - jlong_high(tbytes), jlong_low(tbytes), - jlong_high(tinsts), jlong_low(tinsts), - num_elements); - for(i=0; i< num_elements; i++) { - ty = read_u1(&p); - class_serial_num = read_u4(&p); - CHECK_CLASS_SERIAL_NO(class_serial_num); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - nblive = read_u4(&p); - nilive = read_u4(&p); - tbytes = read_u4(&p); - tinsts = read_u4(&p); - check_printf("\t %d: ty=%d, class_serial_num=%u," - " trace_serial_num=%u, nblive=%d, nilive=%d," - " tbytes=%d, tinsts=%d\n", - i, ty, class_serial_num, trace_serial_num, - nblive, nilive, (jint)tbytes, (jint)tinsts); - } - break; - CASE_TAG(HPROF_HEAP_SUMMARY) - CHECK_FOR_ERROR(size==2*4+2*8); - nblive = read_u4(&p); - nilive = read_u4(&p); - tbytes = read_u8(&p); - tinsts = read_u8(&p); - check_printf("#%d@%d: %s, sz=%d," - " nblive=%d, nilive=%d, tbytes=(%d,%d)," - " tinsts=(%d,%d)\n", - nrecord, npos, label, size, - nblive, nilive, - jlong_high(tbytes), jlong_low(tbytes), - jlong_high(tinsts), jlong_low(tinsts)); - break; - CASE_TAG(HPROF_START_THREAD) - CHECK_FOR_ERROR(size==2*4+4*(int)sizeof(HprofId)); - thread_serial_num = read_u4(&p); - CHECK_THREAD_SERIAL_NO(thread_serial_num); - id = read_id(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - nm = read_id(&p); - gr = read_id(&p); - gn = read_id(&p); - check_printf("#%d@%d: %s, sz=%d, thread_serial_num=%u," - " id=0x%x, trace_serial_num=%u, ", - nrecord, npos, label, size, - thread_serial_num, id, trace_serial_num); - check_print_utf8(utab, "nm=", id); - check_printf(" trace_serial_num=%u, nm=0x%x," - " gr=0x%x, gn=0x%x\n", - trace_serial_num, nm, gr, gn); - break; - CASE_TAG(HPROF_END_THREAD) - CHECK_FOR_ERROR(size==4); - thread_serial_num = read_u4(&p); - CHECK_THREAD_SERIAL_NO(thread_serial_num); - check_printf("#%d@%d: %s, sz=%d, thread_serial_num=%u\n", - nrecord, npos, label, size, thread_serial_num); - break; - CASE_TAG(HPROF_HEAP_DUMP) - check_printf("#%d@%d: BEGIN: %s, sz=%d\n", - nrecord, npos, label, size); - nheap_records = check_heap_tags(utab, p, size); - check_printf("#%d@%d: END: %s, sz=%d, nheap_recs=%d\n", - nrecord, npos, label, size, nheap_records); - p += size; - break; - CASE_TAG(HPROF_HEAP_DUMP_SEGMENT) /* 1.0.2 */ - check_printf("#%d@%d: BEGIN SEGMENT: %s, sz=%d\n", - nrecord, npos, label, size); - nheap_records = check_heap_tags(utab, p, size); - check_printf("#%d@%d: END SEGMENT: %s, sz=%d, nheap_recs=%d\n", - nrecord, npos, label, size, nheap_records); - p += size; - break; - CASE_TAG(HPROF_HEAP_DUMP_END) /* 1.0.2 */ - check_printf("#%d@%d: SEGMENT END: %s, sz=%d\n", - nrecord, npos, label, size); - break; - CASE_TAG(HPROF_CPU_SAMPLES) - CHECK_FOR_ERROR(size>=2*4); - total_samples = read_u4(&p); - trace_count = read_u4(&p); - check_printf("#%d@%d: %s, sz=%d, total_samples=%d," - " trace_count=%d\n", - nrecord, npos, label, size, - total_samples, trace_count); - for(i=0; i< trace_count; i++) { - num_elements = read_u4(&p); - trace_serial_num = read_u4(&p); - CHECK_TRACE_SERIAL_NO(trace_serial_num); - check_printf("\t %d: samples=%d, trace_serial_num=%u\n", - trace_serial_num, num_elements); - } - break; - CASE_TAG(HPROF_CONTROL_SETTINGS) - CHECK_FOR_ERROR(size==4+2); - flags = read_u4(&p); - depth = read_u2(&p); - check_printf("#%d@%d: %s, sz=%d, flags=0x%x, depth=%d\n", - nrecord, npos, label, size, flags, depth); - break; - default: - label = "UNKNOWN"; - check_printf("#%d@%d: %s, sz=%d\n", - nrecord, npos, label, size); - HPROF_ERROR(JNI_TRUE, "unknown record type"); - p += size; - break; - } - CHECK_FOR_ERROR(p<=(pstart+nbytes)); - } - check_flush(); - CHECK_FOR_ERROR(p==(pstart+nbytes)); - table_cleanup(utab, &utab_cleanup, NULL); - return nrecord; -} - -/* Read the entire file into memory */ -static void * -get_binary_file_image(char *filename, int *pnbytes) -{ - unsigned char *image; - int fd; - jlong nbytes; - int nread; - - *pnbytes = 0; - fd = md_open_binary(filename); - CHECK_FOR_ERROR(fd>=0); - if ( (nbytes = md_seek(fd, (jlong)-1)) == (jlong)-1 ) { - HPROF_ERROR(JNI_TRUE, "Cannot md_seek() to end of file"); - } - CHECK_FOR_ERROR(((jint)nbytes)>512); - if ( md_seek(fd, (jlong)0) != (jlong)0 ) { - HPROF_ERROR(JNI_TRUE, "Cannot md_seek() to start of file"); - } - image = HPROF_MALLOC(((jint)nbytes)+1); - CHECK_FOR_ERROR(image!=NULL); - - /* Read the entire file image into memory */ - nread = md_read(fd, image, (jint)nbytes); - if ( nread <= 0 ) { - HPROF_ERROR(JNI_TRUE, "System read failed."); - } - CHECK_FOR_ERROR(((jint)nbytes)==nread); - md_close(fd); - *pnbytes = (jint)nbytes; - return image; -} - -/* ------------------------------------------------------------------ */ - -void -check_binary_file(char *filename) -{ - unsigned char *image; - unsigned char *p; - unsigned idsize; - int nbytes; - int nrecords; - - image = get_binary_file_image(filename, &nbytes); - if ( image == NULL ) { - check_printf("No file image: %s\n", filename); - return; - } - p = image; - CHECK_FOR_ERROR(strcmp((char*)p, gdata->header)==0); - check_printf("Filename=%s, nbytes=%d, header=\"%s\"\n", - filename, nbytes, p); - p+=((int)strlen((char*)p)+1); - idsize = read_u4(&p); - CHECK_FOR_ERROR(idsize==sizeof(HprofId)); - (void)read_u4(&p); - (void)read_u4(&p); - /* LINTED */ - nrecords = check_tags(p, nbytes - (int)( p - image ) ); - check_printf("#%d total records found in %d bytes\n", nrecords, nbytes); - HPROF_FREE(image); -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_check.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2005, 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 HPROF_CHECK_H -#define HPROF_CHECK_H - -#define CHECK_FOR_ERROR(condition) \ - ( (condition) ? \ - (void)0 : \ - HPROF_ERROR(JNI_TRUE, #condition) ) -#define CHECK_SERIAL_NO(name, sno) \ - CHECK_FOR_ERROR( (sno) >= gdata->name##_serial_number_start && \ - (sno) < gdata->name##_serial_number_counter) -#define CHECK_CLASS_SERIAL_NO(sno) CHECK_SERIAL_NO(class,sno) -#define CHECK_THREAD_SERIAL_NO(sno) CHECK_SERIAL_NO(thread,sno) -#define CHECK_TRACE_SERIAL_NO(sno) CHECK_SERIAL_NO(trace,sno) -#define CHECK_OBJECT_SERIAL_NO(sno) CHECK_SERIAL_NO(object,sno) - -void check_binary_file(char *filename); - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,686 +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. - */ - - -/* Table of class information. - * - * Each element in this table is identified with a ClassIndex. - * Each element is uniquely identified by it's signature and loader. - * Every class load has a unique class serial number. - * While loaded, each element will have a cache of a global reference - * to it's jclass object, plus jmethodID's as needed. - * Method signatures and names are obtained via BCI. - * Methods can be identified with a ClassIndex and MethodIndex pair, - * where the MethodIndex matches the index of the method name and - * signature arrays obtained from the BCI pass. - * Strings are stored in the string table and a StringIndex is used. - * Class Loaders are stored in the loader table and a LoaderIndex is used. - * Since the jclass object is an object, at some point an object table - * entry may be allocated for the jclass as an ObjectIndex. - */ - -#include "hprof.h" - -/* Effectively represents a jclass object. */ - -/* These table elements are made unique by and sorted by signature name. */ - -typedef struct ClassKey { - StringIndex sig_string_index; /* Signature of class */ - LoaderIndex loader_index; /* Index for class loader */ -} ClassKey; - -/* Each class could contain method information, gotten from BCI callback */ - -typedef struct MethodInfo { - StringIndex name_index; /* Method name, index into string table */ - StringIndex sig_index; /* Method signature, index into string table */ - jmethodID method_id; /* Method ID, possibly NULL at first */ -} MethodInfo; - -/* The basic class information we save */ - -typedef struct ClassInfo { - jclass classref; /* Global ref to jclass */ - MethodInfo *method; /* Array of method data */ - int method_count; /* Count of methods */ - ObjectIndex object_index; /* Optional object index for jclass */ - SerialNumber serial_num; /* Unique to the actual class load */ - ClassStatus status; /* Current class status (bit mask) */ - ClassIndex super; /* Super class in this table */ - StringIndex name; /* Name of class */ - jint inst_size; /* #bytes needed for instance fields */ - jint field_count; /* Number of all fields */ - FieldInfo *field; /* Pointer to all FieldInfo's */ -} ClassInfo; - -/* Private interfaces */ - -static ClassKey* -get_pkey(ClassIndex index) -{ - void *key_ptr; - int key_len; - - table_get_key(gdata->class_table, index, (void*)&key_ptr, &key_len); - HPROF_ASSERT(key_len==sizeof(ClassKey)); - HPROF_ASSERT(key_ptr!=NULL); - return (ClassKey*)key_ptr; -} - -static void -fillin_pkey(const char *sig, LoaderIndex loader_index, ClassKey *pkey) -{ - static ClassKey empty_key; - - HPROF_ASSERT(loader_index!=0); - *pkey = empty_key; - pkey->sig_string_index = string_find_or_create(sig); - pkey->loader_index = loader_index; -} - -static ClassInfo * -get_info(ClassIndex index) -{ - ClassInfo *info; - - info = (ClassInfo*)table_get_info(gdata->class_table, index); - return info; -} - -static void -fill_info(TableIndex index, ClassKey *pkey) -{ - ClassInfo *info; - char *sig; - - info = get_info(index); - info->serial_num = gdata->class_serial_number_counter++; - info->method_count = 0; - info->inst_size = -1; - info->field_count = -1; - info->field = NULL; - sig = string_get(pkey->sig_string_index); - if ( sig[0] != JVM_SIGNATURE_CLASS ) { - info->name = pkey->sig_string_index; - } else { - int len; - - len = string_get_len(pkey->sig_string_index); - if ( len > 2 ) { - char *name; - - /* Class signature looks like "Lname;", we want "name" here. */ - name = HPROF_MALLOC(len-1); - (void)memcpy(name, sig+1, len-2); - name[len-2] = 0; - info->name = string_find_or_create(name); - HPROF_FREE(name); - } else { - /* This would be strange, a class signature not in "Lname;" form? */ - info->name = pkey->sig_string_index; - } - } -} - -static ClassIndex -find_entry(ClassKey *pkey) -{ - ClassIndex index; - - index = table_find_entry(gdata->class_table, - (void*)pkey, (int)sizeof(ClassKey)); - return index; -} - -static ClassIndex -create_entry(ClassKey *pkey) -{ - ClassIndex index; - - index = table_create_entry(gdata->class_table, - (void*)pkey, (int)sizeof(ClassKey), NULL); - fill_info(index, pkey); - return index; -} - -static ClassIndex -find_or_create_entry(ClassKey *pkey) -{ - ClassIndex index; - - HPROF_ASSERT(pkey!=NULL); - HPROF_ASSERT(pkey->loader_index!=0); - index = find_entry(pkey); - if ( index == 0 ) { - index = create_entry(pkey); - } - return index; -} - -static void -delete_classref(JNIEnv *env, ClassInfo *info, jclass klass) -{ - jclass ref; - int i; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(info!=NULL); - - for ( i = 0 ; i < info->method_count ; i++ ) { - info->method[i].method_id = NULL; - } - ref = info->classref; - if ( klass != NULL ) { - info->classref = newGlobalReference(env, klass); - } else { - info->classref = NULL; - } - if ( ref != NULL ) { - deleteGlobalReference(env, ref); - } -} - -static void -cleanup_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - - /* Cleanup any information in this ClassInfo structure. */ - HPROF_ASSERT(key_ptr!=NULL); - HPROF_ASSERT(key_len==sizeof(ClassKey)); - HPROF_ASSERT(info_ptr!=NULL); - info = (ClassInfo *)info_ptr; - if ( info->method_count > 0 ) { - HPROF_FREE((void*)info->method); - info->method_count = 0; - info->method = NULL; - } - if ( info->field != NULL ) { - HPROF_FREE((void*)info->field); - info->field_count = 0; - info->field = NULL; - } -} - -static void -delete_ref_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - delete_classref((JNIEnv*)arg, (ClassInfo*)info_ptr, NULL); -} - -static void -list_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - ClassKey key; - char *sig; - int i; - - HPROF_ASSERT(key_ptr!=NULL); - HPROF_ASSERT(key_len==sizeof(ClassKey)); - HPROF_ASSERT(info_ptr!=NULL); - key = *((ClassKey*)key_ptr); - sig = string_get(key.sig_string_index); - info = (ClassInfo *)info_ptr; - debug_message( - "0x%08x: Class %s, SN=%u, status=0x%08x, ref=%p," - " method_count=%d\n", - index, - (const char *)sig, - info->serial_num, - info->status, - (void*)info->classref, - info->method_count); - if ( info->method_count > 0 ) { - for ( i = 0 ; i < info->method_count ; i++ ) { - debug_message( - " Method %d: \"%s\", sig=\"%s\", method=%p\n", - i, - string_get(info->method[i].name_index), - string_get(info->method[i].sig_index), - (void*)info->method[i].method_id); - } - } -} - -static void -all_status_remove(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - ClassStatus status; - - HPROF_ASSERT(info_ptr!=NULL); - /*LINTED*/ - status = (ClassStatus)(long)(ptrdiff_t)arg; - info = (ClassInfo *)info_ptr; - info->status &= (~status); -} - -static void -unload_walker(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - ClassInfo *info; - - HPROF_ASSERT(info_ptr!=NULL); - info = (ClassInfo *)info_ptr; - if ( ! ( info->status & CLASS_IN_LOAD_LIST ) ) { - if ( ! (info->status & (CLASS_SPECIAL|CLASS_SYSTEM|CLASS_UNLOADED)) ) { - io_write_class_unload(info->serial_num, info->object_index); - info->status |= CLASS_UNLOADED; - delete_classref((JNIEnv*)arg, info, NULL); - } - } -} - -/* External interfaces */ - -void -class_init(void) -{ - HPROF_ASSERT(gdata->class_table==NULL); - gdata->class_table = table_initialize("Class", 512, 512, 511, - (int)sizeof(ClassInfo)); -} - -ClassIndex -class_find_or_create(const char *sig, LoaderIndex loader_index) -{ - ClassKey key; - - fillin_pkey(sig, loader_index, &key); - return find_or_create_entry(&key); -} - -ClassIndex -class_create(const char *sig, LoaderIndex loader_index) -{ - ClassKey key; - - fillin_pkey(sig, loader_index, &key); - return create_entry(&key); -} - -void -class_prime_system_classes(void) -{ - /* Prime System classes? Anything before VM_START is System class. - * Or classes loaded before env arg is non-NULL. - * Or any of the classes listed below. - */ - static const char * signatures[] = - { - "Ljava/lang/Object;", - "Ljava/io/Serializable;", - "Ljava/lang/String;", - "Ljava/lang/Class;", - "Ljava/lang/ClassLoader;", - "Ljava/lang/System;", - "Ljava/lang/Thread;", - "Ljava/lang/ThreadGroup;", - }; - int n_signatures; - int i; - LoaderIndex loader_index; - - n_signatures = (int)sizeof(signatures)/(int)sizeof(signatures[0]); - loader_index = loader_find_or_create(NULL, NULL); - for ( i = 0 ; i < n_signatures ; i++ ) { - ClassInfo *info; - ClassIndex index; - ClassKey key; - - fillin_pkey(signatures[i], loader_index, &key); - index = find_or_create_entry(&key); - info = get_info(index); - info->status |= CLASS_SYSTEM; - } -} - -void -class_add_status(ClassIndex index, ClassStatus status) -{ - ClassInfo *info; - - info = get_info(index); - info->status |= status; -} - -ClassStatus -class_get_status(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->status; -} - -StringIndex -class_get_signature(ClassIndex index) -{ - ClassKey *pkey; - - pkey = get_pkey(index); - return pkey->sig_string_index; -} - -SerialNumber -class_get_serial_number(ClassIndex index) -{ - ClassInfo *info; - - if ( index == 0 ) { - return 0; - } - info = get_info(index); - return info->serial_num; -} - -void -class_all_status_remove(ClassStatus status) -{ - table_walk_items(gdata->class_table, &all_status_remove, - (void*)(ptrdiff_t)(long)status); -} - -void -class_do_unloads(JNIEnv *env) -{ - table_walk_items(gdata->class_table, &unload_walker, (void*)env); -} - -void -class_list(void) -{ - debug_message( - "--------------------- Class Table ------------------------\n"); - table_walk_items(gdata->class_table, &list_item, NULL); - debug_message( - "----------------------------------------------------------\n"); -} - -void -class_cleanup(void) -{ - table_cleanup(gdata->class_table, &cleanup_item, NULL); - gdata->class_table = NULL; -} - -void -class_delete_global_references(JNIEnv* env) -{ - table_walk_items(gdata->class_table, &delete_ref_item, (void*)env); -} - -void -class_set_methods(ClassIndex index, const char **name, const char **sig, - int count) -{ - ClassInfo *info; - int i; - - info = get_info(index); - if ( info->method_count > 0 ) { - HPROF_FREE((void*)info->method); - info->method_count = 0; - info->method = NULL; - } - info->method_count = count; - if ( count > 0 ) { - info->method = (MethodInfo *)HPROF_MALLOC(count*(int)sizeof(MethodInfo)); - for ( i = 0 ; i < count ; i++ ) { - info->method[i].name_index = string_find_or_create(name[i]); - info->method[i].sig_index = string_find_or_create(sig[i]); - info->method[i].method_id = NULL; - } - } -} - -jclass -class_new_classref(JNIEnv *env, ClassIndex index, jclass classref) -{ - ClassInfo *info; - - HPROF_ASSERT(classref!=NULL); - info = get_info(index); - if ( ! isSameObject(env, classref, info->classref) ) { - delete_classref(env, info, classref); - } - return info->classref; -} - -jclass -class_get_class(JNIEnv *env, ClassIndex index) -{ - ClassInfo *info; - jclass clazz; - - info = get_info(index); - clazz = info->classref; - if ( env != NULL && clazz == NULL ) { - WITH_LOCAL_REFS(env, 1) { - jclass new_clazz; - char *class_name; - - class_name = string_get(info->name); - /* This really only makes sense for the bootclass classes, - * since FindClass doesn't provide a way to load a class in - * a specific class loader. - */ - new_clazz = findClass(env, class_name); - if ( new_clazz == NULL ) { - HPROF_ERROR(JNI_TRUE, "Cannot load class with findClass"); - } - HPROF_ASSERT(new_clazz!=NULL); - clazz = class_new_classref(env, index, new_clazz); - } END_WITH_LOCAL_REFS; - HPROF_ASSERT(clazz!=NULL); - } - return clazz; -} - -jmethodID -class_get_methodID(JNIEnv *env, ClassIndex index, MethodIndex mnum) -{ - ClassInfo *info; - jmethodID method; - - info = get_info(index); - if (mnum >= info->method_count) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Illegal mnum"); - - return NULL; - } - method = info->method[mnum].method_id; - if ( method == NULL ) { - char * name; - char * sig; - jclass clazz; - - name = (char *)string_get(info->method[mnum].name_index); - if (name==NULL) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Name not found"); - - return NULL; - } - sig = (char *)string_get(info->method[mnum].sig_index); - HPROF_ASSERT(sig!=NULL); - clazz = class_get_class(env, index); - if ( clazz != NULL ) { - method = getMethodID(env, clazz, name, sig); - HPROF_ASSERT(method!=NULL); - info = get_info(index); - info->method[mnum].method_id = method; - } - } - return method; -} - -void -class_set_inst_size(ClassIndex index, jint inst_size) -{ - ClassInfo *info; - - info = get_info(index); - info->inst_size = inst_size; -} - -jint -class_get_inst_size(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->inst_size; -} - -void -class_set_object_index(ClassIndex index, ObjectIndex object_index) -{ - ClassInfo *info; - - info = get_info(index); - info->object_index = object_index; -} - -ObjectIndex -class_get_object_index(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->object_index; -} - -ClassIndex -class_get_super(ClassIndex index) -{ - ClassInfo *info; - - info = get_info(index); - return info->super; -} - -void -class_set_super(ClassIndex index, ClassIndex super) -{ - ClassInfo *info; - - info = get_info(index); - info->super = super; -} - -LoaderIndex -class_get_loader(ClassIndex index) -{ - ClassKey *pkey; - - pkey = get_pkey(index); - HPROF_ASSERT(pkey->loader_index!=0); - return pkey->loader_index; -} - -/* Get ALL class fields (supers too), return 1 on error, 0 if ok */ -jint -class_get_all_fields(JNIEnv *env, ClassIndex index, - jint *pfield_count, FieldInfo **pfield) -{ - ClassInfo *info; - FieldInfo *finfo; - jint count; - jint ret; - - count = 0; - finfo = NULL; - ret = 1; /* Default is to return an error condition */ - - info = get_info(index); - if ( info != NULL ) { - if ( info->field_count >= 0 ) { - /* Get cache */ - count = info->field_count; - finfo = info->field; - ret = 0; /* Return of cache data, no error */ - } else { - jclass klass; - - klass = info->classref; - if ( klass == NULL || isSameObject(env, klass, NULL) ) { - /* This is probably an error because this will cause the field - * index values to be off, but I'm hesitant to generate a - * fatal error here, so I will issue something and continue. - * I should have been holding a global reference to all the - * jclass, so I'm not sure how this could happen. - * Issuing a FindClass() here is just asking for trouble - * because if the class went away, we aren't even sure - * what ClassLoader to use. - */ - HPROF_ERROR(JNI_FALSE, "Missing jclass when fields needed"); - } else { - jint status; - - status = getClassStatus(klass); - if ( status & - (JVMTI_CLASS_STATUS_PRIMITIVE|JVMTI_CLASS_STATUS_ARRAY) ) { - /* Set cache */ - info->field_count = count; - info->field = finfo; - ret = 0; /* Primitive or array ok */ - } else if ( status & JVMTI_CLASS_STATUS_PREPARED ) { - /* Call JVMTI to get them */ - getAllClassFieldInfo(env, klass, &count, &finfo); - /* Set cache */ - info->field_count = count; - info->field = finfo; - ret = 0; - } - } - } - } - *pfield_count = count; - *pfield = finfo; - return ret; -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_class.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +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 HPROF_CLASS_H -#define HPROF_CLASS_H - -void class_init(void); -ClassIndex class_find_or_create(const char *sig, LoaderIndex loader); -ClassIndex class_create(const char *sig, LoaderIndex loader); -SerialNumber class_get_serial_number(ClassIndex index); -StringIndex class_get_signature(ClassIndex index); -ClassStatus class_get_status(ClassIndex index); -void class_add_status(ClassIndex index, ClassStatus status); -void class_all_status_remove(ClassStatus status); -void class_do_unloads(JNIEnv *env); -void class_list(void); -void class_delete_global_references(JNIEnv* env); -void class_cleanup(void); -void class_set_methods(ClassIndex index, const char**name, - const char**descr, int count); -jmethodID class_get_methodID(JNIEnv *env, ClassIndex index, - MethodIndex mnum); -jclass class_new_classref(JNIEnv *env, ClassIndex index, - jclass classref); -void class_delete_classref(JNIEnv *env, ClassIndex index); -jclass class_get_class(JNIEnv *env, ClassIndex index); -void class_set_inst_size(ClassIndex index, jint inst_size); -jint class_get_inst_size(ClassIndex index); -void class_set_object_index(ClassIndex index, - ObjectIndex object_index); -ObjectIndex class_get_object_index(ClassIndex index); -ClassIndex class_get_super(ClassIndex index); -void class_set_super(ClassIndex index, ClassIndex super); -void class_set_loader(ClassIndex index, LoaderIndex loader); -LoaderIndex class_get_loader(ClassIndex index); -void class_prime_system_classes(void); -jint class_get_all_fields(JNIEnv *env, ClassIndex cnum, - jint *pfield_count, FieldInfo **pfield); - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +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. - */ - - -#include "hprof.h" - -/* This file contains the cpu loop for the option cpu=samples */ - -/* The cpu_loop thread basically waits for gdata->sample_interval millisecs - * then wakes up, and for each running thread it gets their stack trace, - * and updates the traces with 'hits'. - * - * No threads are suspended or resumed, and the thread sampling is in the - * file hprof_tls.c, which manages all active threads. The sampling - * technique (what is sampled) is also in hprof_tls.c. - * - * No adjustments are made to the pause time or sample interval except - * by the user via the interval=n option (default is 10ms). - * - * This thread can cause havoc when started prematurely or not terminated - * properly, see cpu_sample_init() and cpu_term(), and their calls in hprof_init.c. - * - * The listener loop (hprof_listener.c) can dynamically turn on or off the - * sampling of all or selected threads. - * - */ - -/* Private functions */ - -static void JNICALL -cpu_loop_function(jvmtiEnv *jvmti, JNIEnv *env, void *p) -{ - int loop_trip_counter; - jboolean cpu_loop_running; - - loop_trip_counter = 0; - - rawMonitorEnter(gdata->cpu_loop_lock); { - gdata->cpu_loop_running = JNI_TRUE; - cpu_loop_running = gdata->cpu_loop_running; - /* Notify cpu_sample_init() that we have started */ - rawMonitorNotifyAll(gdata->cpu_loop_lock); - } rawMonitorExit(gdata->cpu_loop_lock); - - rawMonitorEnter(gdata->cpu_sample_lock); /* Only waits inside loop let go */ - - while ( cpu_loop_running ) { - - ++loop_trip_counter; - - LOG3("cpu_loop()", "iteration", loop_trip_counter); - - /* If a dump is in progress, we pause sampling. */ - rawMonitorEnter(gdata->dump_lock); { - if (gdata->dump_in_process) { - gdata->pause_cpu_sampling = JNI_TRUE; - } - } rawMonitorExit(gdata->dump_lock); - - /* Check to see if we need to pause sampling (listener_loop command) */ - if (gdata->pause_cpu_sampling) { - - /* - * Pause sampling for now. Reset sample controls if - * sampling is resumed again. - */ - - rawMonitorWait(gdata->cpu_sample_lock, 0); - - rawMonitorEnter(gdata->cpu_loop_lock); { - cpu_loop_running = gdata->cpu_loop_running; - } rawMonitorExit(gdata->cpu_loop_lock); - - /* Continue the while loop, which will terminate if done. */ - continue; - } - - /* This is the normal short timed wait before getting a sample */ - rawMonitorWait(gdata->cpu_sample_lock, (jlong)gdata->sample_interval); - - /* Make sure we really want to continue */ - rawMonitorEnter(gdata->cpu_loop_lock); { - cpu_loop_running = gdata->cpu_loop_running; - } rawMonitorExit(gdata->cpu_loop_lock); - - /* Break out if we are done */ - if ( !cpu_loop_running ) { - break; - } - - /* - * If a dump request came in after we checked at the top of - * the while loop, then we catch that fact here. We - * don't want to perturb the data that is being dumped so - * we just ignore the data from this sampling loop. - */ - rawMonitorEnter(gdata->dump_lock); { - if (gdata->dump_in_process) { - gdata->pause_cpu_sampling = JNI_TRUE; - } - } rawMonitorExit(gdata->dump_lock); - - /* Sample all the threads and update trace costs */ - if ( !gdata->pause_cpu_sampling) { - tls_sample_all_threads(env); - } - - /* Check to see if we need to finish */ - rawMonitorEnter(gdata->cpu_loop_lock); { - cpu_loop_running = gdata->cpu_loop_running; - } rawMonitorExit(gdata->cpu_loop_lock); - - } - rawMonitorExit(gdata->cpu_sample_lock); - - rawMonitorEnter(gdata->cpu_loop_lock); { - /* Notify cpu_sample_term() that we are done. */ - rawMonitorNotifyAll(gdata->cpu_loop_lock); - } rawMonitorExit(gdata->cpu_loop_lock); - - LOG2("cpu_loop()", "clean termination"); -} - -/* External functions */ - -void -cpu_sample_init(JNIEnv *env) -{ - gdata->cpu_sampling = JNI_TRUE; - - /* Create the raw monitors needed */ - gdata->cpu_loop_lock = createRawMonitor("HPROF cpu loop lock"); - gdata->cpu_sample_lock = createRawMonitor("HPROF cpu sample lock"); - - rawMonitorEnter(gdata->cpu_loop_lock); { - createAgentThread(env, "HPROF cpu sampling thread", - &cpu_loop_function); - /* Wait for cpu_loop_function() to notify us it has started. */ - rawMonitorWait(gdata->cpu_loop_lock, 0); - } rawMonitorExit(gdata->cpu_loop_lock); -} - -void -cpu_sample_off(JNIEnv *env, ObjectIndex object_index) -{ - jint count; - - count = 1; - if (object_index != 0) { - tls_set_sample_status(object_index, 0); - count = tls_sum_sample_status(); - } - if ( count == 0 ) { - gdata->pause_cpu_sampling = JNI_TRUE; - } else { - gdata->pause_cpu_sampling = JNI_FALSE; - } -} - -void -cpu_sample_on(JNIEnv *env, ObjectIndex object_index) -{ - if ( gdata->cpu_loop_lock == NULL ) { - cpu_sample_init(env); - } - - if (object_index == 0) { - gdata->cpu_sampling = JNI_TRUE; - gdata->pause_cpu_sampling = JNI_FALSE; - } else { - jint count; - - tls_set_sample_status(object_index, 1); - count = tls_sum_sample_status(); - if ( count > 0 ) { - gdata->pause_cpu_sampling = JNI_FALSE; - } - } - - /* Notify the CPU sampling thread that sampling is on */ - rawMonitorEnter(gdata->cpu_sample_lock); { - rawMonitorNotifyAll(gdata->cpu_sample_lock); - } rawMonitorExit(gdata->cpu_sample_lock); - -} - -void -cpu_sample_term(JNIEnv *env) -{ - gdata->pause_cpu_sampling = JNI_FALSE; - rawMonitorEnter(gdata->cpu_sample_lock); { - /* Notify the CPU sampling thread to get out of any sampling Wait */ - rawMonitorNotifyAll(gdata->cpu_sample_lock); - } rawMonitorExit(gdata->cpu_sample_lock); - rawMonitorEnter(gdata->cpu_loop_lock); { - if ( gdata->cpu_loop_running ) { - gdata->cpu_loop_running = JNI_FALSE; - /* Wait for cpu_loop_function() thread to tell us it completed. */ - rawMonitorWait(gdata->cpu_loop_lock, 0); - } - } rawMonitorExit(gdata->cpu_loop_lock); -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_cpu.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +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 HPROF_CPU_H -#define HPROF_CPU_H - -void cpu_sample_off(JNIEnv *env, ObjectIndex object_index); -void cpu_sample_on(JNIEnv *env, ObjectIndex object_index); - -void cpu_sample_init(JNIEnv *env); -void cpu_sample_term(JNIEnv *env); - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +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. - */ - - -#include "hprof.h" - -/* The error handling logic. */ - -/* - * Most hprof error processing and error functions are kept here, along with - * termination functions and signal handling (used in debug version only). - * - */ - -#include - -static int p = 1; /* Used with pause=y|n option */ - -/* Private functions */ - -static void -error_message(const char * format, ...) -{ - va_list ap; - - va_start(ap, format); - (void)vfprintf(stderr, format, ap); - va_end(ap); -} - -static void -error_abort(void) -{ - /* Important to remove existing signal handler */ - (void)signal(SIGABRT, NULL); - error_message("HPROF DUMPING CORE\n"); - abort(); /* Sends SIGABRT signal, usually also caught by libjvm */ -} - -static void -signal_handler(int sig) -{ - /* Caught a signal, most likely a SIGABRT */ - error_message("HPROF SIGNAL %d TERMINATED PROCESS\n", sig); - error_abort(); -} - -static void -setup_signal_handler(int sig) -{ - /* Only if debug version or debug=y */ - if ( gdata->debug ) { - (void)signal(sig, (void(*)(int))(void*)&signal_handler); - } -} - -static void -terminate_everything(jint exit_code) -{ - if ( exit_code > 0 ) { - /* Could be a fatal error or assert error or a sanity error */ - error_message("HPROF TERMINATED PROCESS\n"); - if ( gdata->coredump || gdata->debug ) { - /* Core dump here by request */ - error_abort(); - } - } - /* Terminate the process */ - error_exit_process(exit_code); -} - -/* External functions */ - -void -error_setup(void) -{ - setup_signal_handler(SIGABRT); -} - -void -error_do_pause(void) -{ - int pid = md_getpid(); - int timeleft = 600; /* 10 minutes max */ - int interval = 10; /* 10 second message check */ - - /*LINTED*/ - error_message("\nHPROF pause for PID %d\n", (int)pid); - while ( p && timeleft > 0 ) { - md_sleep(interval); /* 'assign p=0' to stop pause loop */ - timeleft -= interval; - } - if ( timeleft <= 0 ) { - error_message("\n HPROF pause got tired of waiting and gave up.\n"); - } -} - -void -error_exit_process(int exit_code) -{ - exit(exit_code); -} - -static const char * -source_basename(const char *file) -{ - const char *p; - - if ( file == NULL ) { - return "UnknownSourceFile"; - } - p = strrchr(file, '/'); - if ( p == NULL ) { - p = strrchr(file, '\\'); - } - if ( p == NULL ) { - p = file; - } else { - p++; /* go past / */ - } - return p; -} - -void -error_assert(const char *condition, const char *file, int line) -{ - error_message("ASSERTION FAILURE: %s [%s:%d]\n", condition, - source_basename(file), line); - error_abort(); -} - -void -error_handler(jboolean fatal, jvmtiError error, - const char *message, const char *file, int line) -{ - char *error_name; - - if ( message==NULL ) { - message = ""; - } - if ( error != JVMTI_ERROR_NONE ) { - error_name = getErrorName(error); - if ( error_name == NULL ) { - error_name = "?"; - } - error_message("HPROF ERROR: %s (JVMTI Error %s(%d)) [%s:%d]\n", - message, error_name, error, - source_basename(file), line); - } else { - error_message("HPROF ERROR: %s [%s:%d]\n", message, - source_basename(file), line); - } - if ( fatal || gdata->errorexit ) { - /* If it's fatal, or the user wants termination on any error, die */ - terminate_everything(9); - } -} - -void -debug_message(const char * format, ...) -{ - va_list ap; - - va_start(ap, format); - (void)vfprintf(stderr, format, ap); - va_end(ap); -} - -void -verbose_message(const char * format, ...) -{ - if ( gdata->verbose ) { - va_list ap; - - va_start(ap, format); - (void)vfprintf(stderr, format, ap); - va_end(ap); - } -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2003, 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. - */ - - -#ifndef HPROF_ERROR_H -#define HPROF_ERROR_H - -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - -/* Macros over assert and error functions so we can capture the source loc. */ - -#define HPROF_BOOL(x) ((jboolean)((x)==0?JNI_FALSE:JNI_TRUE)) - -#define HPROF_ERROR(fatal,msg) \ - error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, THIS_FILE, __LINE__) - -#define HPROF_JVMTI_ERROR(error,msg) \ - error_handler(HPROF_BOOL(error!=JVMTI_ERROR_NONE), \ - error, msg, THIS_FILE, __LINE__) - -#if defined(DEBUG) || !defined(NDEBUG) - #define HPROF_ASSERT(cond) \ - (((int)(cond))?(void)0:error_assert(#cond, THIS_FILE, __LINE__)) -#else - #define HPROF_ASSERT(cond) -#endif - -#define LOG_DUMP_MISC 0x1 /* Misc. logging info */ -#define LOG_DUMP_LISTS 0x2 /* Dump tables at vm init and death */ -#define LOG_CHECK_BINARY 0x4 /* If format=b, verify binary format */ - -#ifdef HPROF_LOGGING - #define LOG_STDERR(args) \ - { \ - if ( gdata != NULL && (gdata->logflags & LOG_DUMP_MISC) ) { \ - (void)fprintf args ; \ - } \ - } -#else - #define LOG_STDERR(args) -#endif - -#define LOG_FORMAT(format) "HPROF LOG: " format " [%s:%d]\n" - -#define LOG1(str1) LOG_STDERR((stderr, LOG_FORMAT("%s"), \ - str1, THIS_FILE, __LINE__ )) -#define LOG2(str1,str2) LOG_STDERR((stderr, LOG_FORMAT("%s %s"), \ - str1, str2, THIS_FILE, __LINE__ )) -#define LOG3(str1,str2,num) LOG_STDERR((stderr, LOG_FORMAT("%s %s 0x%x"), \ - str1, str2, num, THIS_FILE, __LINE__ )) - -#define LOG(str) LOG1(str) - -void error_handler(jboolean fatal, jvmtiError error, - const char *message, const char *file, int line); -void error_assert(const char *condition, const char *file, int line); -void error_exit_process(int exit_code); -void error_do_pause(void); -void error_setup(void); -void debug_message(const char * format, ...); -void verbose_message(const char * format, ...); - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,450 +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. - */ - - -/* This file contains all class, method and allocation event support functions, - * both JVMTI and BCI events. - * (See hprof_monitor.c for the monitor event handlers). - */ - -#include "hprof.h" - -/* Private internal functions. */ - -/* Return a TraceIndex for the given thread. */ -static TraceIndex -get_current(TlsIndex tls_index, JNIEnv *env, jboolean skip_init) -{ - TraceIndex trace_index; - - trace_index = tls_get_trace(tls_index, env, gdata->max_trace_depth, skip_init); - return trace_index; -} - -/* Return a ClassIndex for the given jclass, loader supplied or looked up. */ -static ClassIndex -find_cnum(JNIEnv *env, jclass klass, jobject loader) -{ - LoaderIndex loader_index; - ClassIndex cnum; - char * signature; - - HPROF_ASSERT(klass!=NULL); - - /* Get the loader index */ - loader_index = loader_find_or_create(env, loader); - - /* Get the signature for this class */ - getClassSignature(klass, &signature, NULL); - - /* Find the ClassIndex for this class */ - cnum = class_find_or_create(signature, loader_index); - - /* Free the signature space */ - jvmtiDeallocate(signature); - - /* Make sure we save a global reference to this class in the table */ - HPROF_ASSERT(cnum!=0); - (void)class_new_classref(env, cnum, klass); - return cnum; -} - -/* Get the ClassIndex for the superClass of this jclass. */ -static ClassIndex -get_super(JNIEnv *env, jclass klass) -{ - ClassIndex super_cnum; - - super_cnum = 0; - WITH_LOCAL_REFS(env, 1) { - jclass super_klass; - - super_klass = getSuperclass(env, klass); - if ( super_klass != NULL ) { - super_cnum = find_cnum(env, super_klass, - getClassLoader(super_klass)); - } - } END_WITH_LOCAL_REFS; - return super_cnum; -} - -/* Record an allocation. Could be jobject, jclass, jarray or primitive type. */ -static void -any_allocation(JNIEnv *env, SerialNumber thread_serial_num, - TraceIndex trace_index, jobject object) -{ - SiteIndex site_index; - ClassIndex cnum; - jint size; - jclass klass; - - /* NOTE: Normally the getObjectClass() and getClassLoader() - * would require a - * WITH_LOCAL_REFS(env, 1) { - * } END_WITH_LOCAL_REFS; - * but for performance reasons we skip it here. - */ - - /* Get and tag the klass */ - klass = getObjectClass(env, object); - cnum = find_cnum(env, klass, getClassLoader(klass)); - site_index = site_find_or_create(cnum, trace_index); - tag_class(env, klass, cnum, thread_serial_num, site_index); - - /* Tag the object */ - size = (jint)getObjectSize(object); - tag_new_object(object, OBJECT_NORMAL, thread_serial_num, size, site_index); -} - -/* Handle a java.lang.Object. object allocation. */ -void -event_object_init(JNIEnv *env, jthread thread, jobject object) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - jint *pstatus; - TraceIndex trace_index; - SerialNumber thread_serial_num; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(object!=NULL); - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_TRUE, - &pstatus, NULL, &thread_serial_num, &trace_index) == 0 ) { - (*pstatus) = 1; - any_allocation(env, thread_serial_num, trace_index, object); - (*pstatus) = 0; - } -} - -/* Handle any newarray opcode allocation. */ -void -event_newarray(JNIEnv *env, jthread thread, jobject object) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - jint *pstatus; - TraceIndex trace_index; - SerialNumber thread_serial_num; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(object!=NULL); - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, NULL, &thread_serial_num, &trace_index) == 0 ) { - (*pstatus) = 1; - any_allocation(env, thread_serial_num, trace_index, object); - (*pstatus) = 0; - } -} - -/* Handle tracking of a method call. */ -void -event_call(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - TlsIndex tls_index; - jint *pstatus; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - if (cnum == 0 || cnum == gdata->tracker_cnum) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Illegal cnum."); - - return; - } - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, &tls_index, NULL, NULL) == 0 ) { - jmethodID method; - - (*pstatus) = 1; - method = class_get_methodID(env, cnum, mnum); - if (method != NULL) { - tls_push_method(tls_index, method); - } - - (*pstatus) = 0; - } -} - -/* Handle tracking of an exception catch */ -void -event_exception_catch(JNIEnv *env, jthread thread, jmethodID method, - jlocation location, jobject exception) -{ - /* Called via JVMTI_EVENT_EXCEPTION_CATCH callback */ - - /* Be very careful what is called here, watch out for recursion. */ - - TlsIndex tls_index; - jint *pstatus; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(method!=NULL); - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, &tls_index, NULL, NULL) == 0 ) { - (*pstatus) = 1; - tls_pop_exception_catch(tls_index, thread, method); - (*pstatus) = 0; - } -} - -/* Handle tracking of a method return pop one (maybe more) methods. */ -void -event_return(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum) -{ - /* Called via BCI Tracker class */ - - /* Be very careful what is called here, watch out for recursion. */ - - TlsIndex tls_index; - jint *pstatus; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - - if (cnum == 0 || cnum == gdata->tracker_cnum) { - jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - (*env)->ThrowNew(env, newExcCls, "Illegal cnum."); - - return; - } - - /* Prevent recursion into any BCI function for this thread (pstatus). */ - if ( tls_get_tracker_status(env, thread, JNI_FALSE, - &pstatus, &tls_index, NULL, NULL) == 0 ) { - jmethodID method; - - (*pstatus) = 1; - method = class_get_methodID(env, cnum, mnum); - if (method != NULL) { - tls_pop_method(tls_index, thread, method); - } - - (*pstatus) = 0; - } -} - -/* Handle a class prepare (should have been already loaded) */ -void -event_class_prepare(JNIEnv *env, jthread thread, jclass klass, jobject loader) -{ - /* Called via JVMTI_EVENT_CLASS_PREPARE event */ - - ClassIndex cnum; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - HPROF_ASSERT(klass!=NULL); - - /* Find the ClassIndex for this class */ - cnum = find_cnum(env, klass, loader); - class_add_status(cnum, CLASS_PREPARED); - -} - -/* Handle a class load (could have been already loaded) */ -void -event_class_load(JNIEnv *env, jthread thread, jclass klass, jobject loader) -{ - /* Called via JVMTI_EVENT_CLASS_LOAD event or reset_class_load_status() */ - - ClassIndex cnum; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(klass!=NULL); - - /* Find the ClassIndex for this class */ - cnum = find_cnum(env, klass, loader); - - /* Always mark it as being in the load list */ - class_add_status(cnum, CLASS_IN_LOAD_LIST); - - /* If we are seeing this as a new loaded class, extra work */ - if ( ! ( class_get_status(cnum) & CLASS_LOADED ) ) { - TraceIndex trace_index; - SiteIndex site_index; - ClassIndex super; - SerialNumber class_serial_num; - SerialNumber trace_serial_num; - SerialNumber thread_serial_num; - ObjectIndex class_object_index; - char *signature; - - /* Get the TlsIndex and a TraceIndex for this location */ - if ( thread == NULL ) { - /* This should be very rare, but if this class load was simulated - * from hprof_init.c due to a reset of the class load status, - * and it originated from a pre-VM_INIT event, the jthread - * would be NULL, or it was a jclass created that didn't get - * reported to us, like an array class or a primitive class? - */ - trace_index = gdata->system_trace_index; - thread_serial_num = gdata->unknown_thread_serial_num; - } else { - TlsIndex tls_index; - - tls_index = tls_find_or_create(env, thread); - trace_index = get_current(tls_index, env, JNI_FALSE); - thread_serial_num = tls_get_thread_serial_number(tls_index); - } - - /* Get the SiteIndex for this location and a java.lang.Class object */ - /* Note that the target cnum, not the cnum for java.lang.Class. */ - site_index = site_find_or_create(cnum, trace_index); - - /* Tag this java.lang.Class object */ - tag_class(env, klass, cnum, thread_serial_num, site_index); - - class_add_status(cnum, CLASS_LOADED); - - class_serial_num = class_get_serial_number(cnum); - class_object_index = class_get_object_index(cnum); - trace_serial_num = trace_get_serial_number(trace_index); - signature = string_get(class_get_signature(cnum)); - - rawMonitorEnter(gdata->data_access_lock); { - io_write_class_load(class_serial_num, class_object_index, - trace_serial_num, signature); - } rawMonitorExit(gdata->data_access_lock); - - super = get_super(env, klass); - class_set_super(cnum, super); - } - -} - -/* Handle a thread start event */ -void -event_thread_start(JNIEnv *env, jthread thread) -{ - /* Called via JVMTI_EVENT_THREAD_START event */ - - TlsIndex tls_index; - ObjectIndex object_index; - TraceIndex trace_index; - jlong tag; - SerialNumber thread_serial_num; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - - tls_index = tls_find_or_create(env, thread); - thread_serial_num = tls_get_thread_serial_number(tls_index); - trace_index = get_current(tls_index, env, JNI_FALSE); - - tag = getTag(thread); - if ( tag == (jlong)0 ) { - SiteIndex site_index; - jint size; - - size = (jint)getObjectSize(thread); - site_index = site_find_or_create(gdata->thread_cnum, trace_index); - /* We create a new object with this thread's serial number */ - object_index = object_new(site_index, size, OBJECT_NORMAL, - thread_serial_num); - } else { - object_index = tag_extract(tag); - /* Normally the Thread object is created and tagged before we get - * here, but the thread_serial_number on this object isn't what - * we want. So we update it to the serial number of this thread. - */ - object_set_thread_serial_number(object_index, thread_serial_num); - } - tls_set_thread_object_index(tls_index, object_index); - - WITH_LOCAL_REFS(env, 1) { - jvmtiThreadInfo threadInfo; - jvmtiThreadGroupInfo threadGroupInfo; - jvmtiThreadGroupInfo parentGroupInfo; - - getThreadInfo(thread, &threadInfo); - getThreadGroupInfo(threadInfo.thread_group, &threadGroupInfo); - if ( threadGroupInfo.parent != NULL ) { - getThreadGroupInfo(threadGroupInfo.parent, &parentGroupInfo); - } else { - (void)memset(&parentGroupInfo, 0, sizeof(parentGroupInfo)); - } - - rawMonitorEnter(gdata->data_access_lock); { - io_write_thread_start(thread_serial_num, - object_index, trace_get_serial_number(trace_index), - threadInfo.name, threadGroupInfo.name, parentGroupInfo.name); - } rawMonitorExit(gdata->data_access_lock); - - jvmtiDeallocate(threadInfo.name); - jvmtiDeallocate(threadGroupInfo.name); - jvmtiDeallocate(parentGroupInfo.name); - - } END_WITH_LOCAL_REFS; -} - -void -event_thread_end(JNIEnv *env, jthread thread) -{ - /* Called via JVMTI_EVENT_THREAD_END event */ - TlsIndex tls_index; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(thread!=NULL); - - tls_index = tls_find_or_create(env, thread); - rawMonitorEnter(gdata->data_access_lock); { - io_write_thread_end(tls_get_thread_serial_number(tls_index)); - } rawMonitorExit(gdata->data_access_lock); - tls_thread_ended(env, tls_index); - setThreadLocalStorage(thread, (void*)NULL); -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_event.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +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 HPROF_EVENT_H -#define HPROF_EVENT_H - -/* From BCI: */ -void event_object_init(JNIEnv *env, jthread thread, jobject obj); -void event_newarray(JNIEnv *env, jthread thread, jobject obj); -void event_call(JNIEnv *env, jthread thread, - ClassIndex cnum, MethodIndex mnum); -void event_return(JNIEnv *env, jthread thread, - ClassIndex cnum, MethodIndex mnum); - -/* From JVMTI: */ -void event_class_load(JNIEnv *env, jthread thread, jclass klass, jobject loader); -void event_class_prepare(JNIEnv *env, jthread thread, jclass klass, jobject loader); -void event_thread_start(JNIEnv *env_id, jthread thread); -void event_thread_end(JNIEnv *env_id, jthread thread); -void event_exception_catch(JNIEnv *env, jthread thread, jmethodID method, - jlocation location, jobject exception); - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +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. - */ - - -/* This file contains support for handling frames, or (method,location) pairs. */ - -#include "hprof.h" - -/* - * Frames map 1-to-1 to (methodID,location) pairs. - * When no line number is known, -1 should be used. - * - * Frames are mostly used in traces (see hprof_trace.c) and will be marked - * with their status flag as they are written out to the hprof output file. - * - */ - -enum LinenoState { - LINENUM_UNINITIALIZED = 0, - LINENUM_AVAILABLE = 1, - LINENUM_UNAVAILABLE = 2 -}; - -typedef struct FrameKey { - jmethodID method; - jlocation location; -} FrameKey; - -typedef struct FrameInfo { - unsigned short lineno; - unsigned char lineno_state; /* LinenoState */ - unsigned char status; - SerialNumber serial_num; -} FrameInfo; - -static FrameKey* -get_pkey(FrameIndex index) -{ - void *key_ptr; - int key_len; - - table_get_key(gdata->frame_table, index, &key_ptr, &key_len); - HPROF_ASSERT(key_len==sizeof(FrameKey)); - HPROF_ASSERT(key_ptr!=NULL); - return (FrameKey*)key_ptr; -} - -static FrameInfo * -get_info(FrameIndex index) -{ - FrameInfo *info; - - info = (FrameInfo*)table_get_info(gdata->frame_table, index); - return info; -} - -static void -list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg) -{ - FrameKey key; - FrameInfo *info; - - HPROF_ASSERT(key_ptr!=NULL); - HPROF_ASSERT(key_len==sizeof(FrameKey)); - HPROF_ASSERT(info_ptr!=NULL); - - key = *((FrameKey*)key_ptr); - info = (FrameInfo*)info_ptr; - debug_message( - "Frame 0x%08x: method=%p, location=%d, lineno=%d(%d), status=%d \n", - i, (void*)key.method, (jint)key.location, - info->lineno, info->lineno_state, info->status); -} - -void -frame_init(void) -{ - gdata->frame_table = table_initialize("Frame", - 1024, 1024, 1023, (int)sizeof(FrameInfo)); -} - -FrameIndex -frame_find_or_create(jmethodID method, jlocation location) -{ - FrameIndex index; - static FrameKey empty_key; - FrameKey key; - jboolean new_one; - - key = empty_key; - key.method = method; - key.location = location; - new_one = JNI_FALSE; - index = table_find_or_create_entry(gdata->frame_table, - &key, (int)sizeof(key), &new_one, NULL); - if ( new_one ) { - FrameInfo *info; - - info = get_info(index); - info->lineno_state = LINENUM_UNINITIALIZED; - if ( location < 0 ) { - info->lineno_state = LINENUM_UNAVAILABLE; - } - info->serial_num = gdata->frame_serial_number_counter++; - } - return index; -} - -void -frame_list(void) -{ - debug_message( - "--------------------- Frame Table ------------------------\n"); - table_walk_items(gdata->frame_table, &list_item, NULL); - debug_message( - "----------------------------------------------------------\n"); -} - -void -frame_cleanup(void) -{ - table_cleanup(gdata->frame_table, NULL, NULL); - gdata->frame_table = NULL; -} - -void -frame_set_status(FrameIndex index, jint status) -{ - FrameInfo *info; - - info = get_info(index); - info->status = (unsigned char)status; -} - -void -frame_get_location(FrameIndex index, SerialNumber *pserial_num, - jmethodID *pmethod, jlocation *plocation, jint *plineno) -{ - FrameKey *pkey; - FrameInfo *info; - jint lineno; - - pkey = get_pkey(index); - *pmethod = pkey->method; - *plocation = pkey->location; - info = get_info(index); - lineno = (jint)info->lineno; - if ( info->lineno_state == LINENUM_UNINITIALIZED ) { - info->lineno_state = LINENUM_UNAVAILABLE; - if ( gdata->lineno_in_traces ) { - if ( pkey->location >= 0 && !isMethodNative(pkey->method) ) { - lineno = getLineNumber(pkey->method, pkey->location); - if ( lineno >= 0 ) { - info->lineno = (unsigned short)lineno; /* save it */ - info->lineno_state = LINENUM_AVAILABLE; - } - } - } - } - if ( info->lineno_state == LINENUM_UNAVAILABLE ) { - lineno = -1; - } - *plineno = lineno; - *pserial_num = info->serial_num; -} - -jint -frame_get_status(FrameIndex index) -{ - FrameInfo *info; - - info = get_info(index); - return (jint)info->status; -} diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.h --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_frame.h Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +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 HPROF_FRAME_H -#define HPROF_FRAME_H - -void frame_init(void); -FrameIndex frame_find_or_create(jmethodID method, jlocation location); -void frame_list(void); -void frame_cleanup(void); -void frame_get_location(FrameIndex frame_num, SerialNumber *serial_num, - jmethodID *pmethod, - jlocation *plocation, jint *plineno); -void frame_set_status(FrameIndex frame_num, jint status); -jint frame_get_status(FrameIndex frame_num); - -#endif diff -r 602c828cf7dc -r fed421ad9b70 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_init.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_init.c Wed Aug 05 03:43:31 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2145 +0,0 @@ -/* - * Copyright (c) 2003, 2014, 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. - */ - - -/* Main source file, the basic JVMTI connection/startup code. */ - -#include "hprof.h" - -#include "java_crw_demo.h" - -/* - * This file contains all the startup logic (Agent_Onload) and - * connection to the JVMTI interface. - * All JVMTI Event callbacks are in this file. - * All setting of global data (gdata) is done here. - * Options are parsed here. - * Option help messages are here. - * Termination handled here (VM_DEATH) and shutdown (Agent_OnUnload). - * Spawning of the cpu sample loop thread and listener thread is done here. - * - * Use of private 'static' data has been limited, most shared static data - * should be found in the GlobalData structure pointed to by gdata - * (see hprof.h). - * - */ - -/* The default output filenames. */ - -#define DEFAULT_TXT_SUFFIX ".txt" -#define DEFAULT_OUTPUTFILE "java.hprof" -#define DEFAULT_OUTPUTTEMP "java.hprof.temp" - -/* The only global variable, defined by this library */ -GlobalData *gdata; - -/* Experimental options */ -#define EXPERIMENT_NO_EARLY_HOOK 0x1 - -/* Default trace depth */ -#define DEFAULT_TRACE_DEPTH 4 - -/* Default sample interval */ -#define DEFAULT_SAMPLE_INTERVAL 10 - -/* Default cutoff */ -#define DEFAULT_CUTOFF_POINT 0.0001 - -/* Stringize macros for help. */ -#define _TO_STR(a) #a -#define TO_STR(a) _TO_STR(a) - -/* Macros to surround callback code (non-VM_DEATH callbacks). - * Note that this just keeps a count of the non-VM_DEATH callbacks that - * are currently active, it does not prevent these callbacks from - * operating in parallel. It's the VM_DEATH callback that will wait - * for all these callbacks to either complete and block, or just block. - * We need to hold back these threads so they don't die during the final - * VM_DEATH processing. - * If the VM_DEATH callback is active in the beginning, then this callback - * just blocks to prevent further execution of the thread. - * If the VM_DEATH callback is active at the end, then this callback - * will notify the VM_DEATH callback if it's the last one. - * In all cases, the last thing they do is Enter/Exit the monitor - * gdata->callbackBlock, which will block this callback if VM_DEATH - * is running. - * - * WARNING: No not 'return' or 'goto' out of the BEGIN_CALLBACK/END_CALLBACK - * block, this will mess up the count. - */ - -#define BEGIN_CALLBACK() \ -{ /* BEGIN OF CALLBACK */ \ - jboolean bypass; \ - rawMonitorEnter(gdata->callbackLock); \ - if (gdata->vm_death_callback_active) { \ - /* VM_DEATH is active, we will bypass the CALLBACK CODE */ \ - bypass = JNI_TRUE; \ - rawMonitorExit(gdata->callbackLock); \ - /* Bypassed CALLBACKS block here until VM_DEATH done */ \ - rawMonitorEnter(gdata->callbackBlock); \ - rawMonitorExit(gdata->callbackBlock); \ - } else { \ - /* We will be executing the CALLBACK CODE in this case */ \ - gdata->active_callbacks++; \ - bypass = JNI_FALSE; \ - rawMonitorExit(gdata->callbackLock); \ - } \ - if ( !bypass ) { \ - /* BODY OF CALLBACK CODE (with no callback locks held) */ - -#define END_CALLBACK() /* Part of bypass if body */ \ - rawMonitorEnter(gdata->callbackLock); \ - gdata->active_callbacks--; \ - /* If VM_DEATH is active, and last one, send notify. */ \ - if (gdata->vm_death_callback_active) { \ - if (gdata->active_callbacks == 0) { \ - rawMonitorNotifyAll(gdata->callbackLock); \ - } \ - } \ - rawMonitorExit(gdata->callbackLock); \ - /* Non-Bypassed CALLBACKS block here until VM_DEATH done */ \ - rawMonitorEnter(gdata->callbackBlock); \ - rawMonitorExit(gdata->callbackBlock); \ - } \ -} /* END OF CALLBACK */ - -/* Forward declarations */ -static void set_callbacks(jboolean on); - -/* ------------------------------------------------------------------- */ -/* Global data initialization */ - -/* Get initialized global data area */ -static GlobalData * -get_gdata(void) -{ - static GlobalData data; - - /* Create initial default values */ - (void)memset(&data, 0, sizeof(GlobalData)); - - data.fd = -1; /* Non-zero file or socket. */ - data.heap_fd = -1; /* For heap=dump, see hprof_io */ - data.check_fd = -1; /* For heap=dump, see hprof_io */ - data.max_trace_depth = DEFAULT_TRACE_DEPTH; - data.prof_trace_depth = DEFAULT_TRACE_DEPTH; - data.sample_interval = DEFAULT_SAMPLE_INTERVAL; - data.lineno_in_traces = JNI_TRUE; - data.output_format = 'a'; /* 'b' for binary */ - data.cutoff_point = DEFAULT_CUTOFF_POINT; - data.dump_on_exit = JNI_TRUE; - data.gc_start_time = -1L; -#ifdef DEBUG - data.debug = JNI_TRUE; - data.coredump = JNI_TRUE; -#endif - data.micro_state_accounting = JNI_FALSE; - data.force_output = JNI_TRUE; - data.verbose = JNI_TRUE; - data.primfields = JNI_TRUE; - data.primarrays = JNI_TRUE; - - data.table_serial_number_start = 1; - data.class_serial_number_start = 100000; - data.thread_serial_number_start = 200000; - data.trace_serial_number_start = 300000; - data.object_serial_number_start = 400000; - data.frame_serial_number_start = 500000; - data.gref_serial_number_start = 1; - - data.table_serial_number_counter = data.table_serial_number_start; - data.class_serial_number_counter = data.class_serial_number_start; - data.thread_serial_number_counter = data.thread_serial_number_start; - data.trace_serial_number_counter = data.trace_serial_number_start; - data.object_serial_number_counter = data.object_serial_number_start; - data.frame_serial_number_counter = data.frame_serial_number_start; - data.gref_serial_number_counter = data.gref_serial_number_start; - - data.unknown_thread_serial_num = data.thread_serial_number_counter++; - return &data; -} - -/* ------------------------------------------------------------------- */ -/* Error handler callback for the java_crw_demo (classfile read write) functions. */ - -static void -my_crw_fatal_error_handler(const char * msg, const char *file, int line) -{ - char errmsg[256]; - - (void)md_snprintf(errmsg, sizeof(errmsg), - "%s [%s:%d]", msg, file, line); - errmsg[sizeof(errmsg)-1] = 0; - HPROF_ERROR(JNI_TRUE, errmsg); -} - -static void -list_all_tables(void) -{ - string_list(); - class_list(); - frame_list(); - site_list(); - object_list(); - trace_list(); - monitor_list(); - tls_list(); - loader_list(); -} - -/* ------------------------------------------------------------------- */ -/* Option Parsing support */ - -/** - * Socket connection - */ - -/* - * Return a socket connect()ed to a "hostname" that is - * accept()ing heap profile data on "port." Return a value <= 0 if - * such a connection can't be made. - */ -static int -connect_to_socket(char *hostname, int port) -{ - int fd; - - if (port == 0 || port > 65535) { - HPROF_ERROR(JNI_FALSE, "invalid port number"); - return -1; - } - if (hostname == NULL) { - HPROF_ERROR(JNI_FALSE, "hostname is NULL"); - return -1; - } - - /* create a socket */ - fd = md_connect(hostname, (unsigned short)port); - return fd; -} - -/* Accept a filename, and adjust the name so that it is unique for this PID */ -static void -make_unique_filename(char **filename) -{ - int fd; - - /* Find a file that doesn't exist */ - fd = md_open(*filename); - if ( fd >= 0 ) { - int pid; - char *new_name; - char *old_name; - char *prefix; - char suffix[5]; - int new_len; - - /* Close the file. */ - md_close(fd); - - /* Make filename name.PID[.txt] */ - pid = md_getpid(); - old_name = *filename; - new_len = (int)strlen(old_name)+64; - new_name = HPROF_MALLOC(new_len); - prefix = old_name; - suffix[0] = 0; - - /* Look for .txt suffix if not binary output */ - if (gdata->output_format != 'b') { - char *dot; - char *format_suffix; - - format_suffix = DEFAULT_TXT_SUFFIX; - - (void)strcpy(suffix, format_suffix); - - dot = strrchr(old_name, '.'); - if ( dot != NULL ) { - int i; - int slen; - int match; - - slen = (int)strlen(format_suffix); - match = 1; - for ( i = 0; i < slen; i++ ) { - if ( dot[i]==0 || - tolower(format_suffix[i]) != tolower(dot[i]) ) { - match = 0; - break; - } - } - if ( match ) { - (void)strcpy(suffix, dot); - *dot = 0; /* truncates prefix and old_name */ - } - } - } - - /* Construct the name */ - (void)md_snprintf(new_name, new_len, - "%s.%d%s", prefix, pid, suffix); - *filename = new_name; - HPROF_FREE(old_name); - - /* Odds are with Windows, this file may not be so unique. */ - (void)remove(gdata->output_filename); - } -} - -static int -get_tok(char **src, char *buf, int buflen, int sep) -{ - int len; - char *p; - - buf[0] = 0; - if ( **src == 0 ) { - return 0; - } - p = strchr(*src, sep); - if ( p==NULL ) { - len = (int)strlen(*src); - p = (*src) + len; - } else { - /*LINTED*/ - len = (int)(p - (*src)); - } - if ( (len+1) > buflen ) { - return 0; - } - (void)memcpy(buf, *src, len); - buf[len] = 0; - if ( *p != 0 && *p == sep ) { - (*src) = p+1; - } else { - (*src) = p; - } - return len; -} - -static jboolean -setBinarySwitch(char **src, jboolean *ptr) -{ - char buf[80]; - - if (!get_tok(src, buf, (int)sizeof(buf), ',')) { - return JNI_FALSE; - } - if (strcmp(buf, "y") == 0) { - *ptr = JNI_TRUE; - } else if (strcmp(buf, "n") == 0) { - *ptr = JNI_FALSE; - } else { - return JNI_FALSE; - } - return JNI_TRUE; -} - -static void -print_usage(void) -{ - - (void)fprintf(stdout, -"\n" -" HPROF: Heap and CPU Profiling Agent (JVMTI Demonstration Code)\n" -"\n" -AGENTNAME " usage: java " AGENTLIB "=[help]|[