--- 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
-
-################################################################################
--- 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)
-
-################################################################################
--- 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:
- *;
-};
--- 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:
- *;
-};
--- 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
--- 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 ||
--- 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 <stdio.h>
-#include <sys/ldr.h>
-#include <errno.h>
-
-#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;
-}
--- 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);
--- 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.<init>(), 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);
- }
- }
-
-}
--- 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 <init> 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 "<init>" and "finalize"
- whose length is 1 and system class methods with name "<clinit>",
- 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 <clinit> 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.<init> 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
-
---------
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#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
--- 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 <stdlib.h>
-#include <string.h>
-
-/* 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
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <time.h>
-#include <errno.h>
-
-/* General JVM/Java functions, types and macros. */
-
-#include <sys/types.h>
-#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 <init> 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
--- 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
--- 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);
-}
--- 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
--- 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("<null>");
- }
- 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<num_elements; i++) {
- (void)read_u2(&p);
- ty = read_u1(&p);
- (void)read_val(&p, ty);
- }
- num_elements = read_u2(&p);
- for(i=0; i<num_elements; i++) {
- (void)read_id(&p);
- ty = read_u1(&p);
- (void)read_val(&p, ty);
- }
- num_elements = read_u2(&p);
- for(i=0; i<num_elements; i++) {
- HprofType ty;
- HprofId id;
-
- id = read_id(&p);
- ty = read_u1(&p);
- add_inst_field_to_cmap(&cmap, id, ty);
- }
- (void)table_create_entry(ctab, &id, sizeof(id), &cmap);
- break;
- CASE_HEAP(HPROF_GC_INSTANCE_DUMP)
- id = read_id(&p);
- trace_serial_num = read_u4(&p);
- id2 = read_id(&p); /* class id */
- num_bytes = read_u4(&p);
- p += num_bytes;
- break;
- CASE_HEAP(HPROF_GC_OBJ_ARRAY_DUMP)
- id = read_id(&p);
- trace_serial_num = read_u4(&p);
- num_elements = read_u4(&p);
- id2 = read_id(&p);
- p += num_elements*(int)sizeof(HprofId);
- break;
- CASE_HEAP(HPROF_GC_PRIM_ARRAY_DUMP)
- id = read_id(&p);
- trace_serial_num = read_u4(&p);
- num_elements = read_u4(&p);
- ty = read_u1(&p);
- p += type_size[ty]*num_elements;
- 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);
-
- /* Scan again once we have our cmap */
- 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);
- check_printf("H#%d@%d %s: id=0x%x\n",
- nrecords, npos, label, id);
- break;
- CASE_HEAP(HPROF_GC_ROOT_JNI_GLOBAL)
- id = read_id(&p);
- id2 = read_id(&p);
- check_printf("H#%d@%d %s: id=0x%x, id2=0x%x\n",
- nrecords, npos, label, id, id2);
- break;
- CASE_HEAP(HPROF_GC_ROOT_JNI_LOCAL)
- id = read_id(&p);
- thread_serial_num = read_u4(&p);
- fr = read_u4(&p);
- check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u, fr=0x%x\n",
- nrecords, npos, label, id, thread_serial_num, fr);
- break;
- CASE_HEAP(HPROF_GC_ROOT_JAVA_FRAME)
- id = read_id(&p);
- thread_serial_num = read_u4(&p);
- fr = read_u4(&p);
- check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u, fr=0x%x\n",
- nrecords, npos, label, id, thread_serial_num, fr);
- break;
- CASE_HEAP(HPROF_GC_ROOT_NATIVE_STACK)
- id = read_id(&p);
- thread_serial_num = read_u4(&p);
- check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u\n",
- nrecords, npos, label, id, thread_serial_num);
- break;
- CASE_HEAP(HPROF_GC_ROOT_STICKY_CLASS)
- id = read_id(&p);
- check_printf("H#%d@%d %s: id=0x%x\n",
- nrecords, npos, label, id);
- break;
- CASE_HEAP(HPROF_GC_ROOT_THREAD_BLOCK)
- id = read_id(&p);
- thread_serial_num = read_u4(&p);
- check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u\n",
- nrecords, npos, label, id, thread_serial_num);
- break;
- CASE_HEAP(HPROF_GC_ROOT_MONITOR_USED)
- id = read_id(&p);
- check_printf("H#%d@%d %s: id=0x%x\n",
- nrecords, npos, label, id);
- break;
- CASE_HEAP(HPROF_GC_ROOT_THREAD_OBJ)
- id = read_id(&p);
- thread_serial_num = read_u4(&p);
- trace_serial_num = read_u4(&p);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u,"
- " trace_serial_num=%u\n",
- nrecords, npos, label, id, thread_serial_num,
- trace_serial_num);
- break;
- CASE_HEAP(HPROF_GC_CLASS_DUMP)
- id = read_id(&p);
- trace_serial_num = read_u4(&p);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u\n",
- nrecords, npos, label, id, trace_serial_num);
- {
- 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);
- check_printf(" su=0x%x, ld=0x%x, si=0x%x,"
- " pr=0x%x, re1=0x%x, re2=0x%x\n",
- sup, ld, si, pr, re1, re2);
- }
- inst_size = read_u4(&p);
- check_printf(" instance_size=%d\n", inst_size);
-
- num_elements = read_u2(&p);
- for(i=0; i<num_elements; i++) {
- HprofType ty;
- unsigned cpi;
- jvalue val;
-
- cpi = read_u2(&p);
- ty = read_u1(&p);
- val = read_val(&p, ty);
- check_printf(" constant_pool %d: cpi=%d, ty=%d, val=",
- i, cpi, ty);
- check_printf_val(ty, val, 1);
- check_printf("\n");
- }
-
- num_elements = read_u2(&p);
- check_printf(" static_field_count=%d\n", num_elements);
- for(i=0; i<num_elements; i++) {
- HprofType ty;
- HprofId id;
- jvalue val;
-
- id = read_id(&p);
- ty = read_u1(&p);
- val = read_val(&p, ty);
- check_printf(" static field %d: ", i);
- check_print_utf8(utab, "id=", id);
- check_printf(", ty=%d, val=", ty);
- check_printf_val(ty, val, 1);
- check_printf("\n");
- }
-
- num_elements = read_u2(&p);
- check_printf(" instance_field_count=%d\n", num_elements);
- for(i=0; i<num_elements; i++) {
- HprofType ty;
- HprofId id;
-
- id = read_id(&p);
- ty = read_u1(&p);
- check_printf(" instance_field %d: ", i);
- check_print_utf8(utab, "id=", id);
- check_printf(", ty=%d\n", ty);
- }
- break;
- CASE_HEAP(HPROF_GC_INSTANCE_DUMP)
- id = read_id(&p);
- trace_serial_num = read_u4(&p);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- id2 = read_id(&p); /* class id */
- num_bytes = read_u4(&p);
- check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u,"
- " cid=0x%x, nbytes=%d\n",
- nrecords, npos, label, id, trace_serial_num,
- id2, num_bytes);
- /* This is a packed set of bytes for the instance fields */
- if ( num_bytes > 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;i<map->n_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<num_elements; i++) {
- HprofId id;
-
- id = read_id(&p);
- check_printf(" [%d]: id=0x%x\n", i, id);
- }
- break;
- CASE_HEAP(HPROF_GC_PRIM_ARRAY_DUMP)
- id = read_id(&p);
- trace_serial_num = read_u4(&p);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- num_elements = read_u4(&p);
- ty = read_u1(&p);
- psave = p;
- check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u, "
- "nelems=%d, ty=%d\n",
- nrecords, npos, label, id, trace_serial_num, num_elements, ty);
- HPROF_ASSERT(HPROF_TYPE_IS_PRIMITIVE(ty));
- if ( num_elements > 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<num_elements; i++) {
- jvalue val;
-
- if ( 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);
-}
--- 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
--- 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;
-}
--- 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
--- 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);
-}
--- 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
--- 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 <signal.h>
-
-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);
- }
-}
--- 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
--- 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.<init> 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);
-}
--- 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
--- 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;
-}
--- 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
--- 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]|[<option>=<value>, ...]\n"
-"\n"
-"Option Name and Value Description Default\n"
-"--------------------- ----------- -------\n"
-"heap=dump|sites|all heap profiling all\n"
-"cpu=samples|times|old CPU usage off\n"
-"monitor=y|n monitor contention n\n"
-"format=a|b text(txt) or binary output a\n"
-"file=<file> write data to file " DEFAULT_OUTPUTFILE "[{" DEFAULT_TXT_SUFFIX "}]\n"
-"net=<host>:<port> send data over a socket off\n"
-"depth=<size> stack trace depth " TO_STR(DEFAULT_TRACE_DEPTH) "\n"
-"interval=<ms> sample interval in ms " TO_STR(DEFAULT_SAMPLE_INTERVAL) "\n"
-"cutoff=<value> output cutoff point " TO_STR(DEFAULT_CUTOFF_POINT) "\n"
-"lineno=y|n line number in traces? y\n"
-"thread=y|n thread in traces? n\n"
-"doe=y|n dump on exit? y\n"
-"msa=y|n Solaris micro state accounting n\n"
-"force=y|n force output to <file> y\n"
-"verbose=y|n print messages about dumps y\n"
-"\n"
-"Obsolete Options\n"
-"----------------\n"
-"gc_okay=y|n\n"
-
-#ifdef DEBUG
-"\n"
-"DEBUG Option Description Default\n"
-"------------ ----------- -------\n"
-"primfields=y|n include primitive field values y\n"
-"primarrays=y|n include primitive array values y\n"
-"debugflags=MASK Various debug flags 0\n"
-" 0x01 Report refs in and of unprepared classes\n"
-"logflags=MASK Logging to stderr 0\n"
-" " TO_STR(LOG_DUMP_MISC) " Misc logging\n"
-" " TO_STR(LOG_DUMP_LISTS) " Dump out the tables\n"
-" " TO_STR(LOG_CHECK_BINARY) " Verify & dump format=b\n"
-"coredump=y|n Core dump on fatal n\n"
-"errorexit=y|n Exit on any error n\n"
-"pause=y|n Pause on onload & echo PID n\n"
-"debug=y|n Turn on all debug checking n\n"
-"X=MASK Internal use only 0\n"
-
-"\n"
-"Environment Variables\n"
-"---------------------\n"
-"_JAVA_HPROF_OPTIONS\n"
-" Options can be added externally via this environment variable.\n"
-" Anything contained in it will get a comma prepended to it (if needed),\n"
-" then it will be added to the end of the options supplied via the\n"
-" " XRUN " or " AGENTLIB " command line option.\n"
-
-#endif
-
-"\n"
-"Examples\n"
-"--------\n"
-" - Get sample cpu information every 20 millisec, with a stack depth of 3:\n"
-" java " AGENTLIB "=cpu=samples,interval=20,depth=3 classname\n"
-" - Get heap usage information based on the allocation sites:\n"
-" java " AGENTLIB "=heap=sites classname\n"
-
-#ifdef DEBUG
-" - Using the external option addition with csh, log details on all runs:\n"
-" setenv _JAVA_HPROF_OPTIONS \"logflags=0xC\"\n"
-" java " AGENTLIB "=cpu=samples classname\n"
-" is the same as:\n"
-" java " AGENTLIB "=cpu=samples,logflags=0xC classname\n"
-#endif
-
-"\n"
-"Notes\n"
-"-----\n"
-" - The option format=b cannot be used with monitor=y.\n"
-" - The option format=b cannot be used with cpu=old|times.\n"
-" - Use of the " XRUN " interface can still be used, e.g.\n"
-" java " XRUN ":[help]|[<option>=<value>, ...]\n"
-" will behave exactly the same as:\n"
-" java " AGENTLIB "=[help]|[<option>=<value>, ...]\n"
-
-#ifdef DEBUG
-" - The debug options and environment variables are available with both java\n"
-" and java_g versions.\n"
-#endif
-
-"\n"
-"Warnings\n"
-"--------\n"
-" - This is demonstration code for the JVMTI interface and use of BCI,\n"
-" it is not an official product or formal part of the JDK.\n"
-" - The " XRUN " interface will be removed in a future release.\n"
-" - The option format=b is considered experimental, this format may change\n"
-" in a future release.\n"
-
-#ifdef DEBUG
-" - The obsolete options may be completely removed in a future release.\n"
-" - The debug options and environment variables are not considered public\n"
-" interfaces and can change or be removed with any type of update of\n"
-" " AGENTNAME ", including patches.\n"
-#endif
-
- );
-}
-
-static void
-option_error(char *description)
-{
- char errmsg[FILENAME_MAX+80];
-
- (void)md_snprintf(errmsg, sizeof(errmsg),
- "%s option error: %s (%s)", AGENTNAME, description, gdata->options);
- errmsg[sizeof(errmsg)-1] = 0;
- HPROF_ERROR(JNI_FALSE, errmsg);
- error_exit_process(1);
-}
-
-static void
-parse_options(char *command_line_options)
-{
- int file_or_net_option_seen = JNI_FALSE;
- char *all_options;
- char *extra_options;
- char *options;
- char *default_filename;
- int ulen;
-
- if (command_line_options == 0)
- command_line_options = "";
-
- if ((strcmp(command_line_options, "help")) == 0) {
- print_usage();
- error_exit_process(0);
- }
-
- extra_options = getenv("_JAVA_HPROF_OPTIONS");
- if ( extra_options == NULL ) {
- extra_options = "";
- }
-
- all_options = HPROF_MALLOC((int)strlen(command_line_options) +
- (int)strlen(extra_options) + 2);
- gdata->options = all_options;
- (void)strcpy(all_options, command_line_options);
- if ( extra_options[0] != 0 ) {
- if ( all_options[0] != 0 ) {
- (void)strcat(all_options, ",");
- }
- (void)strcat(all_options, extra_options);
- }
- options = all_options;
-
- LOG2("parse_options()", all_options);
-
- while (*options) {
- char option[16];
- char suboption[FILENAME_MAX+1];
- char *endptr;
-
- if (!get_tok(&options, option, (int)sizeof(option), '=')) {
- option_error("general syntax error parsing options");
- }
- if (strcmp(option, "file") == 0) {
- if ( file_or_net_option_seen ) {
- option_error("file or net options should only appear once");
- }
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("syntax error parsing file=filename");
- }
- gdata->utf8_output_filename = HPROF_MALLOC((int)strlen(suboption)+1);
- (void)strcpy(gdata->utf8_output_filename, suboption);
- file_or_net_option_seen = JNI_TRUE;
- } else if (strcmp(option, "net") == 0) {
- char port_number[16];
- if (file_or_net_option_seen ) {
- option_error("file or net options should only appear once");
- }
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ':')) {
- option_error("net option missing ':'");
- }
- if (!get_tok(&options, port_number, (int)sizeof(port_number), ',')) {
- option_error("net option missing port");
- }
- gdata->net_hostname = HPROF_MALLOC((int)strlen(suboption)+1);
- (void)strcpy(gdata->net_hostname, suboption);
- gdata->net_port = (int)strtol(port_number, NULL, 10);
- file_or_net_option_seen = JNI_TRUE;
- } else if (strcmp(option, "format") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("syntax error parsing format=a|b");
- }
- if (strcmp(suboption, "a") == 0) {
- gdata->output_format = 'a';
- } else if (strcmp(suboption, "b") == 0) {
- gdata->output_format = 'b';
- } else {
- option_error("format option value must be a|b");
- }
- } else if (strcmp(option, "depth") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("syntax error parsing depth=DECIMAL");
- }
- gdata->max_trace_depth = (int)strtol(suboption, &endptr, 10);
- if ((endptr != NULL && *endptr != 0) || gdata->max_trace_depth < 0) {
- option_error("depth option value must be decimal and >= 0");
- }
- gdata->prof_trace_depth = gdata->max_trace_depth;
- } else if (strcmp(option, "interval") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("syntax error parsing interval=DECIMAL");
- }
- gdata->sample_interval = (int)strtol(suboption, &endptr, 10);
- if ((endptr != NULL && *endptr != 0) || gdata->sample_interval <= 0) {
- option_error("interval option value must be decimal and > 0");
- }
- } else if (strcmp(option, "cutoff") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("syntax error parsing cutoff=DOUBLE");
- }
- gdata->cutoff_point = strtod(suboption, &endptr);
- if ((endptr != NULL && *endptr != 0) || gdata->cutoff_point < 0) {
- option_error("cutoff option value must be floating point and >= 0");
- }
- } else if (strcmp(option, "cpu") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("syntax error parsing cpu=y|samples|times|old");
- }
- if ((strcmp(suboption, "samples") == 0) ||
- (strcmp(suboption, "y") == 0)) {
- gdata->cpu_sampling = JNI_TRUE;
- } else if (strcmp(suboption, "times") == 0) {
- gdata->cpu_timing = JNI_TRUE;
- gdata->old_timing_format = JNI_FALSE;
- } else if (strcmp(suboption, "old") == 0) {
- gdata->cpu_timing = JNI_TRUE;
- gdata->old_timing_format = JNI_TRUE;
- } else {
- option_error("cpu option value must be y|samples|times|old");
- }
- } else if (strcmp(option, "heap") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("syntax error parsing heap=dump|sites|all");
- }
- if (strcmp(suboption, "dump") == 0) {
- gdata->heap_dump = JNI_TRUE;
- } else if (strcmp(suboption, "sites") == 0) {
- gdata->alloc_sites = JNI_TRUE;
- } else if (strcmp(suboption, "all") == 0) {
- gdata->heap_dump = JNI_TRUE;
- gdata->alloc_sites = JNI_TRUE;
- } else {
- option_error("heap option value must be dump|sites|all");
- }
- } else if( strcmp(option,"lineno") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->lineno_in_traces)) ) {
- option_error("lineno option value must be y|n");
- }
- } else if( strcmp(option,"thread") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->thread_in_traces)) ) {
- option_error("thread option value must be y|n");
- }
- } else if( strcmp(option,"doe") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->dump_on_exit)) ) {
- option_error("doe option value must be y|n");
- }
- } else if( strcmp(option,"msa") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->micro_state_accounting)) ) {
- option_error("msa option value must be y|n");
- }
- } else if( strcmp(option,"force") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->force_output)) ) {
- option_error("force option value must be y|n");
- }
- } else if( strcmp(option,"verbose") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->verbose)) ) {
- option_error("verbose option value must be y|n");
- }
- } else if( strcmp(option,"primfields") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->primfields)) ) {
- option_error("primfields option value must be y|n");
- }
- } else if( strcmp(option,"primarrays") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->primarrays)) ) {
- option_error("primarrays option value must be y|n");
- }
- } else if( strcmp(option,"monitor") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->monitor_tracing)) ) {
- option_error("monitor option value must be y|n");
- }
- } else if( strcmp(option,"gc_okay") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->gc_okay)) ) {
- option_error("gc_okay option value must be y|n");
- }
- } else if (strcmp(option, "logflags") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("logflags option value must be numeric");
- }
- gdata->logflags = (int)strtol(suboption, NULL, 0);
- } else if (strcmp(option, "debugflags") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("debugflags option value must be numeric");
- }
- gdata->debugflags = (int)strtol(suboption, NULL, 0);
- } else if (strcmp(option, "coredump") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->coredump)) ) {
- option_error("coredump option value must be y|n");
- }
- } else if (strcmp(option, "exitpause") == 0) {
- option_error("The exitpause option was removed, use -XX:OnError='cmd %%p'");
- } else if (strcmp(option, "errorexit") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->errorexit)) ) {
- option_error("errorexit option value must be y|n");
- }
- } else if (strcmp(option, "pause") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->pause)) ) {
- option_error("pause option value must be y|n");
- }
- } else if (strcmp(option, "debug") == 0) {
- if ( !setBinarySwitch(&options, &(gdata->debug)) ) {
- option_error("debug option value must be y|n");
- }
- } else if (strcmp(option, "precrash") == 0) {
- option_error("The precrash option was removed, use -XX:OnError='precrash -p %%p'");
- } else if (strcmp(option, "X") == 0) {
- if (!get_tok(&options, suboption, (int)sizeof(suboption), ',')) {
- option_error("X option value must be numeric");
- }
- gdata->experiment = (int)strtol(suboption, NULL, 0);
- } else {
- char errmsg[80];
- (void)strcpy(errmsg, "Unknown option: ");
- (void)strcat(errmsg, option);
- option_error(errmsg);
- }
- }
-
- if (gdata->output_format == 'b') {
- if (gdata->cpu_timing) {
- option_error("cpu=times|old is not supported with format=b");
- }
- if (gdata->monitor_tracing) {
- option_error("monitor=y is not supported with format=b");
- }
- }
-
- if (gdata->old_timing_format) {
- gdata->prof_trace_depth = 2;
- }
-
- if (gdata->output_format == 'b') {
- default_filename = DEFAULT_OUTPUTFILE;
- } else {
- default_filename = DEFAULT_OUTPUTFILE DEFAULT_TXT_SUFFIX;
- }
-
- if (!file_or_net_option_seen) {
- gdata->utf8_output_filename = HPROF_MALLOC((int)strlen(default_filename)+1);
- (void)strcpy(gdata->utf8_output_filename, default_filename);
- }
-
- if ( gdata->utf8_output_filename != NULL ) {
- // Don't attempt to convert output filename.
- // If fileystem uses the same encoding as the rest of the OS it will work as is.
- ulen = (int)strlen(gdata->utf8_output_filename);
- gdata->output_filename = (char*)HPROF_MALLOC(ulen*3+3);
- (void)strcpy(gdata->output_filename, gdata->utf8_output_filename);
- }
-
- /* By default we turn on gdata->alloc_sites and gdata->heap_dump */
- if ( !gdata->cpu_timing &&
- !gdata->cpu_sampling &&
- !gdata->monitor_tracing &&
- !gdata->alloc_sites &&
- !gdata->heap_dump) {
- gdata->heap_dump = JNI_TRUE;
- gdata->alloc_sites = JNI_TRUE;
- }
-
- if ( gdata->alloc_sites || gdata->heap_dump ) {
- gdata->obj_watch = JNI_TRUE;
- }
- if ( gdata->obj_watch || gdata->cpu_timing ) {
- gdata->bci = JNI_TRUE;
- }
-
- /* Create files & sockets needed */
- if (gdata->heap_dump) {
- char *base;
- int len;
-
- /* Get a fast tempfile for the heap information */
- base = gdata->output_filename;
- if ( base==NULL ) {
- base = default_filename;
- }
- len = (int)strlen(base);
- gdata->heapfilename = HPROF_MALLOC(len + 5);
- (void)strcpy(gdata->heapfilename, base);
- (void)strcat(gdata->heapfilename, ".TMP");
- make_unique_filename(&(gdata->heapfilename));
- (void)remove(gdata->heapfilename);
- if (gdata->output_format == 'b') {
- if ( gdata->logflags & LOG_CHECK_BINARY ) {
- char * check_suffix;
-
- check_suffix = ".check" DEFAULT_TXT_SUFFIX;
- gdata->checkfilename =
- HPROF_MALLOC((int)strlen(default_filename)+
- (int)strlen(check_suffix)+1);
- (void)strcpy(gdata->checkfilename, default_filename);
- (void)strcat(gdata->checkfilename, check_suffix);
- (void)remove(gdata->checkfilename);
- gdata->check_fd = md_creat(gdata->checkfilename);
- }
- if ( gdata->debug ) {
- gdata->logflags |= LOG_CHECK_BINARY;
- }
- gdata->heap_fd = md_creat_binary(gdata->heapfilename);
- } else {
- gdata->heap_fd = md_creat(gdata->heapfilename);
- }
- if ( gdata->heap_fd < 0 ) {
- char errmsg[FILENAME_MAX+80];
-
- (void)md_snprintf(errmsg, sizeof(errmsg),
- "can't create temp heap file: %s", gdata->heapfilename);
- errmsg[sizeof(errmsg)-1] = 0;
- HPROF_ERROR(JNI_TRUE, errmsg);
- }
- }
-
- if ( gdata->net_port > 0 ) {
- LOG2("Agent_OnLoad", "Connecting to socket");
- gdata->fd = connect_to_socket(gdata->net_hostname, gdata->net_port);
- if (gdata->fd <= 0) {
- char errmsg[120];
-
- (void)md_snprintf(errmsg, sizeof(errmsg),
- "can't connect to %s:%u", gdata->net_hostname, gdata->net_port);
- errmsg[sizeof(errmsg)-1] = 0;
- HPROF_ERROR(JNI_FALSE, errmsg);
- error_exit_process(1);
- }
- gdata->socket = JNI_TRUE;
- } else {
- /* If going out to a file, obey the force=y|n option */
- if ( !gdata->force_output ) {
- make_unique_filename(&(gdata->output_filename));
- }
- /* Make doubly sure this file does NOT exist */
- (void)remove(gdata->output_filename);
- /* Create the file */
- if (gdata->output_format == 'b') {
- gdata->fd = md_creat_binary(gdata->output_filename);
- } else {
- gdata->fd = md_creat(gdata->output_filename);
- }
- if (gdata->fd < 0) {
- char errmsg[FILENAME_MAX+80];
-
- (void)md_snprintf(errmsg, sizeof(errmsg),
- "can't create profile file: %s", gdata->output_filename);
- errmsg[sizeof(errmsg)-1] = 0;
- HPROF_ERROR(JNI_FALSE, errmsg);
- error_exit_process(1);
- }
- }
-
-}
-
-/* ------------------------------------------------------------------- */
-/* Data reset and dump functions */
-
-static void
-reset_all_data(void)
-{
- if (gdata->cpu_sampling || gdata->cpu_timing || gdata->monitor_tracing) {
- rawMonitorEnter(gdata->data_access_lock);
- }
-
- if (gdata->cpu_sampling || gdata->cpu_timing) {
- trace_clear_cost();
- }
- if (gdata->monitor_tracing) {
- monitor_clear();
- }
-
- if (gdata->cpu_sampling || gdata->cpu_timing || gdata->monitor_tracing) {
- rawMonitorExit(gdata->data_access_lock);
- }
-}
-
-static void reset_class_load_status(JNIEnv *env, jthread thread);
-
-static void
-dump_all_data(JNIEnv *env)
-{
- verbose_message("Dumping");
- if (gdata->monitor_tracing) {
- verbose_message(" contended monitor usage ...");
- tls_dump_monitor_state(env);
- monitor_write_contended_time(env, gdata->cutoff_point);
- }
- if (gdata->heap_dump) {
- verbose_message(" Java heap ...");
- /* Update the class table */
- reset_class_load_status(env, NULL);
- site_heapdump(env);
- }
- if (gdata->alloc_sites) {
- verbose_message(" allocation sites ...");
- site_write(env, 0, gdata->cutoff_point);
- }
- if (gdata->cpu_sampling) {
- verbose_message(" CPU usage by sampling running threads ...");
- trace_output_cost(env, gdata->cutoff_point);
- }
- if (gdata->cpu_timing) {
- if (!gdata->old_timing_format) {
- verbose_message(" CPU usage by timing methods ...");
- trace_output_cost(env, gdata->cutoff_point);
- } else {
- verbose_message(" CPU usage in old prof format ...");
- trace_output_cost_in_prof_format(env);
- }
- }
- reset_all_data();
- io_flush();
- verbose_message(" done.\n");
-}
-
-/* ------------------------------------------------------------------- */
-/* Dealing with class load and unload status */
-
-static void
-reset_class_load_status(JNIEnv *env, jthread thread)
-{
-
- WITH_LOCAL_REFS(env, 1) {
- jint class_count;
- jclass *classes;
- jint i;
-
- /* Get all classes from JVMTI, make sure they are in the class table. */
- getLoadedClasses(&classes, &class_count);
-
- /* We don't know if the class list has changed really, so we
- * guess by the class count changing. Don't want to do
- * a bunch of work on classes when it's unnecessary.
- * I assume that even though we have global references on the
- * jclass object that the class is still considered unloaded.
- * (e.g. GC of jclass isn't required for it to be included
- * in the unloaded list, or not in the load list)
- * [Note: Use of Weak references was a performance problem.]
- */
- if ( class_count != gdata->class_count ) {
-
- rawMonitorEnter(gdata->data_access_lock); {
-
- /* Unmark the classes in the load list */
- class_all_status_remove(CLASS_IN_LOAD_LIST);
-
- /* Pretend like it was a class load event */
- for ( i = 0 ; i < class_count ; i++ ) {
- jobject loader;
-
- loader = getClassLoader(classes[i]);
- event_class_load(env, thread, classes[i], loader);
- }
-
- /* Process the classes that have been unloaded */
- class_do_unloads(env);
-
- } rawMonitorExit(gdata->data_access_lock);
-
- }
-
- /* Free the space and save the count. */
- jvmtiDeallocate(classes);
- gdata->class_count = class_count;
-
- } END_WITH_LOCAL_REFS;
-
-}
-
-/* A GC or Death event has happened, so do some cleanup */
-static void
-object_free_cleanup(JNIEnv *env, jboolean force_class_table_reset)
-{
- Stack *stack;
-
- /* Then we process the ObjectFreeStack */
- rawMonitorEnter(gdata->object_free_lock); {
- stack = gdata->object_free_stack;
- gdata->object_free_stack = NULL; /* Will trigger new stack */
- } rawMonitorExit(gdata->object_free_lock);
-
- /* Notice we just grabbed the stack of freed objects so
- * any object free events will create a new stack.
- */
- if ( stack != NULL ) {
- int count;
- int i;
-
- count = stack_depth(stack);
-
- /* If we saw something freed in this GC */
- if ( count > 0 ) {
-
- for ( i = 0 ; i < count ; i++ ) {
- ObjectIndex object_index;
- jlong tag;
-
- tag = *(jlong*)stack_element(stack,i);
- object_index = tag_extract(tag);
-
- (void)object_free(object_index);
- }
-
- /* We reset the class load status (only do this once) */
- reset_class_load_status(env, NULL);
- force_class_table_reset = JNI_FALSE;
-
- }
-
- /* Just terminate this stack object */
- stack_term(stack);
- }
-
- /* We reset the class load status if we haven't and need to */
- if ( force_class_table_reset ) {
- reset_class_load_status(env, NULL);
- }
-
-}
-
-/* Main function for thread that watches for GC finish events */
-static void JNICALL
-gc_finish_watcher(jvmtiEnv *jvmti, JNIEnv *env, void *p)
-{
- jboolean active;
-
- active = JNI_TRUE;
-
- /* Indicate the watcher thread is active */
- rawMonitorEnter(gdata->gc_finish_lock); {
- gdata->gc_finish_active = JNI_TRUE;
- } rawMonitorExit(gdata->gc_finish_lock);
-
- /* Loop while active */
- while ( active ) {
- jboolean do_cleanup;
-
- do_cleanup = JNI_FALSE;
- rawMonitorEnter(gdata->gc_finish_lock); {
- /* Don't wait if VM_DEATH wants us to quit */
- if ( gdata->gc_finish_stop_request ) {
- /* Time to terminate */
- active = JNI_FALSE;
- } else {
- /* Wait for notification to do cleanup, or terminate */
- rawMonitorWait(gdata->gc_finish_lock, 0);
- /* After wait, check to see if VM_DEATH wants us to quit */
- if ( gdata->gc_finish_stop_request ) {
- /* Time to terminate */
- active = JNI_FALSE;
- }
- }
- if ( active && gdata->gc_finish > 0 ) {
- /* Time to cleanup, reset count and prepare for cleanup */
- gdata->gc_finish = 0;
- do_cleanup = JNI_TRUE;
- }
- } rawMonitorExit(gdata->gc_finish_lock);
-
- /* Do the cleanup if requested outside gc_finish_lock */
- if ( do_cleanup ) {
- /* Free up all freed objects, don't force class table reset
- * We cannot let the VM_DEATH complete while we are doing
- * this cleanup. So if during this, VM_DEATH happens,
- * the VM_DEATH callback should block waiting for this
- * loop to terminate, and send a notification to the
- * VM_DEATH thread.
- */
- object_free_cleanup(env, JNI_FALSE);
-
- /* Cleanup the tls table where the Thread objects were GC'd */
- tls_garbage_collect(env);
- }
-
- }
-
- /* Falling out means VM_DEATH is happening, we need to notify VM_DEATH
- * that we are done doing the cleanup. VM_DEATH is waiting on this
- * notify.
- */
- rawMonitorEnter(gdata->gc_finish_lock); {
- gdata->gc_finish_active = JNI_FALSE;
- rawMonitorNotifyAll(gdata->gc_finish_lock);
- } rawMonitorExit(gdata->gc_finish_lock);
-}
-
-/* ------------------------------------------------------------------- */
-/* JVMTI Event callback functions */
-
-static void
-setup_event_mode(jboolean onload_set_only, jvmtiEventMode state)
-{
- if ( onload_set_only ) {
- setEventNotificationMode(state,
- JVMTI_EVENT_VM_INIT, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_VM_DEATH, NULL);
- if (gdata->bci) {
- setEventNotificationMode(state,
- JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
- }
- } else {
- /* Enable all other JVMTI events of interest now. */
- setEventNotificationMode(state,
- JVMTI_EVENT_THREAD_START, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_THREAD_END, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_CLASS_LOAD, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_CLASS_PREPARE, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
- if (gdata->cpu_timing) {
- setEventNotificationMode(state,
- JVMTI_EVENT_EXCEPTION_CATCH, NULL);
- }
- if (gdata->monitor_tracing) {
- setEventNotificationMode(state,
- JVMTI_EVENT_MONITOR_WAIT, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_MONITOR_WAITED, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL);
- }
- if (gdata->obj_watch) {
- setEventNotificationMode(state,
- JVMTI_EVENT_OBJECT_FREE, NULL);
- }
- setEventNotificationMode(state,
- JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL);
- setEventNotificationMode(state,
- JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL);
- }
-}
-
-/* JVMTI_EVENT_VM_INIT */
-static void JNICALL
-cbVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
-{
- rawMonitorEnter(gdata->data_access_lock); {
-
- LoaderIndex loader_index;
- ClassIndex cnum;
- TlsIndex tls_index;
-
- gdata->jvm_initializing = JNI_TRUE;
-
- /* Header to use in heap dumps */
- gdata->header = "JAVA PROFILE 1.0.1";
- gdata->segmented = JNI_FALSE;
- if (gdata->output_format == 'b') {
- /* We need JNI here to call in and get the current maximum memory */
- gdata->maxMemory = getMaxMemory(env);
- gdata->maxHeapSegment = (jlong)2000000000;
- /* More than 2Gig triggers segments and 1.0.2 */
- if ( gdata->maxMemory >= gdata->maxHeapSegment ) {
- gdata->header = "JAVA PROFILE 1.0.2";
- gdata->segmented = JNI_TRUE; /* 1.0.2 */
- }
- }
-
- /* We write the initial header after the VM initializes now
- * because we needed to use JNI to get maxMemory and determine if
- * a 1.0.1 or a 1.0.2 header will be used.
- * This used to be done in Agent_OnLoad.
- */
- io_write_file_header();
-
- LOG("cbVMInit begin");
-
- /* Create a system loader entry first */
- loader_index = loader_find_or_create(NULL,NULL);
-
- /* Find the thread jclass (does JNI calls) */
- gdata->thread_cnum = class_find_or_create("Ljava/lang/Thread;",
- loader_index);
- class_add_status(gdata->thread_cnum, CLASS_SYSTEM);
-
- /* Issue fake system thread start */
- tls_index = tls_find_or_create(env, thread);
-
- /* Setup the Tracker class (should be first class in table) */
- tracker_setup_class();
-
- /* Find selected system classes to keep track of */
- gdata->system_class_size = 0;
- cnum = class_find_or_create("Ljava/lang/Object;", loader_index);
-
- gdata->system_trace_index = tls_get_trace(tls_index, env,
- gdata->max_trace_depth, JNI_FALSE);
- gdata->system_object_site_index = site_find_or_create(
- cnum, gdata->system_trace_index);
-
- /* Used to ID HPROF generated items */
- gdata->hprof_trace_index = tls_get_trace(tls_index, env,
- gdata->max_trace_depth, JNI_FALSE);
- gdata->hprof_site_index = site_find_or_create(
- cnum, gdata->hprof_trace_index);
-
- if ( gdata->logflags & LOG_DUMP_LISTS ) {
- list_all_tables();
- }
-
- /* Prime the class table */
- reset_class_load_status(env, thread);
-
- /* Find the tracker jclass and jmethodID's (does JNI calls) */
- if ( gdata->bci ) {
- tracker_setup_methods(env);
- }
-
- /* Start any agent threads (does JNI, JVMTI, and Java calls) */
-
- /* Thread to watch for gc_finish events */
- rawMonitorEnter(gdata->gc_finish_lock); {
- createAgentThread(env, "HPROF gc_finish watcher",
- &gc_finish_watcher);
- } rawMonitorExit(gdata->gc_finish_lock);
-
- /* Start up listener thread if we need it */
- if ( gdata->socket ) {
- listener_init(env);
- }
-
- /* Start up cpu sampling thread if we need it */
- if ( gdata->cpu_sampling ) {
- /* Note: this could also get started later (see cpu) */
- cpu_sample_init(env);
- }
-
- /* Setup event modes */
- setup_event_mode(JNI_FALSE, JVMTI_ENABLE);
-
- /* Engage tracking (sets Java Tracker field so injections call into
- * agent library).
- */
- if ( gdata->bci ) {
- tracker_engage(env);
- }
-
- /* Indicate the VM is initialized now */
- gdata->jvm_initialized = JNI_TRUE;
- gdata->jvm_initializing = JNI_FALSE;
-
- LOG("cbVMInit end");
-
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-/* JVMTI_EVENT_VM_DEATH */
-static void JNICALL
-cbVMDeath(jvmtiEnv *jvmti, JNIEnv *env)
-{
- /*
- * Use local flag to minimize gdata->dump_lock hold time.
- */
- jboolean need_to_dump = JNI_FALSE;
-
- LOG("cbVMDeath");
-
- /* Shutdown thread watching gc_finish, outside CALLBACK locks.
- * We need to make sure the watcher thread is done doing any cleanup
- * work before we continue here.
- */
- rawMonitorEnter(gdata->gc_finish_lock); {
- /* Notify watcher thread to finish up, it will send
- * another notify when done. If the watcher thread is busy
- * cleaning up, it will detect gc_finish_stop_request when it's done.
- * Then it sets gc_finish_active to JNI_FALSE and will notify us.
- * If the watcher thread is waiting to be notified, then the
- * notification wakes it up.
- * We do not want to do the VM_DEATH while the gc_finish
- * watcher thread is in the middle of a cleanup.
- */
- gdata->gc_finish_stop_request = JNI_TRUE;
- rawMonitorNotifyAll(gdata->gc_finish_lock);
- /* Wait for the gc_finish watcher thread to notify us it's done */
- while ( gdata->gc_finish_active ) {
- rawMonitorWait(gdata->gc_finish_lock,0);
- }
- } rawMonitorExit(gdata->gc_finish_lock);
-
- /* The gc_finish watcher thread should be done now, or done shortly. */
-
-
- /* BEGIN_CALLBACK/END_CALLBACK handling. */
-
- /* The callbackBlock prevents any active callbacks from returning
- * back to the VM, and also blocks all new callbacks.
- * We want to prevent any threads from premature death, so
- * that we don't have worry about that during thread queries
- * in this final dump process.
- */
- rawMonitorEnter(gdata->callbackBlock); {
-
- /* We need to wait for all callbacks actively executing to block
- * on exit, and new ones will block on entry.
- * The BEGIN_CALLBACK/END_CALLBACK macros keep track of callbacks
- * that are active.
- * Once the last active callback is done, it will notify this
- * thread and block.
- */
-
- rawMonitorEnter(gdata->callbackLock); {
- /* Turn off native calls */
- if ( gdata->bci ) {
- tracker_disengage(env);
- }
- gdata->vm_death_callback_active = JNI_TRUE;
- while (gdata->active_callbacks > 0) {
- rawMonitorWait(gdata->callbackLock, 0);
- }
- } rawMonitorExit(gdata->callbackLock);
-
- /* Now we know that no threads will die on us, being blocked
- * on some event callback, at a minimum ThreadEnd.
- */
-
- /* Make some basic checks. */
- rawMonitorEnter(gdata->data_access_lock); {
- if ( gdata->jvm_initializing ) {
- HPROF_ERROR(JNI_TRUE, "VM Death during VM Init");
- return;
- }
- if ( !gdata->jvm_initialized ) {
- HPROF_ERROR(JNI_TRUE, "VM Death before VM Init");
- return;
- }
- if (gdata->jvm_shut_down) {
- HPROF_ERROR(JNI_TRUE, "VM Death more than once?");
- return;
- }
- } rawMonitorExit(gdata->data_access_lock);
-
- /* Shutdown the cpu loop thread */
- if ( gdata->cpu_sampling ) {
- cpu_sample_term(env);
- }
-
- /* Time to dump the final data */
- rawMonitorEnter(gdata->dump_lock); {
-
- gdata->jvm_shut_down = JNI_TRUE;
-
- if (!gdata->dump_in_process) {
- need_to_dump = JNI_TRUE;
- gdata->dump_in_process = JNI_TRUE;
- /*
- * Setting gdata->dump_in_process will cause cpu sampling to pause
- * (if we are sampling). We don't resume sampling after the
- * dump_all_data() call below because the VM is shutting
- * down.
- */
- }
-
- } rawMonitorExit(gdata->dump_lock);
-
- /* Dump everything if we need to */
- if (gdata->dump_on_exit && need_to_dump) {
-
- dump_all_data(env);
- }
-
- /* Disable all events and callbacks now, all of them.
- * NOTE: It's important that this be done after the dump
- * it prevents other threads from messing up the data
- * because they will block on ThreadStart and ThreadEnd
- * events due to the CALLBACK block.
- */
- set_callbacks(JNI_FALSE);
- setup_event_mode(JNI_FALSE, JVMTI_DISABLE);
- setup_event_mode(JNI_TRUE, JVMTI_DISABLE);
-
- /* Write tail of file */
- io_write_file_footer();
-
- } rawMonitorExit(gdata->callbackBlock);
-
- /* Shutdown the listener thread and socket, or flush I/O buffers */
- if (gdata->socket) {
- listener_term(env);
- } else {
- io_flush();
- }
-
- /* Close the file descriptors down */
- if ( gdata->fd >= 0 ) {
- (void)md_close(gdata->fd);
- gdata->fd = -1;
- if ( gdata->logflags & LOG_CHECK_BINARY ) {
- if (gdata->output_format == 'b' && gdata->output_filename != NULL) {
- check_binary_file(gdata->output_filename);
- }
- }
- }
- if ( gdata->heap_fd >= 0 ) {
- (void)md_close(gdata->heap_fd);
- gdata->heap_fd = -1;
- }
-
- if ( gdata->check_fd >= 0 ) {
- (void)md_close(gdata->check_fd);
- gdata->check_fd = -1;
- }
-
- /* Remove the temporary heap file */
- if (gdata->heap_dump) {
- (void)remove(gdata->heapfilename);
- }
-
- /* If logging, dump the tables */
- if ( gdata->logflags & LOG_DUMP_LISTS ) {
- list_all_tables();
- }
-
- /* Make sure all global references are deleted */
- class_delete_global_references(env);
- loader_delete_global_references(env);
- tls_delete_global_references(env);
-
-}
-
-/* JVMTI_EVENT_THREAD_START */
-static void JNICALL
-cbThreadStart(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
-{
- LOG3("cbThreadStart", "thread is", (int)(long)(ptrdiff_t)thread);
-
- BEGIN_CALLBACK() {
- event_thread_start(env, thread);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_THREAD_END */
-static void JNICALL
-cbThreadEnd(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
-{
- LOG3("cbThreadEnd", "thread is", (int)(long)(ptrdiff_t)thread);
-
- BEGIN_CALLBACK() {
- event_thread_end(env, thread);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */
-static void JNICALL
-cbClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv* env,
- jclass class_being_redefined, jobject loader,
- const char* name, jobject protection_domain,
- jint class_data_len, const unsigned char* class_data,
- jint* new_class_data_len, unsigned char** new_class_data)
-{
-
- /* WARNING: This will be called before VM_INIT. */
-
- LOG2("cbClassFileLoadHook:",(name==NULL?"Unknown":name));
-
- if (!gdata->bci) {
- return;
- }
-
- BEGIN_CALLBACK() {
- rawMonitorEnter(gdata->data_access_lock); {
- const char *classname;
-
- if ( gdata->bci_counter == 0 ) {
- /* Prime the system classes */
- class_prime_system_classes();
- }
-
- gdata->bci_counter++;
-
- *new_class_data_len = 0;
- *new_class_data = NULL;
-
- /* Name could be NULL */
- if ( name == NULL ) {
- classname = ((JavaCrwDemoClassname)
- (gdata->java_crw_demo_classname_function))
- (class_data, class_data_len, &my_crw_fatal_error_handler);
- if ( classname == NULL ) {
- HPROF_ERROR(JNI_TRUE, "No classname in classfile");
- }
- } else {
- classname = strdup(name);
- if ( classname == NULL ) {
- HPROF_ERROR(JNI_TRUE, "Ran out of malloc() space");
- }
- }
-
- /* The tracker class itself? */
- if ( strcmp(classname, TRACKER_CLASS_NAME) != 0 ) {
- ClassIndex cnum;
- int system_class;
- unsigned char * new_image;
- long new_length;
- int len;
- char *signature;
- LoaderIndex loader_index;
-
- LOG2("cbClassFileLoadHook injecting class" , classname);
-
- /* Define a unique class number for this class */
- len = (int)strlen(classname);
- signature = HPROF_MALLOC(len+3);
- signature[0] = JVM_SIGNATURE_CLASS;
- (void)memcpy(signature+1, classname, len);
- signature[len+1] = JVM_SIGNATURE_ENDCLASS;
- signature[len+2] = 0;
- loader_index = loader_find_or_create(env,loader);
- if ( class_being_redefined != NULL ) {
- cnum = class_find_or_create(signature, loader_index);
- } else {
- cnum = class_create(signature, loader_index);
- }
- HPROF_FREE(signature);
- signature = NULL;
-
- /* Make sure class doesn't get unloaded by accident */
- class_add_status(cnum, CLASS_IN_LOAD_LIST);
-
- /* Is it a system class? */
- system_class = 0;
- if ( (!gdata->jvm_initialized)
- && (!gdata->jvm_initializing)
- && ( ( class_get_status(cnum) & CLASS_SYSTEM) != 0
- || gdata->bci_counter < 8 ) ) {
- system_class = 1;
- LOG2(classname, " is a system class");
- }
-
- new_image = NULL;
- new_length = 0;
-
- /* Call the class file reader/write demo code */
- ((JavaCrwDemo)(gdata->java_crw_demo_function))(
- cnum,
- classname,
- class_data,
- class_data_len,
- system_class,
- TRACKER_CLASS_NAME,
- TRACKER_CLASS_SIG,
- (gdata->cpu_timing)?TRACKER_CALL_NAME:NULL,
- (gdata->cpu_timing)?TRACKER_CALL_SIG:NULL,
- (gdata->cpu_timing)?TRACKER_RETURN_NAME:NULL,
- (gdata->cpu_timing)?TRACKER_RETURN_SIG:NULL,
- (gdata->obj_watch)?TRACKER_OBJECT_INIT_NAME:NULL,
- (gdata->obj_watch)?TRACKER_OBJECT_INIT_SIG:NULL,
- (gdata->obj_watch)?TRACKER_NEWARRAY_NAME:NULL,
- (gdata->obj_watch)?TRACKER_NEWARRAY_SIG:NULL,
- &new_image,
- &new_length,
- &my_crw_fatal_error_handler,
- &class_set_methods);
-
- if ( new_length > 0 ) {
- unsigned char *jvmti_space;
-
- LOG2("cbClassFileLoadHook DID inject this class", classname);
- jvmti_space = (unsigned char *)jvmtiAllocate((jint)new_length);
- (void)memcpy((void*)jvmti_space, (void*)new_image, (int)new_length);
- *new_class_data_len = (jint)new_length;
- *new_class_data = jvmti_space; /* VM will deallocate */
- } else {
- LOG2("cbClassFileLoadHook DID NOT inject this class", classname);
- *new_class_data_len = 0;
- *new_class_data = NULL;
- }
- if ( new_image != NULL ) {
- (void)free((void*)new_image); /* Free malloc() space with free() */
- }
- }
- (void)free((void*)classname);
- } rawMonitorExit(gdata->data_access_lock);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_CLASS_LOAD */
-static void JNICALL
-cbClassLoad(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass)
-{
-
- /* WARNING: This MAY be called before VM_INIT. */
-
- LOG("cbClassLoad");
-
- BEGIN_CALLBACK() {
- rawMonitorEnter(gdata->data_access_lock); {
-
- WITH_LOCAL_REFS(env, 1) {
- jobject loader;
-
- loader = getClassLoader(klass);
- event_class_load(env, thread, klass, loader);
- } END_WITH_LOCAL_REFS;
-
- } rawMonitorExit(gdata->data_access_lock);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_CLASS_PREPARE */
-static void JNICALL
-cbClassPrepare(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass)
-{
-
- /* WARNING: This will be called before VM_INIT. */
-
- LOG("cbClassPrepare");
-
- BEGIN_CALLBACK() {
- rawMonitorEnter(gdata->data_access_lock); {
-
- WITH_LOCAL_REFS(env, 1) {
- jobject loader;
-
- loader = NULL;
- loader = getClassLoader(klass);
- event_class_prepare(env, thread, klass, loader);
- } END_WITH_LOCAL_REFS;
-
- } rawMonitorExit(gdata->data_access_lock);
- } END_CALLBACK();
-
-}
-
-/* JVMTI_EVENT_DATA_DUMP_REQUEST */
-static void JNICALL
-cbDataDumpRequest(jvmtiEnv *jvmti)
-{
- jboolean need_to_dump;
-
- LOG("cbDataDumpRequest");
-
- BEGIN_CALLBACK() {
- need_to_dump = JNI_FALSE;
- rawMonitorEnter(gdata->dump_lock); {
- if (!gdata->dump_in_process) {
- need_to_dump = JNI_TRUE;
- gdata->dump_in_process = JNI_TRUE;
- }
- } rawMonitorExit(gdata->dump_lock);
-
- if (need_to_dump) {
- dump_all_data(getEnv());
-
- rawMonitorEnter(gdata->dump_lock); {
- gdata->dump_in_process = JNI_FALSE;
- } rawMonitorExit(gdata->dump_lock);
-
- if (gdata->cpu_sampling && !gdata->jvm_shut_down) {
- cpu_sample_on(NULL, 0); /* resume sampling */
- }
- }
- } END_CALLBACK();
-
-}
-
-/* JVMTI_EVENT_EXCEPTION_CATCH */
-static void JNICALL
-cbExceptionCatch(jvmtiEnv *jvmti, JNIEnv* env,
- jthread thread, jmethodID method, jlocation location,
- jobject exception)
-{
- LOG("cbExceptionCatch");
-
- BEGIN_CALLBACK() {
- event_exception_catch(env, thread, method, location, exception);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_MONITOR_WAIT */
-static void JNICALL
-cbMonitorWait(jvmtiEnv *jvmti, JNIEnv* env,
- jthread thread, jobject object, jlong timeout)
-{
- LOG("cbMonitorWait");
-
- BEGIN_CALLBACK() {
- monitor_wait_event(env, thread, object, timeout);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_MONITOR_WAITED */
-static void JNICALL
-cbMonitorWaited(jvmtiEnv *jvmti, JNIEnv* env,
- jthread thread, jobject object, jboolean timed_out)
-{
- LOG("cbMonitorWaited");
-
- BEGIN_CALLBACK() {
- monitor_waited_event(env, thread, object, timed_out);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_MONITOR_CONTENDED_ENTER */
-static void JNICALL
-cbMonitorContendedEnter(jvmtiEnv *jvmti, JNIEnv* env,
- jthread thread, jobject object)
-{
- LOG("cbMonitorContendedEnter");
-
- BEGIN_CALLBACK() {
- monitor_contended_enter_event(env, thread, object);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_MONITOR_CONTENDED_ENTERED */
-static void JNICALL
-cbMonitorContendedEntered(jvmtiEnv *jvmti, JNIEnv* env,
- jthread thread, jobject object)
-{
- LOG("cbMonitorContendedEntered");
-
- BEGIN_CALLBACK() {
- monitor_contended_entered_event(env, thread, object);
- } END_CALLBACK();
-}
-
-/* JVMTI_EVENT_GARBAGE_COLLECTION_START */
-static void JNICALL
-cbGarbageCollectionStart(jvmtiEnv *jvmti)
-{
- LOG("cbGarbageCollectionStart");
-
- /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
- * are allowed here (see the JVMTI Spec).
- */
-
- gdata->gc_start_time = md_get_timemillis();
-}
-
-/* JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */
-static void JNICALL
-cbGarbageCollectionFinish(jvmtiEnv *jvmti)
-{
- LOG("cbGarbageCollectionFinish");
-
- /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
- * are allowed here (see the JVMTI Spec).
- */
-
- if ( gdata->gc_start_time != -1L ) {
- gdata->time_in_gc += (md_get_timemillis() - gdata->gc_start_time);
- gdata->gc_start_time = -1L;
- }
-
- /* Increment gc_finish counter, notify watcher thread */
- rawMonitorEnter(gdata->gc_finish_lock); {
- /* If VM_DEATH is trying to shut it down, don't do anything at all.
- * Never send notify if VM_DEATH wants the watcher thread to quit.
- */
- if ( gdata->gc_finish_active ) {
- gdata->gc_finish++;
- rawMonitorNotifyAll(gdata->gc_finish_lock);
- }
- } rawMonitorExit(gdata->gc_finish_lock);
-}
-
-/* JVMTI_EVENT_OBJECT_FREE */
-static void JNICALL
-cbObjectFree(jvmtiEnv *jvmti, jlong tag)
-{
- LOG3("cbObjectFree", "tag", (int)tag);
-
- /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
- * are allowed here (see the JVMTI Spec).
- */
-
- HPROF_ASSERT(tag!=(jlong)0);
- rawMonitorEnter(gdata->object_free_lock); {
- if ( !gdata->jvm_shut_down ) {
- Stack *stack;
-
- stack = gdata->object_free_stack;
- if ( stack == NULL ) {
- gdata->object_free_stack = stack_init(512, 512, sizeof(jlong));
- stack = gdata->object_free_stack;
- }
- stack_push(stack, (void*)&tag);
- }
- } rawMonitorExit(gdata->object_free_lock);
-}
-
-static void
-set_callbacks(jboolean on)
-{
- jvmtiEventCallbacks callbacks;
-
- (void)memset(&callbacks,0,sizeof(callbacks));
- if ( ! on ) {
- setEventCallbacks(&callbacks);
- return;
- }
-
- /* JVMTI_EVENT_VM_INIT */
- callbacks.VMInit = &cbVMInit;
- /* JVMTI_EVENT_VM_DEATH */
- callbacks.VMDeath = &cbVMDeath;
- /* JVMTI_EVENT_THREAD_START */
- callbacks.ThreadStart = &cbThreadStart;
- /* JVMTI_EVENT_THREAD_END */
- callbacks.ThreadEnd = &cbThreadEnd;
- /* JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */
- callbacks.ClassFileLoadHook = &cbClassFileLoadHook;
- /* JVMTI_EVENT_CLASS_LOAD */
- callbacks.ClassLoad = &cbClassLoad;
- /* JVMTI_EVENT_CLASS_PREPARE */
- callbacks.ClassPrepare = &cbClassPrepare;
- /* JVMTI_EVENT_DATA_DUMP_REQUEST */
- callbacks.DataDumpRequest = &cbDataDumpRequest;
- /* JVMTI_EVENT_EXCEPTION_CATCH */
- callbacks.ExceptionCatch = &cbExceptionCatch;
- /* JVMTI_EVENT_MONITOR_WAIT */
- callbacks.MonitorWait = &cbMonitorWait;
- /* JVMTI_EVENT_MONITOR_WAITED */
- callbacks.MonitorWaited = &cbMonitorWaited;
- /* JVMTI_EVENT_MONITOR_CONTENDED_ENTER */
- callbacks.MonitorContendedEnter = &cbMonitorContendedEnter;
- /* JVMTI_EVENT_MONITOR_CONTENDED_ENTERED */
- callbacks.MonitorContendedEntered = &cbMonitorContendedEntered;
- /* JVMTI_EVENT_GARBAGE_COLLECTION_START */
- callbacks.GarbageCollectionStart = &cbGarbageCollectionStart;
- /* JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */
- callbacks.GarbageCollectionFinish = &cbGarbageCollectionFinish;
- /* JVMTI_EVENT_OBJECT_FREE */
- callbacks.ObjectFree = &cbObjectFree;
-
- setEventCallbacks(&callbacks);
-
-}
-
-static void
-getCapabilities(void)
-{
- jvmtiCapabilities needed_capabilities;
- jvmtiCapabilities potential_capabilities;
-
- /* Fill in ones that we must have */
- (void)memset(&needed_capabilities,0,sizeof(needed_capabilities));
- needed_capabilities.can_generate_garbage_collection_events = 1;
- needed_capabilities.can_tag_objects = 1;
- if (gdata->bci) {
- needed_capabilities.can_generate_all_class_hook_events = 1;
- }
- if (gdata->obj_watch) {
- needed_capabilities.can_generate_object_free_events = 1;
- }
- if (gdata->cpu_timing || gdata->cpu_sampling) {
- #if 0 /* Not needed until we call JVMTI for CpuTime */
- needed_capabilities.can_get_thread_cpu_time = 1;
- needed_capabilities.can_get_current_thread_cpu_time = 1;
- #endif
- needed_capabilities.can_generate_exception_events = 1;
- }
- if (gdata->monitor_tracing) {
- #if 0 /* Not needed until we call JVMTI for CpuTime */
- needed_capabilities.can_get_thread_cpu_time = 1;
- needed_capabilities.can_get_current_thread_cpu_time = 1;
- #endif
- needed_capabilities.can_get_owned_monitor_info = 1;
- needed_capabilities.can_get_current_contended_monitor = 1;
- needed_capabilities.can_get_monitor_info = 1;
- needed_capabilities.can_generate_monitor_events = 1;
- }
-
- /* Get potential capabilities */
- getPotentialCapabilities(&potential_capabilities);
-
- /* Some capabilities would be nicer to have */
- needed_capabilities.can_get_source_file_name =
- potential_capabilities.can_get_source_file_name;
- needed_capabilities.can_get_line_numbers =
- potential_capabilities.can_get_line_numbers;
-
- /* Add the capabilities */
- addCapabilities(&needed_capabilities);
-
-}
-
-/* Dynamic library loading */
-static void *
-load_library(char *name)
-{
- char lname[FILENAME_MAX+1];
- char err_buf[256+FILENAME_MAX+1];
- char *boot_path;
- void *handle;
-
- handle = NULL;
-
- /* The library may be located in different ways, try both, but
- * if it comes from outside the SDK/jre it isn't ours.
- */
- getSystemProperty("sun.boot.library.path", &boot_path);
- md_build_library_name(lname, FILENAME_MAX, boot_path, name);
- if ( strlen(lname) == 0 ) {
- HPROF_ERROR(JNI_TRUE, "Could not find library");
- }
- jvmtiDeallocate(boot_path);
- handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
- if ( handle == NULL ) {
- /* This may be necessary on Windows. */
- md_build_library_name(lname, FILENAME_MAX, "", name);
- if ( strlen(lname) == 0 ) {
- HPROF_ERROR(JNI_TRUE, "Could not find library");
- }
- handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
- if ( handle == NULL ) {
- HPROF_ERROR(JNI_TRUE, err_buf);
- }
- }
- return handle;
-}
-
-/* Lookup dynamic function pointer in shared library */
-static void *
-lookup_library_symbol(void *library, char **symbols, int nsymbols)
-{
- void *addr;
- int i;
-
- addr = NULL;
- for( i = 0 ; i < nsymbols; i++ ) {
- addr = md_find_library_entry(library, symbols[i]);
- if ( addr != NULL ) {
- break;
- }
- }
- if ( addr == NULL ) {
- char errmsg[256];
-
- (void)md_snprintf(errmsg, sizeof(errmsg),
- "Cannot find library symbol '%s'", symbols[0]);
- HPROF_ERROR(JNI_TRUE, errmsg);
- }
- return addr;
-}
-
-/* ------------------------------------------------------------------- */
-/* The OnLoad interface */
-
-JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
-{
- char *boot_path = NULL;
-
- /* See if it's already loaded */
- if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
- HPROF_ERROR(JNI_TRUE, "Cannot load this JVM TI agent twice, check your java command line for duplicate hprof options.");
- return JNI_ERR;
- }
-
- gdata = get_gdata();
-
- gdata->isLoaded = JNI_TRUE;
-
- error_setup();
-
- LOG2("Agent_OnLoad", "gdata setup");
-
- gdata->jvm = vm;
-
- /* Get the JVMTI environment */
- getJvmti();
-
- /* Lock needed to protect debug_malloc() code, which is not MT safe */
- #ifdef DEBUG
- gdata->debug_malloc_lock = createRawMonitor("HPROF debug_malloc lock");
- #endif
-
- parse_options(options);
-
- LOG2("Agent_OnLoad", "Has jvmtiEnv and options parsed");
-
- /* Initialize machine dependent code (micro state accounting) */
- md_init();
-
- string_init(); /* Table index values look like: 0x10000000 */
-
- class_init(); /* Table index values look like: 0x20000000 */
- tls_init(); /* Table index values look like: 0x30000000 */
- trace_init(); /* Table index values look like: 0x40000000 */
- object_init(); /* Table index values look like: 0x50000000 */
-
- site_init(); /* Table index values look like: 0x60000000 */
- frame_init(); /* Table index values look like: 0x70000000 */
- monitor_init(); /* Table index values look like: 0x80000000 */
- loader_init(); /* Table index values look like: 0x90000000 */
-
- LOG2("Agent_OnLoad", "Tables initialized");
-
- if ( gdata->pause ) {
- error_do_pause();
- }
-
- getCapabilities();
-
- /* Set the JVMTI callback functions (do this only once)*/
- set_callbacks(JNI_TRUE);
-
- /* Create basic locks */
- gdata->dump_lock = createRawMonitor("HPROF dump lock");
- gdata->data_access_lock = createRawMonitor("HPROF data access lock");
- gdata->callbackLock = createRawMonitor("HPROF callback lock");
- gdata->callbackBlock = createRawMonitor("HPROF callback block");
- gdata->object_free_lock = createRawMonitor("HPROF object free lock");
- gdata->gc_finish_lock = createRawMonitor("HPROF gc_finish lock");
-
- /* Set Onload events mode. */
- setup_event_mode(JNI_TRUE, JVMTI_ENABLE);
-
- LOG2("Agent_OnLoad", "JVMTI capabilities, callbacks and initial notifications setup");
-
- /* Used in VM_DEATH to wait for callbacks to complete */
- gdata->jvm_initializing = JNI_FALSE;
- gdata->jvm_initialized = JNI_FALSE;
- gdata->vm_death_callback_active = JNI_FALSE;
- gdata->active_callbacks = 0;
-
- /* Write the header information */
- io_setup();
-
- /* We sample the start time now so that the time increments can be
- * placed in the various heap dump segments in micro seconds.
- */
- gdata->micro_sec_ticks = md_get_microsecs();
-
- /* Load java_crw_demo library and find function "java_crw_demo" */
- if ( gdata->bci ) {
-
- /* Load the library or get the handle to it */
- gdata->java_crw_demo_library = load_library("java_crw_demo");
-
- { /* "java_crw_demo" */
- static char *symbols[] = JAVA_CRW_DEMO_SYMBOLS;
- gdata->java_crw_demo_function =
- lookup_library_symbol(gdata->java_crw_demo_library,
- symbols, (int)(sizeof(symbols)/sizeof(char*)));
- }
- { /* "java_crw_demo_classname" */
- static char *symbols[] = JAVA_CRW_DEMO_CLASSNAME_SYMBOLS;
- gdata->java_crw_demo_classname_function =
- lookup_library_symbol(gdata->java_crw_demo_library,
- symbols, (int)(sizeof(symbols)/sizeof(char*)));
- }
- }
-
- return JNI_OK;
-}
-
-JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
-{
- Stack *stack;
-
- LOG("Agent_OnUnload");
-
- gdata->isLoaded = JNI_FALSE;
-
- stack = gdata->object_free_stack;
- gdata->object_free_stack = NULL;
- if ( stack != NULL ) {
- stack_term(stack);
- }
-
- io_cleanup();
- loader_cleanup();
- tls_cleanup();
- monitor_cleanup();
- trace_cleanup();
- site_cleanup();
- object_cleanup();
- frame_cleanup();
- class_cleanup();
- string_cleanup();
-
- /* Deallocate any memory in gdata */
- if ( gdata->net_hostname != NULL ) {
- HPROF_FREE(gdata->net_hostname);
- }
- if ( gdata->utf8_output_filename != NULL ) {
- HPROF_FREE(gdata->utf8_output_filename);
- }
- if ( gdata->output_filename != NULL ) {
- HPROF_FREE(gdata->output_filename);
- }
- if ( gdata->heapfilename != NULL ) {
- HPROF_FREE(gdata->heapfilename);
- }
- if ( gdata->checkfilename != NULL ) {
- HPROF_FREE(gdata->checkfilename);
- }
- if ( gdata->options != NULL ) {
- HPROF_FREE(gdata->options);
- }
-
- /* Verify all allocated memory has been taken care of. */
- malloc_police();
-
- /* Cleanup is hard to do when other threads might still be running
- * so we skip destroying some raw monitors which still might be in use
- * and we skip disposal of the jvmtiEnv* which might still be needed.
- * Only raw monitors that could be held by other threads are left
- * alone. So we explicitly do NOT do this:
- * destroyRawMonitor(gdata->callbackLock);
- * destroyRawMonitor(gdata->callbackBlock);
- * destroyRawMonitor(gdata->gc_finish_lock);
- * destroyRawMonitor(gdata->object_free_lock);
- * destroyRawMonitor(gdata->listener_loop_lock);
- * destroyRawMonitor(gdata->cpu_loop_lock);
- * disposeEnvironment();
- * gdata->jvmti = NULL;
- */
-
- /* Destroy basic locks */
- destroyRawMonitor(gdata->dump_lock);
- gdata->dump_lock = NULL;
- destroyRawMonitor(gdata->data_access_lock);
- gdata->data_access_lock = NULL;
- if ( gdata->cpu_sample_lock != NULL ) {
- destroyRawMonitor(gdata->cpu_sample_lock);
- gdata->cpu_sample_lock = NULL;
- }
- #ifdef DEBUG
- destroyRawMonitor(gdata->debug_malloc_lock);
- gdata->debug_malloc_lock = NULL;
- #endif
-
- /* Unload java_crw_demo library */
- if ( gdata->bci && gdata->java_crw_demo_library != NULL ) {
- md_unload_library(gdata->java_crw_demo_library);
- gdata->java_crw_demo_library = NULL;
- }
-
- /* You would think you could clear out gdata and set it to NULL, but
- * turns out that isn't a good idea. Some of the threads could be
- * blocked inside the CALLBACK*() macros, where they got blocked up
- * waiting for the VM_DEATH callback to complete. They only have
- * some raw monitor actions to do, but they need access to gdata to do it.
- * So do not do this:
- * (void)memset(gdata, 0, sizeof(GlobalData));
- * gdata = NULL;
- */
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_init.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +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_INIT_H
-#define HPROF_INIT_H
-
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_io.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1980 +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.
- */
-
-
-/* All I/O functionality for hprof. */
-
-/*
- * The hprof agent has many forms of output:
- *
- * format=b gdata->output_format=='b'
- * Binary format. Defined below. This is used by HAT.
- * This is NOT the same format as emitted by JVMPI.
- *
- * format=a gdata->output_format=='a'
- * Ascii format. Not exactly an ascii representation of the binary format.
- *
- * And many forms of dumps:
- *
- * heap=dump
- * A large dump that in this implementation is written to a separate
- * file first before being placed in the output file. Several reasons,
- * the binary form needs a byte count of the length in the header, and
- * references in this dump to other items need to be emitted first.
- * So it's two pass, or use a temp file and copy.
- * heap=sites
- * Dumps the sites in the order of most allocations.
- * cpu=samples
- * Dumps the traces in order of most hits
- * cpu=times
- * Dumps the traces in the order of most time spent there.
- * cpu=old (format=a only)
- * Dumps out an older form of cpu output (old -prof format)
- * monitor=y (format=a only)
- * Dumps out a list of monitors in order of most contended.
- *
- * This file also includes a binary format check function that will read
- * back in the hprof binary format and verify the syntax looks correct.
- *
- * WARNING: Besides the comments below, there is little format spec on this,
- * however see:
- * http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html#hprof
- */
-
-#include "hprof.h"
-
-typedef TableIndex HprofId;
-
-#include "hprof_ioname.h"
-#include "hprof_b_spec.h"
-
-static int type_size[ /*HprofType*/ ] = HPROF_TYPE_SIZES;
-
-static void dump_heap_segment_and_reset(jlong segment_size);
-
-static void
-not_implemented(void)
-{
-}
-
-static IoNameIndex
-get_name_index(char *name)
-{
- if (name != NULL && gdata->output_format == 'b') {
- return ioname_find_or_create(name, NULL);
- }
- return 0;
-}
-
-static char *
-signature_to_name(char *sig)
-{
- char *ptr;
- char *basename;
- char *name;
- int i;
- int len;
- int name_len;
-
- if ( sig != NULL ) {
- switch ( sig[0] ) {
- case JVM_SIGNATURE_CLASS:
- ptr = strchr(sig+1, JVM_SIGNATURE_ENDCLASS);
- if ( ptr == NULL ) {
- basename = "Unknown_class";
- break;
- }
- /*LINTED*/
- name_len = (jint)(ptr - (sig+1));
- name = HPROF_MALLOC(name_len+1);
- (void)memcpy(name, sig+1, name_len);
- name[name_len] = 0;
- for ( i = 0 ; i < name_len ; i++ ) {
- if ( name[i] == '/' ) name[i] = '.';
- }
- return name;
- case JVM_SIGNATURE_ARRAY:
- basename = signature_to_name(sig+1);
- len = (int)strlen(basename);
- name_len = len+2;
- name = HPROF_MALLOC(name_len+1);
- (void)memcpy(name, basename, len);
- (void)memcpy(name+len, "[]", 2);
- name[name_len] = 0;
- HPROF_FREE(basename);
- return name;
- case JVM_SIGNATURE_FUNC:
- ptr = strchr(sig+1, JVM_SIGNATURE_ENDFUNC);
- if ( ptr == NULL ) {
- basename = "Unknown_method";
- break;
- }
- basename = "()"; /* Someday deal with method signatures */
- break;
- case JVM_SIGNATURE_BYTE:
- basename = "byte";
- break;
- case JVM_SIGNATURE_CHAR:
- basename = "char";
- break;
- case JVM_SIGNATURE_ENUM:
- basename = "enum";
- break;
- case JVM_SIGNATURE_FLOAT:
- basename = "float";
- break;
- case JVM_SIGNATURE_DOUBLE:
- basename = "double";
- break;
- case JVM_SIGNATURE_INT:
- basename = "int";
- break;
- case JVM_SIGNATURE_LONG:
- basename = "long";
- break;
- case JVM_SIGNATURE_SHORT:
- basename = "short";
- break;
- case JVM_SIGNATURE_VOID:
- basename = "void";
- break;
- case JVM_SIGNATURE_BOOLEAN:
- basename = "boolean";
- break;
- default:
- basename = "Unknown_class";
- break;
- }
- } else {
- basename = "Unknown_class";
- }
-
- /* Simple basename */
- name_len = (int)strlen(basename);
- name = HPROF_MALLOC(name_len+1);
- (void)strcpy(name, basename);
- return name;
-}
-
-static int
-size_from_field_info(int size)
-{
- if ( size == 0 ) {
- size = (int)sizeof(HprofId);
- }
- return size;
-}
-
-static void
-type_from_signature(const char *sig, HprofType *kind, jint *size)
-{
- *kind = HPROF_NORMAL_OBJECT;
- *size = 0;
- switch ( sig[0] ) {
- case JVM_SIGNATURE_ENUM:
- case JVM_SIGNATURE_CLASS:
- case JVM_SIGNATURE_ARRAY:
- *kind = HPROF_NORMAL_OBJECT;
- break;
- case JVM_SIGNATURE_BOOLEAN:
- *kind = HPROF_BOOLEAN;
- break;
- case JVM_SIGNATURE_CHAR:
- *kind = HPROF_CHAR;
- break;
- case JVM_SIGNATURE_FLOAT:
- *kind = HPROF_FLOAT;
- break;
- case JVM_SIGNATURE_DOUBLE:
- *kind = HPROF_DOUBLE;
- break;
- case JVM_SIGNATURE_BYTE:
- *kind = HPROF_BYTE;
- break;
- case JVM_SIGNATURE_SHORT:
- *kind = HPROF_SHORT;
- break;
- case JVM_SIGNATURE_INT:
- *kind = HPROF_INT;
- break;
- case JVM_SIGNATURE_LONG:
- *kind = HPROF_LONG;
- break;
- default:
- HPROF_ASSERT(0);
- break;
- }
- *size = type_size[*kind];
-}
-
-static void
-type_array(const char *sig, HprofType *kind, jint *elem_size)
-{
- *kind = 0;
- *elem_size = 0;
- switch ( sig[0] ) {
- case JVM_SIGNATURE_ARRAY:
- type_from_signature(sig+1, kind, elem_size);
- break;
- }
-}
-
-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);
-}
-
-static void
-system_write(int fd, void *buf, int len, jboolean socket)
-{
- int res;
-
- HPROF_ASSERT(fd>=0);
- if (socket) {
- res = md_send(fd, buf, len, 0);
- if (res < 0 || res!=len) {
- system_error("send", res, errno);
- }
- } else {
- res = md_write(fd, buf, len);
- if (res < 0 || res!=len) {
- system_error("write", res, errno);
- }
- }
-}
-
-static void
-write_flush(void)
-{
- HPROF_ASSERT(gdata->fd >= 0);
- if (gdata->write_buffer_index) {
- system_write(gdata->fd, gdata->write_buffer, gdata->write_buffer_index,
- gdata->socket);
- gdata->write_buffer_index = 0;
- }
-}
-
-static void
-heap_flush(void)
-{
- HPROF_ASSERT(gdata->heap_fd >= 0);
- if (gdata->heap_buffer_index) {
- gdata->heap_write_count += (jlong)gdata->heap_buffer_index;
- system_write(gdata->heap_fd, gdata->heap_buffer, gdata->heap_buffer_index,
- JNI_FALSE);
- gdata->heap_buffer_index = 0;
- }
-}
-
-static void
-write_raw(void *buf, int len)
-{
- HPROF_ASSERT(gdata->fd >= 0);
- if (gdata->write_buffer_index + len > gdata->write_buffer_size) {
- write_flush();
- if (len > gdata->write_buffer_size) {
- system_write(gdata->fd, buf, len, gdata->socket);
- return;
- }
- }
- (void)memcpy(gdata->write_buffer + gdata->write_buffer_index, buf, len);
- gdata->write_buffer_index += len;
-}
-
-static void
-write_u4(unsigned i)
-{
- i = md_htonl(i);
- write_raw(&i, (jint)sizeof(unsigned));
-}
-
-static void
-write_u8(jlong t)
-{
- write_u4((jint)jlong_high(t));
- write_u4((jint)jlong_low(t));
-}
-
-static void
-write_u2(unsigned short i)
-{
- i = md_htons(i);
- write_raw(&i, (jint)sizeof(unsigned short));
-}
-
-static void
-write_u1(unsigned char i)
-{
- write_raw(&i, (jint)sizeof(unsigned char));
-}
-
-static void
-write_id(HprofId i)
-{
- write_u4(i);
-}
-
-static void
-write_current_ticks(void)
-{
- write_u4((jint)(md_get_microsecs() - gdata->micro_sec_ticks));
-}
-
-static void
-write_header(unsigned char type, jint length)
-{
- write_u1(type);
- write_current_ticks();
- write_u4(length);
-}
-
-static void
-write_index_id(HprofId index)
-{
- write_id(index);
-}
-
-static IoNameIndex
-write_name_first(char *name)
-{
- if ( name == NULL ) {
- return 0;
- }
- if (gdata->output_format == 'b') {
- IoNameIndex name_index;
- jboolean new_one;
-
- new_one = JNI_FALSE;
- name_index = ioname_find_or_create(name, &new_one);
- if ( new_one ) {
- int len;
-
- len = (int)strlen(name);
- write_header(HPROF_UTF8, len + (jint)sizeof(HprofId));
- write_index_id(name_index);
- write_raw(name, len);
-
- }
- return name_index;
- }
- return 0;
-}
-
-static void
-write_printf(char *fmt, ...)
-{
- char buf[1024];
- va_list args;
- va_start(args, fmt);
- (void)md_vsnprintf(buf, sizeof(buf), fmt, args);
- buf[sizeof(buf)-1] = 0;
- write_raw(buf, (int)strlen(buf));
- va_end(args);
-}
-
-static void
-write_thread_serial_number(SerialNumber thread_serial_num, int with_comma)
-{
- if ( thread_serial_num != 0 ) {
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- if ( with_comma ) {
- write_printf(" thread %d,", thread_serial_num);
- } else {
- write_printf(" thread %d", thread_serial_num);
- }
- } else {
- if ( with_comma ) {
- write_printf(" <unknown thread>,");
- } else {
- write_printf(" <unknown thread>");
- }
- }
-}
-
-static void
-heap_raw(void *buf, int len)
-{
- HPROF_ASSERT(gdata->heap_fd >= 0);
- if (gdata->heap_buffer_index + len > gdata->heap_buffer_size) {
- heap_flush();
- if (len > gdata->heap_buffer_size) {
- gdata->heap_write_count += (jlong)len;
- system_write(gdata->heap_fd, buf, len, JNI_FALSE);
- return;
- }
- }
- (void)memcpy(gdata->heap_buffer + gdata->heap_buffer_index, buf, len);
- gdata->heap_buffer_index += len;
-}
-
-static void
-heap_u4(unsigned i)
-{
- i = md_htonl(i);
- heap_raw(&i, (jint)sizeof(unsigned));
-}
-
-static void
-heap_u8(jlong i)
-{
- heap_u4((jint)jlong_high(i));
- heap_u4((jint)jlong_low(i));
-}
-
-static void
-heap_u2(unsigned short i)
-{
- i = md_htons(i);
- heap_raw(&i, (jint)sizeof(unsigned short));
-}
-
-static void
-heap_u1(unsigned char i)
-{
- heap_raw(&i, (jint)sizeof(unsigned char));
-}
-
-/* Write out the first byte of a heap tag */
-static void
-heap_tag(unsigned char tag)
-{
- jlong pos;
-
- /* Current position in virtual heap dump file */
- pos = gdata->heap_write_count + (jlong)gdata->heap_buffer_index;
- if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */
- if ( pos >= gdata->maxHeapSegment ) {
- /* Flush all bytes to the heap dump file */
- heap_flush();
-
- /* Send out segment (up to last tag written out) */
- dump_heap_segment_and_reset(gdata->heap_last_tag_position);
-
- /* Get new current position */
- pos = gdata->heap_write_count + (jlong)gdata->heap_buffer_index;
- }
- }
- /* Save position of this tag */
- gdata->heap_last_tag_position = pos;
- /* Write out this tag */
- heap_u1(tag);
-}
-
-static void
-heap_id(HprofId i)
-{
- heap_u4(i);
-}
-
-static void
-heap_index_id(HprofId index)
-{
- heap_id(index);
-}
-
-static void
-heap_name(char *name)
-{
- heap_index_id(get_name_index(name));
-}
-
-static void
-heap_printf(char *fmt, ...)
-{
- char buf[1024];
- va_list args;
- va_start(args, fmt);
- (void)md_vsnprintf(buf, sizeof(buf), fmt, args);
- buf[sizeof(buf)-1] = 0;
- heap_raw(buf, (int)strlen(buf));
- va_end(args);
-}
-
-static void
-heap_element(HprofType kind, jint size, jvalue value)
-{
- if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
- HPROF_ASSERT(size==4);
- heap_id((HprofId)value.i);
- } else {
- switch ( size ) {
- case 8:
- HPROF_ASSERT(size==8);
- HPROF_ASSERT(kind==HPROF_LONG || kind==HPROF_DOUBLE);
- heap_u8(value.j);
- break;
- case 4:
- HPROF_ASSERT(size==4);
- HPROF_ASSERT(kind==HPROF_INT || kind==HPROF_FLOAT);
- heap_u4(value.i);
- break;
- case 2:
- HPROF_ASSERT(size==2);
- HPROF_ASSERT(kind==HPROF_SHORT || kind==HPROF_CHAR);
- heap_u2(value.s);
- break;
- case 1:
- HPROF_ASSERT(size==1);
- HPROF_ASSERT(kind==HPROF_BOOLEAN || kind==HPROF_BYTE);
- HPROF_ASSERT(kind==HPROF_BOOLEAN?(value.b==0 || value.b==1):1);
- heap_u1(value.b);
- break;
- default:
- HPROF_ASSERT(0);
- break;
- }
- }
-}
-
-/* Dump out all elements of an array, objects in jvalues, prims packed */
-static void
-heap_elements(HprofType kind, jint num_elements, jint elem_size, void *elements)
-{
- int i;
- jvalue val;
- static jvalue empty_val;
-
- if ( num_elements == 0 ) {
- return;
- }
-
- switch ( kind ) {
- case 0:
- case HPROF_ARRAY_OBJECT:
- case HPROF_NORMAL_OBJECT:
- for (i = 0; i < num_elements; i++) {
- val = empty_val;
- val.i = ((ObjectIndex*)elements)[i];
- heap_element(kind, elem_size, val);
- }
- break;
- case HPROF_BYTE:
- case HPROF_BOOLEAN:
- HPROF_ASSERT(elem_size==1);
- for (i = 0; i < num_elements; i++) {
- val = empty_val;
- val.b = ((jboolean*)elements)[i];
- heap_element(kind, elem_size, val);
- }
- break;
- case HPROF_CHAR:
- case HPROF_SHORT:
- HPROF_ASSERT(elem_size==2);
- for (i = 0; i < num_elements; i++) {
- val = empty_val;
- val.s = ((jshort*)elements)[i];
- heap_element(kind, elem_size, val);
- }
- break;
- case HPROF_FLOAT:
- case HPROF_INT:
- HPROF_ASSERT(elem_size==4);
- for (i = 0; i < num_elements; i++) {
- val = empty_val;
- val.i = ((jint*)elements)[i];
- heap_element(kind, elem_size, val);
- }
- break;
- case HPROF_DOUBLE:
- case HPROF_LONG:
- HPROF_ASSERT(elem_size==8);
- for (i = 0; i < num_elements; i++) {
- val = empty_val;
- val.j = ((jlong*)elements)[i];
- heap_element(kind, elem_size, val);
- }
- break;
- }
-}
-
-/* ------------------------------------------------------------------ */
-
-void
-io_flush(void)
-{
- HPROF_ASSERT(gdata->header!=NULL);
- write_flush();
-}
-
-void
-io_setup(void)
-{
- gdata->write_buffer_size = FILE_IO_BUFFER_SIZE;
- gdata->write_buffer = HPROF_MALLOC(gdata->write_buffer_size);
- gdata->write_buffer_index = 0;
-
- gdata->heap_write_count = (jlong)0;
- gdata->heap_last_tag_position = (jlong)0;
- gdata->heap_buffer_size = FILE_IO_BUFFER_SIZE;
- gdata->heap_buffer = HPROF_MALLOC(gdata->heap_buffer_size);
- gdata->heap_buffer_index = 0;
-
- if ( gdata->logflags & LOG_CHECK_BINARY ) {
- gdata->check_buffer_size = FILE_IO_BUFFER_SIZE;
- gdata->check_buffer = HPROF_MALLOC(gdata->check_buffer_size);
- gdata->check_buffer_index = 0;
- }
-
- ioname_init();
-}
-
-void
-io_cleanup(void)
-{
- if ( gdata->write_buffer != NULL ) {
- HPROF_FREE(gdata->write_buffer);
- }
- gdata->write_buffer_size = 0;
- gdata->write_buffer = NULL;
- gdata->write_buffer_index = 0;
-
- if ( gdata->heap_buffer != NULL ) {
- HPROF_FREE(gdata->heap_buffer);
- }
- gdata->heap_write_count = (jlong)0;
- gdata->heap_last_tag_position = (jlong)0;
- gdata->heap_buffer_size = 0;
- gdata->heap_buffer = NULL;
- gdata->heap_buffer_index = 0;
-
- if ( gdata->logflags & LOG_CHECK_BINARY ) {
- if ( gdata->check_buffer != NULL ) {
- HPROF_FREE(gdata->check_buffer);
- }
- gdata->check_buffer_size = 0;
- gdata->check_buffer = NULL;
- gdata->check_buffer_index = 0;
- }
-
- ioname_cleanup();
-}
-
-void
-io_write_file_header(void)
-{
- HPROF_ASSERT(gdata->header!=NULL);
- if (gdata->output_format == 'b') {
- jint settings;
- jlong t;
-
- settings = 0;
- if (gdata->heap_dump || gdata->alloc_sites) {
- settings |= 1;
- }
- if (gdata->cpu_sampling) {
- settings |= 2;
- }
- t = md_get_timemillis();
-
- write_raw(gdata->header, (int)strlen(gdata->header) + 1);
- write_u4((jint)sizeof(HprofId));
- write_u8(t);
-
- write_header(HPROF_CONTROL_SETTINGS, 4 + 2);
- write_u4(settings);
- write_u2((unsigned short)gdata->max_trace_depth);
-
- } else if ((!gdata->cpu_timing) || (!gdata->old_timing_format)) {
- /* We don't want the prelude file for the old prof output format */
- time_t t;
- char prelude_file[FILENAME_MAX];
- int prelude_fd;
- int nbytes;
-
- t = time(0);
-
- md_get_prelude_path(prelude_file, sizeof(prelude_file), PRELUDE_FILE);
-
- prelude_fd = md_open(prelude_file);
- if (prelude_fd < 0) {
- char buf[FILENAME_MAX+80];
-
- (void)md_snprintf(buf, sizeof(buf), "Can't open %s", prelude_file);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_TRUE, buf);
- }
-
- write_printf("%s, created %s\n", gdata->header, ctime(&t));
-
- do {
- char buf[1024]; /* File is small, small buffer ok here */
-
- nbytes = md_read(prelude_fd, buf, sizeof(buf));
- if ( nbytes < 0 ) {
- system_error("read", nbytes, errno);
- break;
- }
- if (nbytes == 0) {
- break;
- }
- write_raw(buf, nbytes);
- } while ( nbytes > 0 );
-
- md_close(prelude_fd);
-
- write_printf("\n--------\n\n");
-
- write_flush();
- }
-}
-
-void
-io_write_file_footer(void)
-{
- HPROF_ASSERT(gdata->header!=NULL);
-}
-
-void
-io_write_class_load(SerialNumber class_serial_num, ObjectIndex index,
- SerialNumber trace_serial_num, char *sig)
-{
- CHECK_CLASS_SERIAL_NO(class_serial_num);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- IoNameIndex name_index;
- char *class_name;
-
- class_name = signature_to_name(sig);
- name_index = write_name_first(class_name);
- write_header(HPROF_LOAD_CLASS, (2 * (jint)sizeof(HprofId)) + (4 * 2));
- write_u4(class_serial_num);
- write_index_id(index);
- write_u4(trace_serial_num);
- write_index_id(name_index);
- HPROF_FREE(class_name);
- }
-}
-
-void
-io_write_class_unload(SerialNumber class_serial_num, ObjectIndex index)
-{
- CHECK_CLASS_SERIAL_NO(class_serial_num);
- if (gdata->output_format == 'b') {
- write_header(HPROF_UNLOAD_CLASS, 4);
- write_u4(class_serial_num);
- }
-}
-
-void
-io_write_sites_header(const char * comment_str, jint flags, double cutoff,
- jint total_live_bytes, jint total_live_instances,
- jlong total_alloced_bytes, jlong total_alloced_instances,
- jint count)
-{
- if ( gdata->output_format == 'b') {
- write_header(HPROF_ALLOC_SITES, 2 + (8 * 4) + (count * (4 * 6 + 1)));
- write_u2((unsigned short)flags);
- write_u4(*(int *)(&cutoff));
- write_u4(total_live_bytes);
- write_u4(total_live_instances);
- write_u8(total_alloced_bytes);
- write_u8(total_alloced_instances);
- write_u4(count);
- } else {
- time_t t;
-
- t = time(0);
- write_printf("SITES BEGIN (ordered by %s) %s", comment_str, ctime(&t));
- write_printf(
- " percent live alloc'ed stack class\n");
- write_printf(
- " rank self accum bytes objs bytes objs trace name\n");
- }
-}
-
-void
-io_write_sites_elem(jint index, double ratio, double accum_percent,
- char *sig, SerialNumber class_serial_num,
- SerialNumber trace_serial_num, jint n_live_bytes,
- jint n_live_instances, jint n_alloced_bytes,
- jint n_alloced_instances)
-{
- CHECK_CLASS_SERIAL_NO(class_serial_num);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if ( gdata->output_format == 'b') {
- HprofType kind;
- jint size;
-
- type_array(sig, &kind, &size);
- write_u1(kind);
- write_u4(class_serial_num);
- write_u4(trace_serial_num);
- write_u4(n_live_bytes);
- write_u4(n_live_instances);
- write_u4(n_alloced_bytes);
- write_u4(n_alloced_instances);
- } else {
- char *class_name;
-
- class_name = signature_to_name(sig);
- write_printf("%5u %5.2f%% %5.2f%% %9u %4u %9u %5u %5u %s\n",
- index,
- ratio * 100.0,
- accum_percent * 100.0,
- n_live_bytes,
- n_live_instances,
- n_alloced_bytes,
- n_alloced_instances,
- trace_serial_num,
- class_name);
- HPROF_FREE(class_name);
- }
-}
-
-void
-io_write_sites_footer(void)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- write_printf("SITES END\n");
- }
-}
-
-void
-io_write_thread_start(SerialNumber thread_serial_num,
- ObjectIndex thread_obj_id,
- SerialNumber trace_serial_num, char *thread_name,
- char *thread_group_name, char *thread_parent_name)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- IoNameIndex tname_index;
- IoNameIndex gname_index;
- IoNameIndex pname_index;
-
- tname_index = write_name_first(thread_name);
- gname_index = write_name_first(thread_group_name);
- pname_index = write_name_first(thread_parent_name);
- write_header(HPROF_START_THREAD, ((jint)sizeof(HprofId) * 4) + (4 * 2));
- write_u4(thread_serial_num);
- write_index_id(thread_obj_id);
- write_u4(trace_serial_num);
- write_index_id(tname_index);
- write_index_id(gname_index);
- write_index_id(pname_index);
-
- } else if ( (!gdata->cpu_timing) || (!gdata->old_timing_format)) {
- /* We don't want thread info for the old prof output format */
- write_printf("THREAD START "
- "(obj=%x, id = %d, name=\"%s\", group=\"%s\")\n",
- thread_obj_id, thread_serial_num,
- (thread_name==NULL?"":thread_name),
- (thread_group_name==NULL?"":thread_group_name));
- }
-}
-
-void
-io_write_thread_end(SerialNumber thread_serial_num)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- if (gdata->output_format == 'b') {
- write_header(HPROF_END_THREAD, 4);
- write_u4(thread_serial_num);
-
- } else if ( (!gdata->cpu_timing) || (!gdata->old_timing_format)) {
- /* we don't want thread info for the old prof output format */
- write_printf("THREAD END (id = %d)\n", thread_serial_num);
- }
-}
-
-void
-io_write_frame(FrameIndex index, SerialNumber frame_serial_num,
- char *mname, char *msig, char *sname,
- SerialNumber class_serial_num, jint lineno)
-{
- CHECK_CLASS_SERIAL_NO(class_serial_num);
- if (gdata->output_format == 'b') {
- IoNameIndex mname_index;
- IoNameIndex msig_index;
- IoNameIndex sname_index;
-
- mname_index = write_name_first(mname);
- msig_index = write_name_first(msig);
- sname_index = write_name_first(sname);
-
- write_header(HPROF_FRAME, ((jint)sizeof(HprofId) * 4) + (4 * 2));
- write_index_id(index);
- write_index_id(mname_index);
- write_index_id(msig_index);
- write_index_id(sname_index);
- write_u4(class_serial_num);
- write_u4(lineno);
- }
-}
-
-void
-io_write_trace_header(SerialNumber trace_serial_num,
- SerialNumber thread_serial_num, jint n_frames, char *phase_str)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- write_header(HPROF_TRACE, ((jint)sizeof(HprofId) * n_frames) + (4 * 3));
- write_u4(trace_serial_num);
- write_u4(thread_serial_num);
- write_u4(n_frames);
- } else {
- write_printf("TRACE %u:", trace_serial_num);
- if (thread_serial_num) {
- write_printf(" (thread=%d)", thread_serial_num);
- }
- if ( phase_str != NULL ) {
- write_printf(" (from %s phase of JVM)", phase_str);
- }
- write_printf("\n");
- if (n_frames == 0) {
- write_printf("\t<empty>\n");
- }
- }
-}
-
-void
-io_write_trace_elem(SerialNumber trace_serial_num, FrameIndex frame_index,
- SerialNumber frame_serial_num,
- char *csig, char *mname, char *sname, jint lineno)
-{
- if (gdata->output_format == 'b') {
- write_index_id(frame_index);
- } else {
- char *class_name;
- char linebuf[32];
-
- if (lineno == -2) {
- (void)md_snprintf(linebuf, sizeof(linebuf), "Compiled method");
- } else if (lineno == -3) {
- (void)md_snprintf(linebuf, sizeof(linebuf), "Native method");
- } else if (lineno == -1) {
- (void)md_snprintf(linebuf, sizeof(linebuf), "Unknown line");
- } else {
- (void)md_snprintf(linebuf, sizeof(linebuf), "%d", lineno);
- }
- linebuf[sizeof(linebuf)-1] = 0;
- class_name = signature_to_name(csig);
- if ( mname == NULL ) {
- mname = "<Unknown Method>";
- }
- if ( sname == NULL ) {
- sname = "<Unknown Source>";
- }
- write_printf("\t%s.%s(%s:%s)\n", class_name, mname, sname, linebuf);
- HPROF_FREE(class_name);
- }
-}
-
-void
-io_write_trace_footer(SerialNumber trace_serial_num,
- SerialNumber thread_serial_num, jint n_frames)
-{
-}
-
-#define CPU_SAMPLES_RECORD_NAME ("CPU SAMPLES")
-#define CPU_TIMES_RECORD_NAME ("CPU TIME (ms)")
-
-void
-io_write_cpu_samples_header(jlong total_cost, jint n_items)
-{
-
- if (gdata->output_format == 'b') {
- write_header(HPROF_CPU_SAMPLES, (n_items * (4 * 2)) + (4 * 2));
- write_u4((jint)total_cost);
- write_u4(n_items);
- } else {
- time_t t;
- char *record_name;
-
- if ( gdata->cpu_sampling ) {
- record_name = CPU_SAMPLES_RECORD_NAME;
- } else {
- record_name = CPU_TIMES_RECORD_NAME;
- }
- t = time(0);
- write_printf("%s BEGIN (total = %d) %s", record_name,
- /*jlong*/(int)total_cost, ctime(&t));
- if ( n_items > 0 ) {
- write_printf("rank self accum count trace method\n");
- }
- }
-}
-
-void
-io_write_cpu_samples_elem(jint index, double percent, double accum,
- jint num_hits, jlong cost, SerialNumber trace_serial_num,
- jint n_frames, char *csig, char *mname)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- write_u4((jint)cost);
- write_u4(trace_serial_num);
- } else {
- write_printf("%4u %5.2f%% %5.2f%% %7u %5u",
- index, percent, accum, num_hits,
- trace_serial_num);
- if (n_frames > 0) {
- char * class_name;
-
- class_name = signature_to_name(csig);
- write_printf(" %s.%s\n", class_name, mname);
- HPROF_FREE(class_name);
- } else {
- write_printf(" <empty trace>\n");
- }
- }
-}
-
-void
-io_write_cpu_samples_footer(void)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- char *record_name;
-
- if ( gdata->cpu_sampling ) {
- record_name = CPU_SAMPLES_RECORD_NAME;
- } else {
- record_name = CPU_TIMES_RECORD_NAME;
- }
- write_printf("%s END\n", record_name);
- }
-}
-
-void
-io_write_heap_summary(jlong total_live_bytes, jlong total_live_instances,
- jlong total_alloced_bytes, jlong total_alloced_instances)
-{
- if (gdata->output_format == 'b') {
- write_header(HPROF_HEAP_SUMMARY, 4 * 6);
- write_u4((jint)total_live_bytes);
- write_u4((jint)total_live_instances);
- write_u8(total_alloced_bytes);
- write_u8(total_alloced_instances);
- }
-}
-
-void
-io_write_oldprof_header(void)
-{
- if ( gdata->old_timing_format ) {
- write_printf("count callee caller time\n");
- }
-}
-
-void
-io_write_oldprof_elem(jint num_hits, jint num_frames, char *csig_callee,
- char *mname_callee, char *msig_callee, char *csig_caller,
- char *mname_caller, char *msig_caller, jlong cost)
-{
- if ( gdata->old_timing_format ) {
- char * class_name_callee;
- char * class_name_caller;
-
- class_name_callee = signature_to_name(csig_callee);
- class_name_caller = signature_to_name(csig_caller);
- write_printf("%d ", num_hits);
- if (num_frames >= 1) {
- write_printf("%s.%s%s ", class_name_callee,
- mname_callee, msig_callee);
- } else {
- write_printf("%s ", "<unknown callee>");
- }
- if (num_frames > 1) {
- write_printf("%s.%s%s ", class_name_caller,
- mname_caller, msig_caller);
- } else {
- write_printf("%s ", "<unknown caller>");
- }
- write_printf("%d\n", (int)cost);
- HPROF_FREE(class_name_callee);
- HPROF_FREE(class_name_caller);
- }
-}
-
-void
-io_write_oldprof_footer(void)
-{
-}
-
-void
-io_write_monitor_header(jlong total_time)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- time_t t = time(0);
-
- t = time(0);
- write_printf("MONITOR TIME BEGIN (total = %u ms) %s",
- (int)total_time, ctime(&t));
- if (total_time > 0) {
- write_printf("rank self accum count trace monitor\n");
- }
- }
-}
-
-void
-io_write_monitor_elem(jint index, double percent, double accum,
- jint num_hits, SerialNumber trace_serial_num, char *sig)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- char *class_name;
-
- class_name = signature_to_name(sig);
- write_printf("%4u %5.2f%% %5.2f%% %7u %5u %s (Java)\n",
- index, percent, accum, num_hits,
- trace_serial_num, class_name);
- HPROF_FREE(class_name);
- }
-}
-
-void
-io_write_monitor_footer(void)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- write_printf("MONITOR TIME END\n");
- }
-}
-
-void
-io_write_monitor_sleep(jlong timeout, SerialNumber thread_serial_num)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- if ( thread_serial_num == 0 ) {
- write_printf("SLEEP: timeout=%d, <unknown thread>\n",
- (int)timeout);
- } else {
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- write_printf("SLEEP: timeout=%d, thread %d\n",
- (int)timeout, thread_serial_num);
- }
- }
-}
-
-void
-io_write_monitor_wait(char *sig, jlong timeout,
- SerialNumber thread_serial_num)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- if ( thread_serial_num == 0 ) {
- write_printf("WAIT: MONITOR %s, timeout=%d, <unknown thread>\n",
- sig, (int)timeout);
- } else {
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- write_printf("WAIT: MONITOR %s, timeout=%d, thread %d\n",
- sig, (int)timeout, thread_serial_num);
- }
- }
-}
-
-void
-io_write_monitor_waited(char *sig, jlong time_waited,
- SerialNumber thread_serial_num)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- if ( thread_serial_num == 0 ) {
- write_printf("WAITED: MONITOR %s, time_waited=%d, <unknown thread>\n",
- sig, (int)time_waited);
- } else {
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- write_printf("WAITED: MONITOR %s, time_waited=%d, thread %d\n",
- sig, (int)time_waited, thread_serial_num);
- }
- }
-}
-
-void
-io_write_monitor_exit(char *sig, SerialNumber thread_serial_num)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- if ( thread_serial_num == 0 ) {
- write_printf("EXIT: MONITOR %s, <unknown thread>\n", sig);
- } else {
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- write_printf("EXIT: MONITOR %s, thread %d\n",
- sig, thread_serial_num);
- }
- }
-}
-
-void
-io_write_monitor_dump_header(void)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- write_printf("MONITOR DUMP BEGIN\n");
- }
-}
-
-void
-io_write_monitor_dump_thread_state(SerialNumber thread_serial_num,
- SerialNumber trace_serial_num,
- jint threadState)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- char tstate[20];
-
- tstate[0] = 0;
-
- if (threadState & JVMTI_THREAD_STATE_SUSPENDED) {
- (void)strcat(tstate,"S|");
- }
- if (threadState & JVMTI_THREAD_STATE_INTERRUPTED) {
- (void)strcat(tstate,"intr|");
- }
- if (threadState & JVMTI_THREAD_STATE_IN_NATIVE) {
- (void)strcat(tstate,"native|");
- }
- if ( ! ( threadState & JVMTI_THREAD_STATE_ALIVE ) ) {
- if ( threadState & JVMTI_THREAD_STATE_TERMINATED ) {
- (void)strcat(tstate,"ZO");
- } else {
- (void)strcat(tstate,"NS");
- }
- } else {
- if ( threadState & JVMTI_THREAD_STATE_SLEEPING ) {
- (void)strcat(tstate,"SL");
- } else if ( threadState & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER ) {
- (void)strcat(tstate,"MW");
- } else if ( threadState & JVMTI_THREAD_STATE_WAITING ) {
- (void)strcat(tstate,"CW");
- } else if ( threadState & JVMTI_THREAD_STATE_RUNNABLE ) {
- (void)strcat(tstate,"R");
- } else {
- (void)strcat(tstate,"UN");
- }
- }
- write_printf(" THREAD %d, trace %d, status: %s\n",
- thread_serial_num, trace_serial_num, tstate);
- }
-}
-
-void
-io_write_monitor_dump_state(char *sig, SerialNumber thread_serial_num,
- jint entry_count,
- SerialNumber *waiters, jint waiter_count,
- SerialNumber *notify_waiters, jint notify_waiter_count)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- int i;
-
- if ( thread_serial_num != 0 ) {
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- write_printf(" MONITOR %s\n", sig);
- write_printf("\towner: thread %d, entry count: %d\n",
- thread_serial_num, entry_count);
- } else {
- write_printf(" MONITOR %s unowned\n", sig);
- }
- write_printf("\twaiting to enter:");
- for (i = 0; i < waiter_count; i++) {
- write_thread_serial_number(waiters[i],
- (i != (waiter_count-1)));
- }
- write_printf("\n");
- write_printf("\twaiting to be notified:");
- for (i = 0; i < notify_waiter_count; i++) {
- write_thread_serial_number(notify_waiters[i],
- (i != (notify_waiter_count-1)));
- }
- write_printf("\n");
- }
-}
-
-void
-io_write_monitor_dump_footer(void)
-{
- if (gdata->output_format == 'b') {
- not_implemented();
- } else {
- write_printf("MONITOR DUMP END\n");
- }
-}
-
-/* ----------------------------------------------------------------- */
-/* These functions write to a separate file */
-
-void
-io_heap_header(jlong total_live_instances, jlong total_live_bytes)
-{
- if (gdata->output_format != 'b') {
- time_t t;
-
- t = time(0);
- heap_printf("HEAP DUMP BEGIN (%u objects, %u bytes) %s",
- /*jlong*/(int)total_live_instances,
- /*jlong*/(int)total_live_bytes, ctime(&t));
- }
-}
-
-void
-io_heap_root_thread_object(ObjectIndex thread_obj_id,
- SerialNumber thread_serial_num, SerialNumber trace_serial_num)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_THREAD_OBJ);
- heap_id(thread_obj_id);
- heap_u4(thread_serial_num);
- heap_u4(trace_serial_num);
- } else {
- heap_printf("ROOT %x (kind=<thread>, id=%u, trace=%u)\n",
- thread_obj_id, thread_serial_num, trace_serial_num);
- }
-}
-
-void
-io_heap_root_unknown(ObjectIndex obj_id)
-{
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_UNKNOWN);
- heap_id(obj_id);
- } else {
- heap_printf("ROOT %x (kind=<unknown>)\n", obj_id);
- }
-}
-
-void
-io_heap_root_jni_global(ObjectIndex obj_id, SerialNumber gref_serial_num,
- SerialNumber trace_serial_num)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_JNI_GLOBAL);
- heap_id(obj_id);
- heap_id(gref_serial_num);
- } else {
- heap_printf("ROOT %x (kind=<JNI global ref>, "
- "id=%x, trace=%u)\n",
- obj_id, gref_serial_num, trace_serial_num);
- }
-}
-
-void
-io_heap_root_jni_local(ObjectIndex obj_id, SerialNumber thread_serial_num,
- jint frame_depth)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_JNI_LOCAL);
- heap_id(obj_id);
- heap_u4(thread_serial_num);
- heap_u4(frame_depth);
- } else {
- heap_printf("ROOT %x (kind=<JNI local ref>, "
- "thread=%u, frame=%d)\n",
- obj_id, thread_serial_num, frame_depth);
- }
-}
-
-void
-io_heap_root_system_class(ObjectIndex obj_id, char *sig, SerialNumber class_serial_num)
-{
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_STICKY_CLASS);
- heap_id(obj_id);
- } else {
- char *class_name;
-
- class_name = signature_to_name(sig);
- heap_printf("ROOT %x (kind=<system class>, name=%s)\n",
- obj_id, class_name);
- HPROF_FREE(class_name);
- }
-}
-
-void
-io_heap_root_monitor(ObjectIndex obj_id)
-{
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_MONITOR_USED);
- heap_id(obj_id);
- } else {
- heap_printf("ROOT %x (kind=<busy monitor>)\n", obj_id);
- }
-}
-
-void
-io_heap_root_thread(ObjectIndex obj_id, SerialNumber thread_serial_num)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_THREAD_BLOCK);
- heap_id(obj_id);
- heap_u4(thread_serial_num);
- } else {
- heap_printf("ROOT %x (kind=<thread block>, thread=%u)\n",
- obj_id, thread_serial_num);
- }
-}
-
-void
-io_heap_root_java_frame(ObjectIndex obj_id, SerialNumber thread_serial_num,
- jint frame_depth)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_JAVA_FRAME);
- heap_id(obj_id);
- heap_u4(thread_serial_num);
- heap_u4(frame_depth);
- } else {
- heap_printf("ROOT %x (kind=<Java stack>, "
- "thread=%u, frame=%d)\n",
- obj_id, thread_serial_num, frame_depth);
- }
-}
-
-void
-io_heap_root_native_stack(ObjectIndex obj_id, SerialNumber thread_serial_num)
-{
- CHECK_THREAD_SERIAL_NO(thread_serial_num);
- if (gdata->output_format == 'b') {
- heap_tag(HPROF_GC_ROOT_NATIVE_STACK);
- heap_id(obj_id);
- heap_u4(thread_serial_num);
- } else {
- heap_printf("ROOT %x (kind=<native stack>, thread=%u)\n",
- obj_id, thread_serial_num);
- }
-}
-
-static jboolean
-is_static_field(jint modifiers)
-{
- if ( modifiers & JVM_ACC_STATIC ) {
- return JNI_TRUE;
- }
- return JNI_FALSE;
-}
-
-static jboolean
-is_inst_field(jint modifiers)
-{
- if ( modifiers & JVM_ACC_STATIC ) {
- return JNI_FALSE;
- }
- return JNI_TRUE;
-}
-
-void
-io_heap_class_dump(ClassIndex cnum, char *sig, ObjectIndex class_id,
- SerialNumber trace_serial_num,
- ObjectIndex super_id, ObjectIndex loader_id,
- ObjectIndex signers_id, ObjectIndex domain_id,
- jint size,
- jint n_cpool, ConstantPoolValue *cpool,
- jint n_fields, FieldInfo *fields, jvalue *fvalues)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- int i;
- jint n_static_fields;
- jint n_inst_fields;
- jint inst_size;
- jint saved_inst_size;
-
- n_static_fields = 0;
- n_inst_fields = 0;
- inst_size = 0;
-
- /* These do NOT go into the heap output */
- for ( i = 0 ; i < n_fields ; i++ ) {
- if ( fields[i].cnum == cnum &&
- is_static_field(fields[i].modifiers) ) {
- char *field_name;
-
- field_name = string_get(fields[i].name_index);
- (void)write_name_first(field_name);
- n_static_fields++;
- }
- if ( is_inst_field(fields[i].modifiers) ) {
- inst_size += size_from_field_info(fields[i].primSize);
- if ( fields[i].cnum == cnum ) {
- char *field_name;
-
- field_name = string_get(fields[i].name_index);
- (void)write_name_first(field_name);
- n_inst_fields++;
- }
- }
- }
-
- /* Verify that the instance size we have calculated as we went
- * through the fields, matches what is saved away with this
- * class.
- */
- if ( size >= 0 ) {
- saved_inst_size = class_get_inst_size(cnum);
- if ( saved_inst_size == -1 ) {
- class_set_inst_size(cnum, inst_size);
- } else if ( saved_inst_size != inst_size ) {
- HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in class dump");
- }
- }
-
- heap_tag(HPROF_GC_CLASS_DUMP);
- heap_id(class_id);
- heap_u4(trace_serial_num);
- heap_id(super_id);
- heap_id(loader_id);
- heap_id(signers_id);
- heap_id(domain_id);
- heap_id(0);
- heap_id(0);
- heap_u4(inst_size); /* Must match inst_size in instance dump */
-
- heap_u2((unsigned short)n_cpool);
- for ( i = 0 ; i < n_cpool ; i++ ) {
- HprofType kind;
- jint size;
-
- type_from_signature(string_get(cpool[i].sig_index),
- &kind, &size);
- heap_u2((unsigned short)(cpool[i].constant_pool_index));
- heap_u1(kind);
- HPROF_ASSERT(!HPROF_TYPE_IS_PRIMITIVE(kind));
- heap_element(kind, size, cpool[i].value);
- }
-
- heap_u2((unsigned short)n_static_fields);
- for ( i = 0 ; i < n_fields ; i++ ) {
- if ( fields[i].cnum == cnum &&
- is_static_field(fields[i].modifiers) ) {
- char *field_name;
- HprofType kind;
- jint size;
-
- type_from_signature(string_get(fields[i].sig_index),
- &kind, &size);
- field_name = string_get(fields[i].name_index);
- heap_name(field_name);
- heap_u1(kind);
- heap_element(kind, size, fvalues[i]);
- }
- }
-
- heap_u2((unsigned short)n_inst_fields); /* Does not include super class */
- for ( i = 0 ; i < n_fields ; i++ ) {
- if ( fields[i].cnum == cnum &&
- is_inst_field(fields[i].modifiers) ) {
- HprofType kind;
- jint size;
- char *field_name;
-
- field_name = string_get(fields[i].name_index);
- type_from_signature(string_get(fields[i].sig_index),
- &kind, &size);
- heap_name(field_name);
- heap_u1(kind);
- }
- }
- } else {
- char * class_name;
- int i;
-
- class_name = signature_to_name(sig);
- heap_printf("CLS %x (name=%s, trace=%u)\n",
- class_id, class_name, trace_serial_num);
- HPROF_FREE(class_name);
- if (super_id) {
- heap_printf("\tsuper\t\t%x\n", super_id);
- }
- if (loader_id) {
- heap_printf("\tloader\t\t%x\n", loader_id);
- }
- if (signers_id) {
- heap_printf("\tsigners\t\t%x\n", signers_id);
- }
- if (domain_id) {
- heap_printf("\tdomain\t\t%x\n", domain_id);
- }
- for ( i = 0 ; i < n_fields ; i++ ) {
- if ( fields[i].cnum == cnum &&
- is_static_field(fields[i].modifiers) ) {
- HprofType kind;
- jint size;
-
- type_from_signature(string_get(fields[i].sig_index),
- &kind, &size);
- if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
- if (fvalues[i].i != 0 ) {
- char *field_name;
-
- field_name = string_get(fields[i].name_index);
- heap_printf("\tstatic %s\t%x\n", field_name,
- fvalues[i].i);
- }
- }
- }
- }
- for ( i = 0 ; i < n_cpool ; i++ ) {
- HprofType kind;
- jint size;
-
- type_from_signature(string_get(cpool[i].sig_index), &kind, &size);
- if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
- if (cpool[i].value.i != 0 ) {
- heap_printf("\tconstant pool entry %d\t%x\n",
- cpool[i].constant_pool_index, cpool[i].value.i);
- }
- }
- }
- }
-}
-
-/* Dump the instance fields in the right order. */
-static int
-dump_instance_fields(ClassIndex cnum,
- FieldInfo *fields, jvalue *fvalues, jint n_fields)
-{
- ClassIndex super_cnum;
- int i;
- int nbytes;
-
- HPROF_ASSERT(cnum!=0);
-
- nbytes = 0;
- for (i = 0; i < n_fields; i++) {
- if ( fields[i].cnum == cnum &&
- is_inst_field(fields[i].modifiers) ) {
- HprofType kind;
- int size;
-
- type_from_signature(string_get(fields[i].sig_index),
- &kind, &size);
- heap_element(kind, size, fvalues[i]);
- nbytes += size;
- }
- }
-
- super_cnum = class_get_super(cnum);
- if ( super_cnum != 0 ) {
- nbytes += dump_instance_fields(super_cnum, fields, fvalues, n_fields);
- }
- return nbytes;
-}
-
-void
-io_heap_instance_dump(ClassIndex cnum, ObjectIndex obj_id,
- SerialNumber trace_serial_num,
- ObjectIndex class_id, jint size, char *sig,
- FieldInfo *fields, jvalue *fvalues, jint n_fields)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- jint inst_size;
- jint saved_inst_size;
- int i;
- int nbytes;
-
- inst_size = 0;
- for (i = 0; i < n_fields; i++) {
- if ( is_inst_field(fields[i].modifiers) ) {
- inst_size += size_from_field_info(fields[i].primSize);
- }
- }
-
- /* Verify that the instance size we have calculated as we went
- * through the fields, matches what is saved away with this
- * class.
- */
- saved_inst_size = class_get_inst_size(cnum);
- if ( saved_inst_size == -1 ) {
- class_set_inst_size(cnum, inst_size);
- } else if ( saved_inst_size != inst_size ) {
- HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in instance dump");
- }
-
- heap_tag(HPROF_GC_INSTANCE_DUMP);
- heap_id(obj_id);
- heap_u4(trace_serial_num);
- heap_id(class_id);
- heap_u4(inst_size); /* Must match inst_size in class dump */
-
- /* Order must be class, super, super's super, ... */
- nbytes = dump_instance_fields(cnum, fields, fvalues, n_fields);
- HPROF_ASSERT(nbytes==inst_size);
- } else {
- char * class_name;
- int i;
-
- class_name = signature_to_name(sig);
- heap_printf("OBJ %x (sz=%u, trace=%u, class=%s@%x)\n",
- obj_id, size, trace_serial_num, class_name, class_id);
- HPROF_FREE(class_name);
-
- for (i = 0; i < n_fields; i++) {
- if ( is_inst_field(fields[i].modifiers) ) {
- HprofType kind;
- int size;
-
- type_from_signature(string_get(fields[i].sig_index),
- &kind, &size);
- if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
- if (fvalues[i].i != 0 ) {
- char *sep;
- ObjectIndex val_id;
- char *field_name;
-
- field_name = string_get(fields[i].name_index);
- val_id = (ObjectIndex)(fvalues[i].i);
- sep = (int)strlen(field_name) < 8 ? "\t" : "";
- heap_printf("\t%s\t%s%x\n", field_name, sep, val_id);
- }
- }
- }
- }
- }
-}
-
-void
-io_heap_object_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
- jint size, jint num_elements, char *sig, ObjectIndex *values,
- ObjectIndex class_id)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
-
- heap_tag(HPROF_GC_OBJ_ARRAY_DUMP);
- heap_id(obj_id);
- heap_u4(trace_serial_num);
- heap_u4(num_elements);
- heap_id(class_id);
- heap_elements(HPROF_NORMAL_OBJECT, num_elements,
- (jint)sizeof(HprofId), (void*)values);
- } else {
- char *name;
- int i;
-
- name = signature_to_name(sig);
- heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s@%x)\n",
- obj_id, size, trace_serial_num, num_elements,
- name, class_id);
- for (i = 0; i < num_elements; i++) {
- ObjectIndex id;
-
- id = values[i];
- if (id != 0) {
- heap_printf("\t[%u]\t\t%x\n", i, id);
- }
- }
- HPROF_FREE(name);
- }
-}
-
-void
-io_heap_prim_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
- jint size, jint num_elements, char *sig, void *elements)
-{
- CHECK_TRACE_SERIAL_NO(trace_serial_num);
- if (gdata->output_format == 'b') {
- HprofType kind;
- jint esize;
-
- type_array(sig, &kind, &esize);
- HPROF_ASSERT(HPROF_TYPE_IS_PRIMITIVE(kind));
- heap_tag(HPROF_GC_PRIM_ARRAY_DUMP);
- heap_id(obj_id);
- heap_u4(trace_serial_num);
- heap_u4(num_elements);
- heap_u1(kind);
- heap_elements(kind, num_elements, esize, elements);
- } else {
- char *name;
-
- name = signature_to_name(sig);
- heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s)\n",
- obj_id, size, trace_serial_num, num_elements, name);
- HPROF_FREE(name);
- }
-}
-
-/* Move file bytes into supplied raw interface */
-static void
-write_raw_from_file(int fd, jlong byteCount, void (*raw_interface)(void *,int))
-{
- char *buf;
- int buf_len;
- int left;
- int nbytes;
-
- HPROF_ASSERT(fd >= 0);
-
- /* Move contents of this file into output file. */
- buf_len = FILE_IO_BUFFER_SIZE*2; /* Twice as big! */
- buf = HPROF_MALLOC(buf_len);
- HPROF_ASSERT(buf!=NULL);
-
- /* Keep track of how many we have left */
- left = (int)byteCount;
- do {
- int count;
-
- count = buf_len;
- if ( count > left ) count = left;
- nbytes = md_read(fd, buf, count);
- if (nbytes < 0) {
- system_error("read", nbytes, errno);
- break;
- }
- if (nbytes == 0) {
- break;
- }
- if ( nbytes > 0 ) {
- (*raw_interface)(buf, nbytes);
- left -= nbytes;
- }
- } while ( left > 0 );
-
- if (left > 0 && nbytes == 0) {
- HPROF_ERROR(JNI_TRUE, "File size is smaller than bytes written");
- }
- HPROF_FREE(buf);
-}
-
-/* Write out a heap segment, and copy remainder to top of file. */
-static void
-dump_heap_segment_and_reset(jlong segment_size)
-{
- int fd;
- jlong last_chunk_len;
-
- HPROF_ASSERT(gdata->heap_fd >= 0);
-
- /* Flush all bytes to the heap dump file */
- heap_flush();
-
- /* Last segment? */
- last_chunk_len = gdata->heap_write_count - segment_size;
- HPROF_ASSERT(last_chunk_len>=0);
-
- /* Re-open in proper way, binary vs. ascii is important */
- if (gdata->output_format == 'b') {
- int tag;
-
- if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */
- tag = HPROF_HEAP_DUMP_SEGMENT; /* 1.0.2 */
- } else {
- tag = HPROF_HEAP_DUMP; /* Just one segment */
- HPROF_ASSERT(last_chunk_len==0);
- }
-
- /* Write header for binary heap dump (don't know size until now) */
- write_header(tag, (jint)segment_size);
-
- fd = md_open_binary(gdata->heapfilename);
- } else {
- fd = md_open(gdata->heapfilename);
- }
-
- /* Move file bytes into hprof dump file */
- write_raw_from_file(fd, segment_size, &write_raw);
-
- /* Clear the byte count and reset the heap file. */
- if ( md_seek(gdata->heap_fd, (jlong)0) != (jlong)0 ) {
- HPROF_ERROR(JNI_TRUE, "Cannot seek to beginning of heap info file");
- }
- gdata->heap_write_count = (jlong)0;
- gdata->heap_last_tag_position = (jlong)0;
-
- /* Move trailing bytes from heap dump file to beginning of file */
- if ( last_chunk_len > 0 ) {
- write_raw_from_file(fd, last_chunk_len, &heap_raw);
- }
-
- /* Close the temp file handle */
- md_close(fd);
-}
-
-void
-io_heap_footer(void)
-{
- HPROF_ASSERT(gdata->heap_fd >= 0);
-
- /* Flush all bytes to the heap dump file */
- heap_flush();
-
- /* Send out the last (or maybe only) segment */
- dump_heap_segment_and_reset(gdata->heap_write_count);
-
- /* Write out the last tag */
- if (gdata->output_format != 'b') {
- write_printf("HEAP DUMP END\n");
- } else {
- if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */
- write_header(HPROF_HEAP_DUMP_END, 0);
- }
- }
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_io.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +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_IO_H
-#define HPROF_IO_H
-
-void io_flush(void);
-void io_setup(void);
-void io_cleanup(void);
-
-void io_write_file_header(void);
-void io_write_file_footer(void);
-
-void io_write_class_load(SerialNumber class_serial_num, ObjectIndex index,
- SerialNumber trace_serial_num, char *csig);
-void io_write_class_unload(SerialNumber class_serial_num, ObjectIndex index);
-
-void io_write_sites_header(const char * comment_str, jint flags,
- double cutoff, jint total_live_bytes,
- jint total_live_instances, jlong total_alloced_bytes,
- jlong total_alloced_instances, jint count);
-void io_write_sites_elem(jint index, double ratio, double accum_percent,
- char *csig, SerialNumber class_serial_num,
- SerialNumber trace_serial_num,
- jint n_live_bytes, jint n_live_instances,
- jint n_alloced_bytes, jint n_alloced_instances);
-void io_write_sites_footer(void);
-
-void io_write_thread_start(SerialNumber thread_serial_num, TlsIndex tls_index,
- SerialNumber trace_serial_num, char *thread_name,
- char *thread_group_name, char *thread_parent_name);
-void io_write_thread_end(SerialNumber thread_serial_num);
-
-void io_write_frame(FrameIndex index, SerialNumber serial_num,
- char *mname, char *msig,
- char *sname, SerialNumber class_serial_num,
- jint lineno);
-
-void io_write_trace_header(SerialNumber trace_serial_num,
- SerialNumber thread_serial_num, jint n_frames,
- char * phase_str);
-void io_write_trace_elem(SerialNumber trace_serial_num,
- FrameIndex frame_index, SerialNumber frame_serial_num,
- char *csig, char *mname,
- char *sname, jint lineno);
-void io_write_trace_footer(SerialNumber trace_serial_num,
- SerialNumber thread_serial_num, jint n_frames);
-
-void io_write_cpu_samples_header(jlong total_cost, jint n_items);
-void io_write_cpu_samples_elem(jint index, double percent, double accum,
- jint num_hits, jlong cost,
- SerialNumber trace_serial_num, jint n_frames,
- char *csig, char *mname);
-void io_write_cpu_samples_footer(void);
-
-void io_write_heap_summary(jlong total_live_bytes, jlong total_live_instances,
- jlong total_alloced_bytes,
- jlong total_alloced_instances);
-
-void io_write_oldprof_header(void);
-void io_write_oldprof_elem(jint num_hits, jint num_frames, char *csig_callee,
- char *mname_callee, char *msig_callee,
- char *csig_caller, char *mname_caller,
- char *msig_caller, jlong cost);
-void io_write_oldprof_footer(void);
-
-void io_write_monitor_header(jlong total_time);
-void io_write_monitor_elem(jint index, double percent, double accum,
- jint num_hits, SerialNumber trace_serial_num,
- char *sig);
-void io_write_monitor_footer(void);
-
-void io_write_monitor_sleep(jlong timeout, SerialNumber thread_serial_num);
-void io_write_monitor_wait(char *sig, jlong timeout,
- SerialNumber thread_serial_num);
-void io_write_monitor_waited(char *sig, jlong time_waited,
- SerialNumber thread_serial_num);
-void io_write_monitor_exit(char *sig, SerialNumber thread_serial_num);
-
-void io_write_monitor_dump_header(void);
-void io_write_monitor_dump_thread_state(SerialNumber thread_serial_num,
- SerialNumber trace_serial_num,
- jint threadState);
-void io_write_monitor_dump_state(char *sig,
- SerialNumber thread_serial_num, jint entry_count,
- SerialNumber *waiters, jint waiter_count,
- SerialNumber *notify_waiters, jint notify_waiter_count);
-void io_write_monitor_dump_footer(void);
-
-void io_heap_header(jlong total_live_instances, jlong total_live_bytes);
-
-void io_heap_root_thread_object(ObjectIndex thread_id,
- SerialNumber thread_serial_num,
- SerialNumber trace_serial_num);
-void io_heap_root_unknown(ObjectIndex obj_id);
-void io_heap_root_jni_global(ObjectIndex obj_id, SerialNumber gref_serial_num,
- SerialNumber trace_serial_num);
-void io_heap_root_jni_local(ObjectIndex obj_id,
- SerialNumber thread_serial_num, jint frame_depth);
-void io_heap_root_system_class(ObjectIndex obj_id, char *sig, SerialNumber class_serial_num);
-void io_heap_root_monitor(ObjectIndex obj_id);
-void io_heap_root_thread(ObjectIndex obj_id,
- SerialNumber thread_serial_num);
-void io_heap_root_java_frame(ObjectIndex obj_id,
- SerialNumber thread_serial_num, jint frame_depth);
-void io_heap_root_native_stack(ObjectIndex obj_id,
- SerialNumber thread_serial_num);
-
-void io_heap_class_dump(ClassIndex cnum, char *sig, ObjectIndex class_id,
- SerialNumber trace_serial_num,
- ObjectIndex super_id, ObjectIndex loader_id,
- ObjectIndex signers_id, ObjectIndex domain_id,
- jint inst_size,
- jint n_cpool, ConstantPoolValue *cpool,
- jint n_fields, FieldInfo *fields, jvalue *fvalues);
-
-void io_heap_instance_dump(ClassIndex cnum, ObjectIndex obj_id,
- SerialNumber trace_serial_num,
- ObjectIndex class_id, jint size,
- char *sig, FieldInfo *fields,
- jvalue *fvalues, jint n_fields);
-
-void io_heap_object_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
- jint size, jint num_elements, char *sig,
- ObjectIndex *values, ObjectIndex class_id);
-void io_heap_prim_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
- jint size, jint num_elements, char *sig,
- void *elements);
-
-void io_heap_footer(void);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_ioname.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +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.
- */
-
-
-/* Used to store strings written out to the binary format (see hprof_io.c) */
-
-
-/* Probably could have used the basic string table, however, some strings
- * would only be in this table, so it was isolated as a separate table
- * of strings.
- */
-
-#include "hprof.h"
-#include "hprof_ioname.h"
-
-void
-ioname_init(void)
-{
- HPROF_ASSERT(gdata->ioname_table==NULL);
- gdata->ioname_table = table_initialize("IoNames", 512, 512, 511, 0);
-}
-
-IoNameIndex
-ioname_find_or_create(const char *name, jboolean *pnew_entry)
-{
- return table_find_or_create_entry(gdata->ioname_table,
- (void*)name, (int)strlen(name)+1, pnew_entry, NULL);
-}
-
-void
-ioname_cleanup(void)
-{
- table_cleanup(gdata->ioname_table, NULL, NULL);
- gdata->ioname_table = NULL;
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_ioname.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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_IONAME_H
-#define HPROF_IONAME_H
-
-void ioname_init(void);
-IoNameIndex ioname_find_or_create(const char *name, jboolean *pnew_entry);
-void ioname_cleanup(void);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_listener.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,436 +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.
- */
-
-
-/* The hprof listener loop thread. net=hostname:port option */
-
-/*
- * The option net=hostname:port causes all hprof output to be sent down
- * a socket connection, and also allows for commands to come in over the
- * socket. The commands are documented below.
- *
- * This thread can cause havoc when started prematurely or not terminated
- * properly, see listener_init() and listener_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.
- *
- * The specification of this command protocol is only here, in the comments
- * below. The HAT tools uses this interface.
- * It is also unknown how well these options work given the limited
- * testing of this interface.
- *
- */
-
-#include "hprof.h"
-
-/* When the hprof Agent in the VM is connected via a socket to the
- * profiling client, the client may send the hprof Agent a set of commands.
- * The commands have the following format:
- *
- * u1 a TAG denoting the type of the record
- * u4 a serial number
- * 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 commands are presently supported:
- *
- * TAG BODY notes
- * ----------------------------------------------------------
- * HPROF_CMD_GC force a GC.
- *
- * HPROF_CMD_DUMP_HEAP obtain a heap dump
- *
- * HPROF_CMD_ALLOC_SITES obtain allocation sites
- *
- * u2 flags 0x0001: incremental vs. complete
- * 0x0002: sorted by allocation vs. live
- * 0x0004: whether to force a GC
- * u4 cutoff ratio (0.0 ~ 1.0)
- *
- * HPROF_CMD_HEAP_SUMMARY obtain heap summary
- *
- * HPROF_CMD_DUMP_TRACES obtain all newly created traces
- *
- * HPROF_CMD_CPU_SAMPLES obtain a HPROF_CPU_SAMPLES record
- *
- * u2 ignored for now
- * u4 cutoff ratio (0.0 ~ 1.0)
- *
- * HPROF_CMD_CONTROL changing settings
- *
- * u2 0x0001: alloc traces on
- * 0x0002: alloc traces off
- *
- * 0x0003: CPU sampling on
- *
- * id: thread object id (NULL for all)
- *
- * 0x0004: CPU sampling off
- *
- * id: thread object id (NULL for all)
- *
- * 0x0005: CPU sampling clear
- *
- * 0x0006: clear alloc sites info
- *
- * 0x0007: set max stack depth in CPU samples
- * and alloc traces
- *
- * u2: new depth
- */
-
-typedef enum HprofCmd {
- HPROF_CMD_GC = 0x01,
- HPROF_CMD_DUMP_HEAP = 0x02,
- HPROF_CMD_ALLOC_SITES = 0x03,
- HPROF_CMD_HEAP_SUMMARY = 0x04,
- HPROF_CMD_EXIT = 0x05,
- HPROF_CMD_DUMP_TRACES = 0x06,
- HPROF_CMD_CPU_SAMPLES = 0x07,
- HPROF_CMD_CONTROL = 0x08,
- HPROF_CMD_EOF = 0xFF
-} HprofCmd;
-
-static jint
-recv_fully(int f, char *buf, int len)
-{
- jint nbytes;
-
- nbytes = 0;
- if ( f < 0 ) {
- return nbytes;
- }
- while (nbytes < len) {
- int res;
-
- res = md_recv(f, buf + nbytes, (len - nbytes), 0);
- if (res < 0) {
- /*
- * hprof was disabled before we returned from recv() above.
- * This means the command socket is closed so we let that
- * trickle back up the command processing stack.
- */
- LOG("recv() returned < 0");
- break;
- }
- nbytes += res;
- }
- return nbytes;
-}
-
-static unsigned char
-recv_u1(void)
-{
- unsigned char c;
- jint nbytes;
-
- nbytes = recv_fully(gdata->fd, (char *)&c, (int)sizeof(unsigned char));
- if (nbytes == 0) {
- c = HPROF_CMD_EOF;
- }
- return c;
-}
-
-static unsigned short
-recv_u2(void)
-{
- unsigned short s;
- jint nbytes;
-
- nbytes = recv_fully(gdata->fd, (char *)&s, (int)sizeof(unsigned short));
- if (nbytes == 0) {
- s = (unsigned short)-1;
- }
- return md_ntohs(s);
-}
-
-static unsigned
-recv_u4(void)
-{
- unsigned i;
- jint nbytes;
-
- nbytes = recv_fully(gdata->fd, (char *)&i, (int)sizeof(unsigned));
- if (nbytes == 0) {
- i = (unsigned)-1;
- }
- return md_ntohl(i);
-}
-
-static ObjectIndex
-recv_id(void)
-{
- ObjectIndex result;
- jint nbytes;
-
- nbytes = recv_fully(gdata->fd, (char *)&result, (int)sizeof(ObjectIndex));
- if (nbytes == 0) {
- result = (ObjectIndex)0;
- }
- return result;
-}
-
-static void JNICALL
-listener_loop_function(jvmtiEnv *jvmti, JNIEnv *env, void *p)
-{
- jboolean keep_processing;
- unsigned char tag;
- jboolean kill_the_whole_process;
-
- kill_the_whole_process = JNI_FALSE;
- tag = 0;
-
- rawMonitorEnter(gdata->listener_loop_lock); {
- gdata->listener_loop_running = JNI_TRUE;
- keep_processing = gdata->listener_loop_running;
- /* Tell listener_init() that we have started */
- rawMonitorNotifyAll(gdata->listener_loop_lock);
- } rawMonitorExit(gdata->listener_loop_lock);
-
- while ( keep_processing ) {
-
- LOG("listener loop iteration");
-
- tag = recv_u1(); /* This blocks here on the socket read, a close()
- * on this fd will wake this up. And if recv_u1()
- * can't read anything, it returns HPROF_CMD_EOF.
- */
-
- LOG3("listener_loop", "command = ", tag);
-
- if (tag == HPROF_CMD_EOF) {
- /* The cmd socket has closed so the listener thread is done
- * just fall out of loop and let the thread die.
- */
- keep_processing = JNI_FALSE;
- break;
- }
-
- /* seq_num not used */
- (void)recv_u4();
- /* length not used */
- (void)recv_u4();
-
- switch (tag) {
- case HPROF_CMD_GC:
- runGC();
- break;
- case HPROF_CMD_DUMP_HEAP: {
- site_heapdump(env);
- break;
- }
- case HPROF_CMD_ALLOC_SITES: {
- unsigned short flags;
- unsigned i_tmp;
- float ratio;
-
- flags = recv_u2();
- i_tmp = recv_u4();
- ratio = *(float *)(&i_tmp);
- site_write(env, flags, ratio);
- break;
- }
- case HPROF_CMD_HEAP_SUMMARY: {
- rawMonitorEnter(gdata->data_access_lock); {
- io_write_heap_summary( gdata->total_live_bytes,
- gdata->total_live_instances,
- gdata->total_alloced_bytes,
- gdata->total_alloced_instances);
- } rawMonitorExit(gdata->data_access_lock);
- break;
- }
- case HPROF_CMD_EXIT:
- keep_processing = JNI_FALSE;
- kill_the_whole_process = JNI_TRUE;
- verbose_message("HPROF: received exit event, exiting ...\n");
- break;
- case HPROF_CMD_DUMP_TRACES:
- rawMonitorEnter(gdata->data_access_lock); {
- trace_output_unmarked(env);
- } rawMonitorExit(gdata->data_access_lock);
- break;
- case HPROF_CMD_CPU_SAMPLES: {
- unsigned i_tmp;
- float ratio;
-
- /* flags not used */
- (void)recv_u2();
- i_tmp = recv_u4();
- ratio = *(float *)(&i_tmp);
- trace_output_cost(env, ratio);
- break;
- }
- case HPROF_CMD_CONTROL: {
- unsigned short cmd = recv_u2();
- if (cmd == 0x0001) {
- setEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL);
- tracker_engage(env);
- } else if (cmd == 0x0002) {
- setEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_OBJECT_FREE, NULL);
- tracker_disengage(env);
- } else if (cmd == 0x0003) {
- ObjectIndex thread_object_index;
- thread_object_index = recv_id();
- cpu_sample_on(env, thread_object_index);
- } else if (cmd == 0x0004) {
- ObjectIndex thread_object_index;
- thread_object_index = recv_id();
- cpu_sample_off(env, thread_object_index);
- } else if (cmd == 0x0005) {
- rawMonitorEnter(gdata->data_access_lock); {
- trace_clear_cost();
- } rawMonitorExit(gdata->data_access_lock);
- } else if (cmd == 0x0006) {
- rawMonitorEnter(gdata->data_access_lock); {
- site_cleanup();
- site_init();
- } rawMonitorExit(gdata->data_access_lock);
- } else if (cmd == 0x0007) {
- gdata->max_trace_depth = recv_u2();
- }
- break;
- }
- default:{
- char buf[80];
-
- keep_processing = JNI_FALSE;
- kill_the_whole_process = JNI_TRUE;
- (void)md_snprintf(buf, sizeof(buf),
- "failed to recognize cmd %d, exiting..", (int)tag);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_FALSE, buf);
- break;
- }
- }
-
- rawMonitorEnter(gdata->data_access_lock); {
- io_flush();
- } rawMonitorExit(gdata->data_access_lock);
-
- rawMonitorEnter(gdata->listener_loop_lock); {
- if ( !gdata->listener_loop_running ) {
- keep_processing = JNI_FALSE;
- }
- } rawMonitorExit(gdata->listener_loop_lock);
-
- }
-
- /* If listener_term() is causing this loop to terminate, then
- * you will block here until listener_term wants you to proceed.
- */
- rawMonitorEnter(gdata->listener_loop_lock); {
- if ( gdata->listener_loop_running ) {
- /* We are terminating for our own reasons, maybe because of
- * EOF (socket closed?), or EXIT request, or invalid command.
- * Not from listener_term().
- * We set gdata->listener_loop_running=FALSE so that any
- * future call to listener_term() will do nothing.
- */
- gdata->listener_loop_running = JNI_FALSE;
- } else {
- /* We assume that listener_term() is stopping us,
- * now we need to tell it we understood.
- */
- rawMonitorNotifyAll(gdata->listener_loop_lock);
- }
- } rawMonitorExit(gdata->listener_loop_lock);
-
- LOG3("listener_loop", "finished command = ", tag);
-
- /* If we got an explicit command request to die, die here */
- if ( kill_the_whole_process ) {
- error_exit_process(0);
- }
-
-}
-
-/* External functions */
-
-void
-listener_init(JNIEnv *env)
-{
- /* Create the raw monitor */
- gdata->listener_loop_lock = createRawMonitor("HPROF listener lock");
-
- rawMonitorEnter(gdata->listener_loop_lock); {
- createAgentThread(env, "HPROF listener thread",
- &listener_loop_function);
- /* Wait for listener_loop_function() to tell us it started. */
- rawMonitorWait(gdata->listener_loop_lock, 0);
- } rawMonitorExit(gdata->listener_loop_lock);
-}
-
-void
-listener_term(JNIEnv *env)
-{
- rawMonitorEnter(gdata->listener_loop_lock); {
-
- /* If we are in the middle of sending bytes down the socket, this
- * at least keeps us blocked until that processing is done.
- */
- rawMonitorEnter(gdata->data_access_lock); {
-
- /* Make sure the socket gets everything */
- io_flush();
-
- /*
- * Graceful shutdown of the socket will assure that all data
- * sent is received before the socket close completes.
- */
- (void)md_shutdown(gdata->fd, 2 /* disallow sends and receives */);
-
- /* This close will cause the listener loop to possibly wake up
- * from the recv_u1(), this is critical to get thread running again.
- */
- md_close(gdata->fd);
- } rawMonitorExit(gdata->data_access_lock);
-
- /* It could have shut itself down, so we check the global flag */
- if ( gdata->listener_loop_running ) {
- /* It stopped because of something listener_term() did. */
- gdata->listener_loop_running = JNI_FALSE;
- /* Wait for listener_loop_function() to tell us it finished. */
- rawMonitorWait(gdata->listener_loop_lock, 0);
- }
- } rawMonitorExit(gdata->listener_loop_lock);
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_listener.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +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_LISTENER_H
-#define HPROF_LISTENER_H
-
-void listener_init(JNIEnv *env);
-void listener_term(JNIEnv *env);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_loader.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +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.
- */
-
-
-/* The Class Loader table. */
-
-/*
- * The Class Loader objects show up so early in the VM process that a
- * separate table was designated for Class Loaders.
- *
- * The Class Loader is unique by way of it's jobject uniqueness, unfortunately
- * use of JNI too early for jobject comparisons is problematic.
- * It is assumed that the number of class loaders will be limited, and
- * a simple linear search will be performed for now.
- * That logic is isolated here and can be changed to use the standard
- * table hash table search once we know JNI can be called safely.
- *
- * A weak global reference is created to keep tabs on loaders, and as
- * each search for a loader happens, NULL weak global references will
- * trigger the freedom of those entries.
- *
- */
-
-#include "hprof.h"
-
-typedef struct {
- jobject globalref; /* Weak Global reference for object */
- ObjectIndex object_index;
-} LoaderInfo;
-
-static LoaderInfo *
-get_info(LoaderIndex index)
-{
- return (LoaderInfo*)table_get_info(gdata->loader_table, index);
-}
-
-static void
-delete_globalref(JNIEnv *env, LoaderInfo *info)
-{
- jobject ref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(info!=NULL);
- ref = info->globalref;
- info->globalref = NULL;
- if ( ref != NULL ) {
- deleteWeakGlobalReference(env, ref);
- }
- info->object_index = 0;
-}
-
-static void
-cleanup_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
-}
-
-static void
-delete_ref_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
- delete_globalref((JNIEnv*)arg, (LoaderInfo*)info_ptr);
-}
-
-static void
-list_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
- LoaderInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
-
- info = (LoaderInfo*)info_ptr;
- debug_message( "Loader 0x%08x: globalref=%p, object_index=%d\n",
- index, (void*)info->globalref, info->object_index);
-}
-
-static void
-free_entry(JNIEnv *env, LoaderIndex index)
-{
- LoaderInfo *info;
-
- info = get_info(index);
- delete_globalref(env, info);
- table_free_entry(gdata->loader_table, index);
-}
-
-typedef struct SearchData {
- JNIEnv *env;
- jobject loader;
- LoaderIndex found;
-} SearchData;
-
-static void
-search_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- LoaderInfo *info;
- SearchData *data;
-
- HPROF_ASSERT(info_ptr!=NULL);
- HPROF_ASSERT(arg!=NULL);
- info = (LoaderInfo*)info_ptr;
- data = (SearchData*)arg;
- if ( data->loader == info->globalref ) {
- /* Covers when looking for NULL too. */
- HPROF_ASSERT(data->found==0); /* Did we find more than one? */
- data->found = index;
- } else if ( data->env != NULL && data->loader != NULL &&
- info->globalref != NULL ) {
- jobject lref;
-
- lref = newLocalReference(data->env, info->globalref);
- if ( lref == NULL ) {
- /* Object went away, free reference and entry */
- free_entry(data->env, index);
- } else if ( isSameObject(data->env, data->loader, lref) ) {
- HPROF_ASSERT(data->found==0); /* Did we find more than one? */
- data->found = index;
- }
- if ( lref != NULL ) {
- deleteLocalReference(data->env, lref);
- }
- }
-
-}
-
-static LoaderIndex
-search(JNIEnv *env, jobject loader)
-{
- SearchData data;
-
- data.env = env;
- data.loader = loader;
- data.found = 0;
- table_walk_items(gdata->loader_table, &search_item, (void*)&data);
- return data.found;
-}
-
-LoaderIndex
-loader_find_or_create(JNIEnv *env, jobject loader)
-{
- LoaderIndex index;
-
- /* See if we remembered the system loader */
- if ( loader==NULL && gdata->system_loader != 0 ) {
- return gdata->system_loader;
- }
- if ( loader==NULL ) {
- env = NULL;
- }
- index = search(env, loader);
- if ( index == 0 ) {
- static LoaderInfo empty_info;
- LoaderInfo info;
-
- info = empty_info;
- if ( loader != NULL ) {
- HPROF_ASSERT(env!=NULL);
- info.globalref = newWeakGlobalReference(env, loader);
- info.object_index = 0;
- }
- index = table_create_entry(gdata->loader_table, NULL, 0, (void*)&info);
- }
- HPROF_ASSERT(search(env,loader)==index);
- /* Remember the system loader */
- if ( loader==NULL && gdata->system_loader == 0 ) {
- gdata->system_loader = index;
- }
- return index;
-}
-
-void
-loader_init(void)
-{
- gdata->loader_table = table_initialize("Loader",
- 16, 16, 0, (int)sizeof(LoaderInfo));
-}
-
-void
-loader_list(void)
-{
- debug_message(
- "--------------------- Loader Table ------------------------\n");
- table_walk_items(gdata->loader_table, &list_item, NULL);
- debug_message(
- "----------------------------------------------------------\n");
-}
-
-void
-loader_cleanup(void)
-{
- table_cleanup(gdata->loader_table, &cleanup_item, NULL);
- gdata->loader_table = NULL;
-}
-
-void
-loader_delete_global_references(JNIEnv *env)
-{
- table_walk_items(gdata->loader_table, &delete_ref_item, (void*)env);
-}
-
-/* Get the object index for a class loader */
-ObjectIndex
-loader_object_index(JNIEnv *env, LoaderIndex index)
-{
- LoaderInfo *info;
- ObjectIndex object_index;
- jobject wref;
-
- /* Assume no object index at first (default class loader) */
- info = get_info(index);
- object_index = info->object_index;
- wref = info->globalref;
- if ( wref != NULL && object_index == 0 ) {
- jobject lref;
-
- object_index = 0;
- lref = newLocalReference(env, wref);
- if ( lref != NULL && !isSameObject(env, lref, NULL) ) {
- jlong tag;
-
- /* Get the tag on the object and extract the object_index */
- tag = getTag(lref);
- if ( tag != (jlong)0 ) {
- object_index = tag_extract(tag);
- }
- }
- if ( lref != NULL ) {
- deleteLocalReference(env, lref);
- }
- info->object_index = object_index;
- }
- return object_index;
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_loader.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +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_LOADER_H
-#define HPROF_LOADER_H
-
-LoaderIndex loader_find_or_create(JNIEnv *env, jobject loader);
-void loader_init(void);
-void loader_list(void);
-void loader_delete_global_references(JNIEnv *env);
-void loader_cleanup(void);
-ObjectIndex loader_object_index(JNIEnv *env, LoaderIndex index);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_md.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, 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.
- */
-
-
-#ifndef HPROF_MD_H
-#define HPROF_MD_H
-
-void md_init(void);
-int md_getpid(void);
-void md_sleep(unsigned seconds);
-int md_connect(char *hostname, unsigned short port);
-int md_recv(int f, char *buf, int len, int option);
-int md_shutdown(int filedes, int option);
-int md_open(const char *filename);
-int md_open_binary(const char *filename);
-int md_creat(const char *filename);
-int md_creat_binary(const char *filename);
-jlong md_seek(int filedes, jlong cur);
-void md_close(int filedes);
-int md_send(int s, const char *msg, int len, int flags);
-int md_write(int filedes, const void *buf, int nbyte);
-int md_read(int filedes, void *buf, int nbyte);
-jlong md_get_microsecs(void);
-jlong md_get_timemillis(void);
-jlong md_get_thread_cpu_timemillis(void);
-void md_get_prelude_path(char *path, int path_len, char *filename);
-int md_snprintf(char *s, int n, const char *format, ...);
-int md_vsnprintf(char *s, int n, const char *format, va_list ap);
-void md_system_error(char *buf, int len);
-
-unsigned md_htons(unsigned short s);
-unsigned md_htonl(unsigned l);
-unsigned md_ntohs(unsigned short s);
-unsigned md_ntohl(unsigned l);
-
-void md_build_library_name(char *holder, int holderlen, const char *pname, const char *fname);
-void * md_load_library(const char *name, char *err_buf, int err_buflen);
-void md_unload_library(void *handle);
-void * md_find_library_entry(void *handle, const char *name);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_monitor.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,442 +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.
- */
-
-
-/* Monitor contention tracking and monitor wait handling. */
-
-/*
- * Monitor's under contention are unique per trace and signature.
- * Two monitors with the same trace and signature will be treated
- * the same as far as accumulated contention time.
- *
- * The tls table (or thread table) will be used to store the monitor in
- * contention or being waited on.
- *
- * Monitor wait activity is emitted as it happens.
- *
- * Monitor contention is tabulated and summarized at dump time.
- *
- */
-
-#include "hprof.h"
-
-typedef struct MonitorKey {
- TraceIndex trace_index;
- StringIndex sig_index;
-} MonitorKey;
-
-typedef struct MonitorInfo {
- jint num_hits;
- jlong contended_time;
-} MonitorInfo;
-
-typedef struct IterateInfo {
- MonitorIndex *monitors;
- int count;
- jlong total_contended_time;
-} IterateInfo;
-
-/* Private internal functions. */
-
-static MonitorKey*
-get_pkey(MonitorIndex index)
-{
- void * key_ptr;
- int key_len;
-
- table_get_key(gdata->monitor_table, index, &key_ptr, &key_len);
- HPROF_ASSERT(key_len==sizeof(MonitorKey));
- HPROF_ASSERT(key_ptr!=NULL);
- return (MonitorKey*)key_ptr;
-}
-
-static MonitorInfo *
-get_info(MonitorIndex index)
-{
- MonitorInfo * info;
-
- HPROF_ASSERT(index!=0);
- info = (MonitorInfo*)table_get_info(gdata->monitor_table, index);
- HPROF_ASSERT(info!=NULL);
- return info;
-}
-
-static MonitorIndex
-find_or_create_entry(JNIEnv *env, TraceIndex trace_index, jobject object)
-{
- static MonitorKey empty_key;
- MonitorKey key;
- MonitorIndex index;
- char *sig;
-
- HPROF_ASSERT(object!=NULL);
- WITH_LOCAL_REFS(env, 1) {
- jclass clazz;
-
- clazz = getObjectClass(env, object);
- getClassSignature(clazz, &sig, NULL);
- } END_WITH_LOCAL_REFS;
-
- key = empty_key;
- key.trace_index = trace_index;
- key.sig_index = string_find_or_create(sig);
- jvmtiDeallocate(sig);
- index = table_find_or_create_entry(gdata->monitor_table, &key,
- (int)sizeof(key), NULL, NULL);
- return index;
-}
-
-static void
-cleanup_item(MonitorIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
-}
-
-static void
-list_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- MonitorInfo *info;
- MonitorKey *pkey;
-
- HPROF_ASSERT(key_len==sizeof(MonitorKey));
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(info_ptr!=NULL);
- pkey = (MonitorKey*)key_ptr;
- info = (MonitorInfo *)info_ptr;
- debug_message(
- "Monitor 0x%08x: trace=0x%08x, sig=0x%08x, "
- "num_hits=%d, contended_time=(%d,%d)\n",
- index,
- pkey->trace_index,
- pkey->sig_index,
- info->num_hits,
- jlong_high(info->contended_time),
- jlong_low(info->contended_time));
-}
-
-static void
-collect_iterator(MonitorIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- MonitorInfo *info;
- IterateInfo *iterate;
-
- HPROF_ASSERT(key_len==sizeof(MonitorKey));
- HPROF_ASSERT(info_ptr!=NULL);
- HPROF_ASSERT(arg!=NULL);
- iterate = (IterateInfo *)arg;
- info = (MonitorInfo *)info_ptr;
- iterate->monitors[iterate->count++] = index;
- iterate->total_contended_time += info->contended_time;
-}
-
-static int
-qsort_compare(const void *p_monitor1, const void *p_monitor2)
-{
- MonitorInfo * info1;
- MonitorInfo * info2;
- MonitorIndex monitor1;
- MonitorIndex monitor2;
- jlong result;
-
- HPROF_ASSERT(p_monitor1!=NULL);
- HPROF_ASSERT(p_monitor2!=NULL);
- monitor1 = *(MonitorIndex *)p_monitor1;
- monitor2 = *(MonitorIndex *)p_monitor2;
- info1 = get_info(monitor1);
- info2 = get_info(monitor2);
-
- result = info2->contended_time - info1->contended_time;
- if (result < (jlong)0) {
- return -1;
- } else if ( result > (jlong)0 ) {
- return 1;
- }
- return info2->num_hits - info1->num_hits;
-}
-
-static void
-clear_item(MonitorIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- MonitorInfo *info;
-
- HPROF_ASSERT(key_len==sizeof(MonitorKey));
- HPROF_ASSERT(info_ptr!=NULL);
- info = (MonitorInfo *)info_ptr;
- info->contended_time = 0;
-}
-
-static TraceIndex
-get_trace(TlsIndex tls_index, JNIEnv *env)
-{
- TraceIndex trace_index;
-
- trace_index = tls_get_trace(tls_index, env, gdata->max_trace_depth, JNI_FALSE);
- return trace_index;
-}
-
-/* External functions (called from hprof_init.c) */
-
-void
-monitor_init(void)
-{
- gdata->monitor_table = table_initialize("Monitor",
- 32, 32, 31, (int)sizeof(MonitorInfo));
-}
-
-void
-monitor_list(void)
-{
- debug_message(
- "------------------- Monitor Table ------------------------\n");
- table_walk_items(gdata->monitor_table, &list_item, NULL);
- debug_message(
- "----------------------------------------------------------\n");
-}
-
-void
-monitor_cleanup(void)
-{
- table_cleanup(gdata->monitor_table, &cleanup_item, (void*)NULL);
- gdata->monitor_table = NULL;
-}
-
-void
-monitor_clear(void)
-{
- table_walk_items(gdata->monitor_table, &clear_item, NULL);
-}
-
-/* Contended monitor output */
-void
-monitor_write_contended_time(JNIEnv *env, double cutoff)
-{
- int n_entries;
-
- n_entries = table_element_count(gdata->monitor_table);
- if ( n_entries == 0 ) {
- return;
- }
-
- rawMonitorEnter(gdata->data_access_lock); {
- IterateInfo iterate;
- int i;
- int n_items;
- jlong total_contended_time;
-
- /* First write all trace we might refer to. */
- trace_output_unmarked(env);
-
- /* Looking for an array of monitor index values of interest */
- iterate.monitors = HPROF_MALLOC(n_entries*(int)sizeof(MonitorIndex));
- (void)memset(iterate.monitors, 0, n_entries*(int)sizeof(MonitorIndex));
-
- /* Get a combined total and an array of monitor index numbers */
- iterate.total_contended_time = 0;
- iterate.count = 0;
- table_walk_items(gdata->monitor_table, &collect_iterator, &iterate);
-
- /* Sort that list */
- n_entries = iterate.count;
- if ( n_entries > 0 ) {
- qsort(iterate.monitors, n_entries, sizeof(MonitorIndex),
- &qsort_compare);
- }
-
- /* Apply the cutoff */
- n_items = 0;
- for (i = 0; i < n_entries; i++) {
- MonitorIndex index;
- MonitorInfo *info;
- double percent;
-
- index = iterate.monitors[i];
- info = get_info(index);
- percent = (double)info->contended_time /
- (double)iterate.total_contended_time;
- if (percent < cutoff) {
- break;
- }
- iterate.monitors[n_items++] = index;
- }
-
- /* Output the items that make sense */
- total_contended_time = iterate.total_contended_time / 1000000;
-
- if ( n_items > 0 && total_contended_time > 0 ) {
- double accum;
-
- /* Output the info on this monitor enter site */
- io_write_monitor_header(total_contended_time);
-
- accum = 0.0;
- for (i = 0; i < n_items; i++) {
- MonitorIndex index;
- MonitorInfo *info;
- MonitorKey *pkey;
- double percent;
- char *sig;
-
- index = iterate.monitors[i];
- pkey = get_pkey(index);
- info = get_info(index);
-
- sig = string_get(pkey->sig_index);
-
- percent = (double)info->contended_time /
- (double)iterate.total_contended_time * 100.0;
- accum += percent;
- io_write_monitor_elem(i + 1, percent, accum,
- info->num_hits,
- trace_get_serial_number(pkey->trace_index),
- sig);
- }
- io_write_monitor_footer();
- }
- HPROF_FREE(iterate.monitors);
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-void
-monitor_contended_enter_event(JNIEnv *env, jthread thread, jobject object)
-{
- TlsIndex tls_index;
- MonitorIndex index;
- TraceIndex trace_index;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(object!=NULL);
-
- tls_index = tls_find_or_create(env, thread);
- HPROF_ASSERT(tls_get_monitor(tls_index)==0);
- trace_index = get_trace(tls_index, env);
- index = find_or_create_entry(env, trace_index, object);
- tls_monitor_start_timer(tls_index);
- tls_set_monitor(tls_index, index);
-}
-
-void
-monitor_contended_entered_event(JNIEnv* env, jthread thread, jobject object)
-{
- TlsIndex tls_index;
- MonitorInfo *info;
- MonitorIndex index;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- HPROF_ASSERT(thread!=NULL);
-
- tls_index = tls_find_or_create(env, thread);
- HPROF_ASSERT(tls_index!=0);
- index = tls_get_monitor(tls_index);
- HPROF_ASSERT(index!=0);
- info = get_info(index);
- info->contended_time += tls_monitor_stop_timer(tls_index);
- info->num_hits++;
- tls_set_monitor(tls_index, 0);
-}
-
-void
-monitor_wait_event(JNIEnv *env, jthread thread, jobject object, jlong timeout)
-{
- TlsIndex tls_index;
- MonitorKey *pkey;
- MonitorIndex index;
- TraceIndex trace_index;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- HPROF_ASSERT(thread!=NULL);
-
- tls_index = tls_find_or_create(env, thread);
- HPROF_ASSERT(tls_index!=0);
- HPROF_ASSERT(tls_get_monitor(tls_index)==0);
- trace_index = get_trace(tls_index, env);
- index = find_or_create_entry(env, trace_index, object);
- pkey = get_pkey(index);
- tls_monitor_start_timer(tls_index);
- tls_set_monitor(tls_index, index);
-
- rawMonitorEnter(gdata->data_access_lock); {
- io_write_monitor_wait(string_get(pkey->sig_index), timeout,
- tls_get_thread_serial_number(tls_index));
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-void
-monitor_waited_event(JNIEnv *env, jthread thread,
- jobject object, jboolean timed_out)
-{
- TlsIndex tls_index;
- MonitorIndex index;
- jlong time_waited;
-
- tls_index = tls_find_or_create(env, thread);
- HPROF_ASSERT(tls_index!=0);
- time_waited = tls_monitor_stop_timer(tls_index);
- index = tls_get_monitor(tls_index);
-
- if ( index ==0 ) {
- /* As best as I can tell, on Solaris X86 (not SPARC) I sometimes
- * get a "waited" event on a thread that I have never seen before
- * at all, so how did I get a WAITED event? Perhaps when I
- * did the VM_INIT handling, a thread I've never seen had already
- * done the WAIT (which I never saw?), and now I see this thread
- * for the first time, and also as it finishes it's WAIT?
- * Only happening on faster processors?
- */
- tls_set_monitor(tls_index, 0);
- return;
- }
- HPROF_ASSERT(index!=0);
- tls_set_monitor(tls_index, 0);
- if (object == NULL) {
- rawMonitorEnter(gdata->data_access_lock); {
- io_write_monitor_sleep(time_waited,
- tls_get_thread_serial_number(tls_index));
- } rawMonitorExit(gdata->data_access_lock);
- } else {
- MonitorKey *pkey;
-
- pkey = get_pkey(index);
- rawMonitorEnter(gdata->data_access_lock); {
- io_write_monitor_waited(string_get(pkey->sig_index), time_waited,
- tls_get_thread_serial_number(tls_index));
- } rawMonitorExit(gdata->data_access_lock);
- }
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_monitor.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_MONITOR_H
-#define HPROF_MONITOR_H
-
-void monitor_init(void);
-void monitor_list(void);
-void monitor_cleanup(void);
-
-void monitor_clear(void);
-void monitor_write_contended_time(JNIEnv *env, double cutoff);
-
-void monitor_contended_enter_event(JNIEnv *env_id, jthread thread,
- jobject object);
-void monitor_contended_entered_event(JNIEnv* env_id, jthread thread,
- jobject object);
-void monitor_wait_event(JNIEnv *env_id, jthread thread,
- jobject object, jlong timeout);
-void monitor_waited_event(JNIEnv *env_id, jthread thread,
- jobject object, jboolean timed_out);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_object.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +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.
- */
-
-
-/* Object table. */
-
-/*
- * An Object is unique by it's allocation site (SiteIndex), it's size,
- * it's kind, and it's serial number. Normally only the serial number
- * would have been necessary for heap=dump, and these other items
- * could have been moved to the ObjectInfo. An optimization left
- * to the reader. Lookups are not normally done on ObjectIndex's
- * anyway because we typically know when to create them.
- * Objects that have been tagged, are tagged with an ObjectIndex,
- * Objects that are not tagged need a ObjectIndex, a lookup when
- * heap=sites, and a new one when heap=dump.
- * Objects that are freed, need the tag converted to an ObjectIndex,
- * so they can be freed, but only when heap=dump.
- * The thread serial number is for the thread associated with this
- * object. If the object is a Thread object, it should be the serial
- * number for that thread. The ThreadStart event is responsible
- * for making sure the thread serial number is correct, but between the
- * initial allocation of a Thread object and it's ThreadStart event
- * the thread serial number could be for the thread that allocated
- * the Thread object.
- *
- * This will likely be the largest table when using heap=dump, when
- * there is one table entry per object.
- *
- * ObjectIndex entries differ between heap=dump and heap=sites.
- * With heap=sites, each ObjectIndex represents a unique site, size,
- * and kind of object, so many jobject's will map to a single ObjectIndex.
- * With heap=dump, every ObjectIndex maps to a unique jobject.
- *
- * During processing of a heap dump, the references for the object
- * this ObjectIndex represents is assigned to the references field
- * of the ObjectInfo as a linked list. (see hprof_references.c).
- * Once all the refernces are attached, they are processed into the
- * appropriate hprof dump information.
- *
- * The references field is set and cleared as many times as the heap
- * is dumped, as is the reference table.
- *
- */
-
-#include "hprof.h"
-
-typedef struct ObjectKey {
- SiteIndex site_index; /* Site of allocation */
- jint size; /* Size of object as reported by VM */
- ObjectKind kind; /* Kind of object, most are OBJECT_NORMAL */
- SerialNumber serial_num; /* For heap=dump, a unique number. */
-} ObjectKey;
-
-typedef struct ObjectInfo {
- RefIndex references; /* Linked list of refs in this object */
- SerialNumber thread_serial_num; /* Thread serial number for allocation */
-} ObjectInfo;
-
-/* Private internal functions. */
-
-static ObjectKey*
-get_pkey(ObjectIndex index)
-{
- void *key_ptr;
- int key_len;
-
- table_get_key(gdata->object_table, index, (void*)&key_ptr, &key_len);
- HPROF_ASSERT(key_len==(int)sizeof(ObjectKey));
- HPROF_ASSERT(key_ptr!=NULL);
- return (ObjectKey*)key_ptr;
-}
-
-static ObjectInfo *
-get_info(ObjectIndex index)
-{
- ObjectInfo *info;
-
- info = (ObjectInfo*)table_get_info(gdata->object_table, index);
- return info;
-}
-
-static void
-list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- ObjectKey *pkey;
- ObjectInfo *info;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len!=0);
- HPROF_ASSERT(info_ptr!=NULL);
-
- info = (ObjectInfo*)info_ptr;
-
- pkey = (ObjectKey*)key_ptr;
- debug_message( "Object 0x%08x: site=0x%08x, SN=%u, "
- " size=%d, kind=%d, refs=0x%x, threadSN=%u\n",
- i, pkey->site_index, pkey->serial_num, pkey->size, pkey->kind,
- info->references, info->thread_serial_num);
-}
-
-static void
-clear_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- ObjectInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
- info = (ObjectInfo *)info_ptr;
- info->references = 0;
-}
-
-static void
-dump_class_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- ObjectInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
- info = (ObjectInfo *)info_ptr;
- reference_dump_class((JNIEnv*)arg, i, info->references);
-}
-
-static void
-dump_instance_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- ObjectInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
- info = (ObjectInfo *)info_ptr;
- reference_dump_instance((JNIEnv*)arg, i, info->references);
-}
-
-/* External interfaces. */
-
-ObjectIndex
-object_new(SiteIndex site_index, jint size, ObjectKind kind, SerialNumber thread_serial_num)
-{
- ObjectIndex index;
- ObjectKey key;
- static ObjectKey empty_key;
-
- key = empty_key;
- key.site_index = site_index;
- key.size = size;
- key.kind = kind;
- if ( gdata->heap_dump ) {
- static ObjectInfo empty_info;
- ObjectInfo i;
-
- i = empty_info;
- i.thread_serial_num = thread_serial_num;
- key.serial_num = gdata->object_serial_number_counter++;
- index = table_create_entry(gdata->object_table,
- &key, (int)sizeof(ObjectKey), &i);
- } else {
- key.serial_num =
- class_get_serial_number(site_get_class_index(site_index));
- index = table_find_or_create_entry(gdata->object_table,
- &key, (int)sizeof(ObjectKey), NULL, NULL);
- }
- site_update_stats(site_index, size, 1);
- return index;
-}
-
-void
-object_init(void)
-{
- jint bucket_count;
-
- bucket_count = 511;
- if ( gdata->heap_dump ) {
- bucket_count = 0;
- }
- HPROF_ASSERT(gdata->object_table==NULL);
- gdata->object_table = table_initialize("Object", 4096,
- 4096, bucket_count, (int)sizeof(ObjectInfo));
-}
-
-SiteIndex
-object_get_site(ObjectIndex index)
-{
- ObjectKey *pkey;
-
- pkey = get_pkey(index);
- return pkey->site_index;
-}
-
-jint
-object_get_size(ObjectIndex index)
-{
- ObjectKey *pkey;
-
- pkey = get_pkey(index);
- return pkey->size;
-}
-
-ObjectKind
-object_get_kind(ObjectIndex index)
-{
- ObjectKey *pkey;
-
- pkey = get_pkey(index);
- return pkey->kind;
-}
-
-ObjectKind
-object_free(ObjectIndex index)
-{
- ObjectKey *pkey;
- ObjectKind kind;
-
- pkey = get_pkey(index);
- kind = pkey->kind;
-
- /* Decrement allocations at this site. */
- site_update_stats(pkey->site_index, -(pkey->size), -1);
-
- if ( gdata->heap_dump ) {
- table_free_entry(gdata->object_table, index);
- }
- return kind;
-}
-
-void
-object_list(void)
-{
- debug_message(
- "--------------------- Object Table ------------------------\n");
- table_walk_items(gdata->object_table, &list_item, NULL);
- debug_message(
- "----------------------------------------------------------\n");
-}
-
-void
-object_cleanup(void)
-{
- table_cleanup(gdata->object_table, NULL, NULL);
- gdata->object_table = NULL;
-}
-
-void
-object_set_thread_serial_number(ObjectIndex index,
- SerialNumber thread_serial_num)
-{
- ObjectInfo *info;
-
- info = get_info(index);
- info->thread_serial_num = thread_serial_num;
-}
-
-SerialNumber
-object_get_thread_serial_number(ObjectIndex index)
-{
- ObjectInfo *info;
-
- info = get_info(index);
- return info->thread_serial_num;
-}
-
-RefIndex
-object_get_references(ObjectIndex index)
-{
- ObjectInfo *info;
-
- info = get_info(index);
- return info->references;
-}
-
-void
-object_set_references(ObjectIndex index, RefIndex ref_index)
-{
- ObjectInfo *info;
-
- info = get_info(index);
- info->references = ref_index;
-}
-
-void
-object_clear_references(void)
-{
- table_walk_items(gdata->object_table, &clear_references, NULL);
-}
-
-void
-object_reference_dump(JNIEnv *env)
-{
- table_walk_items(gdata->object_table, &dump_instance_references, (void*)env);
- table_walk_items(gdata->object_table, &dump_class_references, (void*)env);
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_object.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) 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_OBJECT_H
-#define HPROF_OBJECT_H
-
-void object_init(void);
-ObjectIndex object_new(SiteIndex site_index, jint size, ObjectKind kind,
- SerialNumber thread_serial_num);
-SiteIndex object_get_site(ObjectIndex index);
-jint object_get_size(ObjectIndex index);
-ObjectKind object_get_kind(ObjectIndex index);
-ObjectKind object_free(ObjectIndex index);
-void object_list(void);
-void object_cleanup(void);
-
-void object_set_thread_serial_number(ObjectIndex index,
- SerialNumber thread_serial_num);
-SerialNumber object_get_thread_serial_number(ObjectIndex index);
-RefIndex object_get_references(ObjectIndex index);
-void object_set_references(ObjectIndex index, RefIndex ref_index);
-void object_clear_references(void);
-void object_reference_dump(JNIEnv *env);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_reference.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,814 +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.
- */
-
-
-/* Object references table (used in hprof_object.c). */
-
-/*
- * This table is used by the object table to store object reference
- * and primitive data information obtained from iterations over the
- * heap (see hprof_site.c).
- *
- * Most of these table entries have no Key, but the key is used to store
- * the primitive array and primitive field jvalue. None of these entries
- * are ever looked up, there will be no hash table, use of the
- * LookupTable was just an easy way to handle a unbounded table of
- * entries. The object table (see hprof_object.c) will completely
- * free this reference table after each heap dump or after processing the
- * references and primitive data.
- *
- * The hprof format required this accumulation of all heap iteration
- * references and primitive data from objects in order to compose an
- * hprof records for it.
- *
- * This file contains detailed understandings of how an hprof CLASS
- * and INSTANCE dump is constructed, most of this is derived from the
- * original hprof code, but some has been derived by reading the HAT
- * code that accepts this format.
- *
- */
-
-#include "hprof.h"
-
-/* The flavor of data being saved in the RefInfo */
-enum {
- INFO_OBJECT_REF_DATA = 1,
- INFO_PRIM_FIELD_DATA = 2,
- INFO_PRIM_ARRAY_DATA = 3
-};
-
-/* Reference information, object reference or primitive data information */
-typedef struct RefInfo {
- ObjectIndex object_index; /* If an object reference, the referree index */
- jint index; /* If array or field, array or field index */
- jint length; /* If array the element count, if not -1 */
- RefIndex next; /* The next table element */
- unsigned flavor : 8; /* INFO_*, flavor of RefInfo */
- unsigned refKind : 8; /* The kind of reference */
- unsigned primType : 8; /* If primitive data involved, it's type */
-} RefInfo;
-
-/* Private internal functions. */
-
-/* Get the RefInfo structure from an entry */
-static RefInfo *
-get_info(RefIndex index)
-{
- RefInfo *info;
-
- info = (RefInfo*)table_get_info(gdata->reference_table, index);
- return info;
-}
-
-/* Get a jvalue that was stored as the key. */
-static jvalue
-get_key_value(RefIndex index)
-{
- void *key;
- int len;
- jvalue value;
- static jvalue empty_value;
-
- key = NULL;
- table_get_key(gdata->reference_table, index, &key, &len);
- HPROF_ASSERT(key!=NULL);
- HPROF_ASSERT(len==(int)sizeof(jvalue));
- if ( key != NULL ) {
- (void)memcpy(&value, key, (int)sizeof(jvalue));
- } else {
- value = empty_value;
- }
- return value;
-}
-
-/* Get size of a primitive type */
-static jint
-get_prim_size(jvmtiPrimitiveType primType)
-{
- jint size;
-
- switch ( primType ) {
- case JVMTI_PRIMITIVE_TYPE_BOOLEAN:
- size = (jint)sizeof(jboolean);
- break;
- case JVMTI_PRIMITIVE_TYPE_BYTE:
- size = (jint)sizeof(jbyte);
- break;
- case JVMTI_PRIMITIVE_TYPE_CHAR:
- size = (jint)sizeof(jchar);
- break;
- case JVMTI_PRIMITIVE_TYPE_SHORT:
- size = (jint)sizeof(jshort);
- break;
- case JVMTI_PRIMITIVE_TYPE_INT:
- size = (jint)sizeof(jint);
- break;
- case JVMTI_PRIMITIVE_TYPE_FLOAT:
- size = (jint)sizeof(jfloat);
- break;
- case JVMTI_PRIMITIVE_TYPE_LONG:
- size = (jint)sizeof(jlong);
- break;
- case JVMTI_PRIMITIVE_TYPE_DOUBLE:
- size = (jint)sizeof(jdouble);
- break;
- default:
- HPROF_ASSERT(0);
- size = 1;
- break;
- }
- return size;
-}
-
-/* Get a void* elements array that was stored as the key. */
-static void *
-get_key_elements(RefIndex index, jvmtiPrimitiveType primType,
- jint *nelements, jint *nbytes)
-{
- void *key;
- jint byteLen;
-
- HPROF_ASSERT(nelements!=NULL);
- HPROF_ASSERT(nbytes!=NULL);
-
- table_get_key(gdata->reference_table, index, &key, &byteLen);
- HPROF_ASSERT(byteLen>=0);
- HPROF_ASSERT(byteLen!=0?key!=NULL:key==NULL);
- *nbytes = byteLen;
- *nelements = byteLen / get_prim_size(primType);
- return key;
-}
-
-/* Dump a RefInfo* structure */
-static void
-dump_ref_info(RefInfo *info)
-{
- debug_message("[%d]: flavor=%d"
- ", refKind=%d"
- ", primType=%d"
- ", object_index=0x%x"
- ", length=%d"
- ", next=0x%x"
- "\n",
- info->index,
- info->flavor,
- info->refKind,
- info->primType,
- info->object_index,
- info->length,
- info->next);
-}
-
-/* Dump a RefIndex list */
-static void
-dump_ref_list(RefIndex list)
-{
- RefInfo *info;
- RefIndex index;
-
- debug_message("\nFOLLOW REFERENCES RETURNED:\n");
- index = list;
- while ( index != 0 ) {
- info = get_info(index);
- dump_ref_info(info);
- index = info->next;
- }
-}
-
-/* Dump information about a field and what ref data we had on it */
-static void
-dump_field(FieldInfo *fields, jvalue *fvalues, int n_fields,
- jint index, jvalue value, jvmtiPrimitiveType primType)
-{
- ClassIndex cnum;
- StringIndex name;
- StringIndex sig;
-
- cnum = fields[index].cnum;
- name = fields[index].name_index;
- sig = fields[index].sig_index;
- debug_message("[%d] %s \"%s\" \"%s\"",
- index,
- cnum!=0?string_get(class_get_signature(cnum)):"?",
- name!=0?string_get(name):"?",
- sig!=0?string_get(sig):"?");
- if ( fields[index].primType!=0 || fields[index].primType!=primType ) {
- debug_message(" (primType=%d(%c)",
- fields[index].primType,
- primTypeToSigChar(fields[index].primType));
- if ( primType != fields[index].primType ) {
- debug_message(", got %d(%c)",
- primType,
- primTypeToSigChar(primType));
- }
- debug_message(")");
- } else {
- debug_message("(ty=OBJ)");
- }
- if ( value.j != (jlong)0 || fvalues[index].j != (jlong)0 ) {
- debug_message(" val=[0x%08x,0x%08x] or [0x%08x,0x%08x]",
- jlong_high(value.j), jlong_low(value.j),
- jlong_high(fvalues[index].j), jlong_low(fvalues[index].j));
- }
- debug_message("\n");
-}
-
-/* Dump all the fields of interest */
-static void
-dump_fields(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields)
-{
- int i;
-
- debug_message("\nHPROF LIST OF ALL FIELDS:\n");
- for ( i = 0 ; i < n_fields ; i++ ) {
- if ( fields[i].name_index != 0 ) {
- dump_field(fields, fvalues, n_fields, i, fvalues[i], fields[i].primType);
- }
- }
- dump_ref_list(list);
-}
-
-/* Verify field data */
-static void
-verify_field(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields,
- jint index, jvalue value, jvmtiPrimitiveType primType)
-{
- HPROF_ASSERT(fvalues != NULL);
- HPROF_ASSERT(n_fields > 0);
- HPROF_ASSERT(index < n_fields);
- HPROF_ASSERT(index >= 0 );
- if ( primType!=fields[index].primType ) {
- dump_fields(list, fields, fvalues, n_fields);
- debug_message("\nPROBLEM WITH:\n");
- dump_field(fields, fvalues, n_fields, index, value, primType);
- debug_message("\n");
- HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");
- }
- if ( primType == JVMTI_PRIMITIVE_TYPE_BOOLEAN &&
- ( value.b != 1 && value.b != 0 ) ) {
- dump_fields(list, fields, fvalues, n_fields);
- debug_message("\nPROBLEM WITH:\n");
- dump_field(fields, fvalues, n_fields, index, value, primType);
- debug_message("\n");
- HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");
- }
-}
-
-/* Fill in a field value, making sure the index is safe */
-static void
-fill_in_field_value(RefIndex list, FieldInfo *fields, jvalue *fvalues,
- int n_fields, jint index, jvalue value,
- jvmtiPrimitiveType primType)
-{
- HPROF_ASSERT(fvalues != NULL);
- HPROF_ASSERT(n_fields > 0);
- HPROF_ASSERT(index < n_fields);
- HPROF_ASSERT(index >= 0 );
- HPROF_ASSERT(fvalues[index].j==(jlong)0);
- verify_field(list, fields, fvalues, n_fields, index, value, primType);
- if (index >= 0 && index < n_fields) {
- fvalues[index] = value;
- }
-}
-
-/* Walk all references for an ObjectIndex and construct the hprof CLASS dump. */
-static void
-dump_class_and_supers(JNIEnv *env, ObjectIndex object_index, RefIndex list)
-{
- SiteIndex site_index;
- SerialNumber trace_serial_num;
- RefIndex index;
- ClassIndex super_cnum;
- ObjectIndex super_index;
- LoaderIndex loader_index;
- ObjectIndex signers_index;
- ObjectIndex domain_index;
- FieldInfo *fields;
- jvalue *fvalues;
- jint n_fields;
- jboolean skip_fields;
- jint n_fields_set;
- jlong size;
- ClassIndex cnum;
- char *sig;
- ObjectKind kind;
- TraceIndex trace_index;
- Stack *cpool_values;
- ConstantPoolValue *cpool;
- jint cpool_count;
-
- HPROF_ASSERT(object_index!=0);
- kind = object_get_kind(object_index);
- if ( kind != OBJECT_CLASS ) {
- return;
- }
- site_index = object_get_site(object_index);
- HPROF_ASSERT(site_index!=0);
- cnum = site_get_class_index(site_index);
- HPROF_ASSERT(cnum!=0);
- if ( class_get_status(cnum) & CLASS_DUMPED ) {
- return;
- }
- class_add_status(cnum, CLASS_DUMPED);
- size = (jlong)object_get_size(object_index);
-
- super_index = 0;
- super_cnum = class_get_super(cnum);
- if ( super_cnum != 0 ) {
- super_index = class_get_object_index(super_cnum);
- if ( super_index != 0 ) {
- dump_class_and_supers(env, super_index,
- object_get_references(super_index));
- }
- }
-
- trace_index = site_get_trace_index(site_index);
- HPROF_ASSERT(trace_index!=0);
- trace_serial_num = trace_get_serial_number(trace_index);
- sig = string_get(class_get_signature(cnum));
- loader_index = class_get_loader(cnum);
- signers_index = 0;
- domain_index = 0;
-
- /* Get field information */
- n_fields = 0;
- skip_fields = JNI_FALSE;
- n_fields_set = 0;
- fields = NULL;
- fvalues = NULL;
- if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) {
- /* Problems getting all the fields, can't trust field index values */
- skip_fields = JNI_TRUE;
- /* Class with no references at all? (ok to be unprepared if list==0?) */
- if ( list != 0 ) {
- /* It is assumed that the reason why we didn't get the fields
- * was because the class is not prepared.
- */
- if ( gdata->debugflags & DEBUGFLAG_UNPREPARED_CLASSES ) {
- dump_ref_list(list);
- debug_message("Unprepared class with references: %s\n",
- sig);
- }
- HPROF_ERROR(JNI_FALSE, "Trouble with unprepared classes");
- }
- /* Why would an unprepared class contain references? */
- }
- if ( n_fields > 0 ) {
- fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));
- (void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));
- }
-
- /* We use a Stack just because it will automatically expand as needed */
- cpool_values = stack_init(16, 16, sizeof(ConstantPoolValue));
- cpool = NULL;
- cpool_count = 0;
-
- index = list;
- while ( index != 0 ) {
- RefInfo *info;
- jvalue ovalue;
- static jvalue empty_value;
-
- info = get_info(index);
-
- switch ( info->flavor ) {
- case INFO_OBJECT_REF_DATA:
- switch ( info->refKind ) {
- case JVMTI_HEAP_REFERENCE_FIELD:
- case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
- /* Should never be seen on a class dump */
- HPROF_ASSERT(0);
- break;
- case JVMTI_HEAP_REFERENCE_STATIC_FIELD:
- if ( skip_fields == JNI_TRUE ) {
- break;
- }
- ovalue = empty_value;
- ovalue.i = info->object_index;
- fill_in_field_value(list, fields, fvalues, n_fields,
- info->index, ovalue, 0);
- n_fields_set++;
- HPROF_ASSERT(n_fields_set <= n_fields);
- break;
- case JVMTI_HEAP_REFERENCE_CONSTANT_POOL: {
- ConstantPoolValue cpv;
- ObjectIndex cp_object_index;
- SiteIndex cp_site_index;
- ClassIndex cp_cnum;
-
- cp_object_index = info->object_index;
- HPROF_ASSERT(cp_object_index!=0);
- cp_site_index = object_get_site(cp_object_index);
- HPROF_ASSERT(cp_site_index!=0);
- cp_cnum = site_get_class_index(cp_site_index);
- cpv.constant_pool_index = info->index;
- cpv.sig_index = class_get_signature(cp_cnum);
- cpv.value.i = cp_object_index;
- stack_push(cpool_values, (void*)&cpv);
- cpool_count++;
- break;
- }
- case JVMTI_HEAP_REFERENCE_SIGNERS:
- signers_index = info->object_index;
- break;
- case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:
- domain_index = info->object_index;
- break;
- case JVMTI_HEAP_REFERENCE_CLASS_LOADER:
- case JVMTI_HEAP_REFERENCE_INTERFACE:
- default:
- /* Ignore, not needed */
- break;
- }
- break;
- case INFO_PRIM_FIELD_DATA:
- if ( skip_fields == JNI_TRUE ) {
- break;
- }
- HPROF_ASSERT(info->primType!=0);
- HPROF_ASSERT(info->length==-1);
- HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_STATIC_FIELD);
- ovalue = get_key_value(index);
- fill_in_field_value(list, fields, fvalues, n_fields,
- info->index, ovalue, info->primType);
- n_fields_set++;
- HPROF_ASSERT(n_fields_set <= n_fields);
- break;
- case INFO_PRIM_ARRAY_DATA:
- default:
- /* Should never see these */
- HPROF_ASSERT(0);
- break;
- }
-
- index = info->next;
- }
-
- /* Get constant pool data if we have any */
- HPROF_ASSERT(cpool_count==stack_depth(cpool_values));
- if ( cpool_count > 0 ) {
- cpool = (ConstantPoolValue*)stack_element(cpool_values, 0);
- }
- io_heap_class_dump(cnum, sig, object_index, trace_serial_num,
- super_index,
- loader_object_index(env, loader_index),
- signers_index, domain_index,
- (jint)size, cpool_count, cpool, n_fields, fields, fvalues);
-
- stack_term(cpool_values);
- if ( fvalues != NULL ) {
- HPROF_FREE(fvalues);
- }
-}
-
-/* Walk all references for an ObjectIndex and construct the hprof INST dump. */
-static void
-dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list)
-{
- jvmtiPrimitiveType primType;
- SiteIndex site_index;
- SerialNumber trace_serial_num;
- RefIndex index;
- ObjectIndex class_index;
- jlong size;
- ClassIndex cnum;
- char *sig;
- void *elements;
- jint num_elements;
- jint num_bytes;
- ObjectIndex *values;
- FieldInfo *fields;
- jvalue *fvalues;
- jint n_fields;
- jboolean skip_fields;
- jint n_fields_set;
- ObjectKind kind;
- TraceIndex trace_index;
- jboolean is_array;
- jboolean is_prim_array;
-
- HPROF_ASSERT(object_index!=0);
- kind = object_get_kind(object_index);
- if ( kind == OBJECT_CLASS ) {
- return;
- }
- site_index = object_get_site(object_index);
- HPROF_ASSERT(site_index!=0);
- cnum = site_get_class_index(site_index);
- HPROF_ASSERT(cnum!=0);
- size = (jlong)object_get_size(object_index);
- trace_index = site_get_trace_index(site_index);
- HPROF_ASSERT(trace_index!=0);
- trace_serial_num = trace_get_serial_number(trace_index);
- sig = string_get(class_get_signature(cnum));
- class_index = class_get_object_index(cnum);
-
- values = NULL;
- elements = NULL;
- num_elements = 0;
- num_bytes = 0;
-
- n_fields = 0;
- skip_fields = JNI_FALSE;
- n_fields_set = 0;
- fields = NULL;
- fvalues = NULL;
-
- index = list;
-
- is_array = JNI_FALSE;
- is_prim_array = JNI_FALSE;
-
- if ( sig[0] != JVM_SIGNATURE_ARRAY ) {
- if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) {
- /* Trouble getting all the fields, can't trust field index values */
- skip_fields = JNI_TRUE;
- /* It is assumed that the reason why we didn't get the fields
- * was because the class is not prepared.
- */
- if ( gdata->debugflags & DEBUGFLAG_UNPREPARED_CLASSES ) {
- if ( list != 0 ) {
- dump_ref_list(list);
- debug_message("Instance of unprepared class with refs: %s\n",
- sig);
- } else {
- debug_message("Instance of unprepared class without refs: %s\n",
- sig);
- }
- HPROF_ERROR(JNI_FALSE, "Big Trouble with unprepared class instances");
- }
- }
- if ( n_fields > 0 ) {
- fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));
- (void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));
- }
- } else {
- is_array = JNI_TRUE;
- if ( sig[0] != 0 && sigToPrimSize(sig+1) != 0 ) {
- is_prim_array = JNI_TRUE;
- }
- }
-
- while ( index != 0 ) {
- RefInfo *info;
- jvalue ovalue;
- static jvalue empty_value;
-
- info = get_info(index);
-
- /* Process reference objects, many not used right now. */
- switch ( info->flavor ) {
- case INFO_OBJECT_REF_DATA:
- switch ( info->refKind ) {
- case JVMTI_HEAP_REFERENCE_SIGNERS:
- case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:
- case JVMTI_HEAP_REFERENCE_CLASS_LOADER:
- case JVMTI_HEAP_REFERENCE_INTERFACE:
- case JVMTI_HEAP_REFERENCE_STATIC_FIELD:
- case JVMTI_HEAP_REFERENCE_CONSTANT_POOL:
- /* Should never be seen on an instance dump */
- HPROF_ASSERT(0);
- break;
- case JVMTI_HEAP_REFERENCE_FIELD:
- if ( skip_fields == JNI_TRUE ) {
- break;
- }
- HPROF_ASSERT(is_array!=JNI_TRUE);
- ovalue = empty_value;
- ovalue.i = info->object_index;
- fill_in_field_value(list, fields, fvalues, n_fields,
- info->index, ovalue, 0);
- n_fields_set++;
- HPROF_ASSERT(n_fields_set <= n_fields);
- break;
- case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
- /* We get each object element one at a time. */
- HPROF_ASSERT(is_array==JNI_TRUE);
- HPROF_ASSERT(is_prim_array!=JNI_TRUE);
- if ( num_elements <= info->index ) {
- int nbytes;
-
- if ( values == NULL ) {
- num_elements = info->index + 1;
- nbytes = num_elements*(int)sizeof(ObjectIndex);
- values = (ObjectIndex*)HPROF_MALLOC(nbytes);
- (void)memset(values, 0, nbytes);
- } else {
- void *new_values;
- int new_size;
- int obytes;
-
- obytes = num_elements*(int)sizeof(ObjectIndex);
- new_size = info->index + 1;
- nbytes = new_size*(int)sizeof(ObjectIndex);
- new_values = (void*)HPROF_MALLOC(nbytes);
- (void)memcpy(new_values, values, obytes);
- (void)memset(((char*)new_values)+obytes, 0,
- nbytes-obytes);
- HPROF_FREE(values);
- num_elements = new_size;
- values = new_values;
- }
- }
- HPROF_ASSERT(values[info->index]==0);
- values[info->index] = info->object_index;
- break;
- default:
- /* Ignore, not needed */
- break;
- }
- break;
- case INFO_PRIM_FIELD_DATA:
- if ( skip_fields == JNI_TRUE ) {
- break;
- }
- HPROF_ASSERT(info->primType!=0);
- HPROF_ASSERT(info->length==-1);
- HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_FIELD);
- HPROF_ASSERT(is_array!=JNI_TRUE);
- ovalue = get_key_value(index);
- fill_in_field_value(list, fields, fvalues, n_fields,
- info->index, ovalue, info->primType);
- n_fields_set++;
- HPROF_ASSERT(n_fields_set <= n_fields);
- break;
- case INFO_PRIM_ARRAY_DATA:
- /* Should only be one, and it's handled below */
- HPROF_ASSERT(info->refKind==0);
- /* We assert that nothing else was saved with this array */
- HPROF_ASSERT(index==list&&info->next==0);
- HPROF_ASSERT(is_array==JNI_TRUE);
- HPROF_ASSERT(is_prim_array==JNI_TRUE);
- primType = info->primType;
- elements = get_key_elements(index, primType,
- &num_elements, &num_bytes);
- HPROF_ASSERT(info->length==num_elements);
- size = num_bytes;
- break;
- default:
- HPROF_ASSERT(0);
- break;
- }
- index = info->next;
- }
-
- if ( is_array == JNI_TRUE ) {
- if ( is_prim_array == JNI_TRUE ) {
- HPROF_ASSERT(values==NULL);
- io_heap_prim_array(object_index, trace_serial_num,
- (jint)size, num_elements, sig, elements);
- } else {
- HPROF_ASSERT(elements==NULL);
- io_heap_object_array(object_index, trace_serial_num,
- (jint)size, num_elements, sig, values, class_index);
- }
- } else {
- io_heap_instance_dump(cnum, object_index, trace_serial_num,
- class_index, (jint)size, sig, fields, fvalues, n_fields);
- }
- if ( values != NULL ) {
- HPROF_FREE(values);
- }
- if ( fvalues != NULL ) {
- HPROF_FREE(fvalues);
- }
- if ( elements != NULL ) {
- /* Do NOT free elements, it's a key in the table, leave it be */
- }
-}
-
-/* External interfaces. */
-
-void
-reference_init(void)
-{
- HPROF_ASSERT(gdata->reference_table==NULL);
- gdata->reference_table = table_initialize("Ref", 2048, 4096, 0,
- (int)sizeof(RefInfo));
-}
-
-/* Save away a reference to an object */
-RefIndex
-reference_obj(RefIndex next, jvmtiHeapReferenceKind refKind,
- ObjectIndex object_index, jint index, jint length)
-{
- static RefInfo empty_info;
- RefIndex entry;
- RefInfo info;
-
- info = empty_info;
- info.flavor = INFO_OBJECT_REF_DATA;
- info.refKind = refKind;
- info.object_index = object_index;
- info.index = index;
- info.length = length;
- info.next = next;
- entry = table_create_entry(gdata->reference_table, NULL, 0, (void*)&info);
- return entry;
-}
-
-/* Save away some primitive field data */
-RefIndex
-reference_prim_field(RefIndex next, jvmtiHeapReferenceKind refKind,
- jvmtiPrimitiveType primType, jvalue field_value, jint field_index)
-{
- static RefInfo empty_info;
- RefIndex entry;
- RefInfo info;
-
- HPROF_ASSERT(primType==JVMTI_PRIMITIVE_TYPE_BOOLEAN?(field_value.b==1||field_value.b==0):1);
-
- info = empty_info;
- info.flavor = INFO_PRIM_FIELD_DATA;
- info.refKind = refKind;
- info.primType = primType;
- info.index = field_index;
- info.length = -1;
- info.next = next;
- entry = table_create_entry(gdata->reference_table,
- (void*)&field_value, (int)sizeof(jvalue), (void*)&info);
- return entry;
-}
-
-/* Save away some primitive array data */
-RefIndex
-reference_prim_array(RefIndex next, jvmtiPrimitiveType primType,
- const void *elements, jint elementCount)
-{
- static RefInfo empty_info;
- RefIndex entry;
- RefInfo info;
-
- HPROF_ASSERT(next == 0);
- HPROF_ASSERT(elementCount >= 0);
- HPROF_ASSERT(elements != NULL);
-
- info = empty_info;
- info.flavor = INFO_PRIM_ARRAY_DATA;
- info.refKind = 0;
- info.primType = primType;
- info.index = 0;
- info.length = elementCount;
- info.next = next;
- entry = table_create_entry(gdata->reference_table, (void*)elements,
- elementCount * get_prim_size(primType), (void*)&info);
- return entry;
-}
-
-void
-reference_cleanup(void)
-{
- if ( gdata->reference_table == NULL ) {
- return;
- }
- table_cleanup(gdata->reference_table, NULL, NULL);
- gdata->reference_table = NULL;
-}
-
-void
-reference_dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list)
-{
- dump_instance(env, object_index, list);
-}
-
-void
-reference_dump_class(JNIEnv *env, ObjectIndex object_index, RefIndex list)
-{
- dump_class_and_supers(env, object_index, list);
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_reference.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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_REFERENCE_H
-#define HPROF_REFERENCE_H
-
-void reference_init(void);
-RefIndex reference_obj(RefIndex next, jvmtiHeapReferenceKind kind,
- ObjectIndex object_index, jint index, jint length);
-RefIndex reference_prim_field(RefIndex next, jvmtiHeapReferenceKind refKind,
- jvmtiPrimitiveType primType, jvalue value, jint field_index);
-RefIndex reference_prim_array(RefIndex next, jvmtiPrimitiveType element_type,
- const void *elements, jint count);
-void reference_cleanup(void);
-void reference_dump_class(JNIEnv *env, ObjectIndex object_index,
- RefIndex list);
-void reference_dump_instance(JNIEnv *env, ObjectIndex object_index,
- RefIndex list);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_site.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,905 +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.
- */
-
-
-/* Allocation site table. */
-
-/*
- * Every object allocation will have a place where it was allocated,
- * this is the purpose of the SiteIndex.
- *
- * The allocation site or SiteIndex is unique via a (class,trace) pair.
- *
- * The allocation statistics are accumulated in the SiteInfo for each
- * site.
- *
- * This file also contains the heap iterate logic, which is closely
- * associated with the site table, the object table, and the
- * reference table. Each object has an element in the object table
- * and as the heap is traversed, and information contained in each
- * object is saved as a linked list of references.
- *
- */
-
-#include "hprof.h"
-
-typedef struct SiteKey {
- ClassIndex cnum; /* Unique class number */
- TraceIndex trace_index; /* Trace number */
-} SiteKey;
-
-typedef struct SiteInfo {
- int changed; /* Objects at this site changed? */
- unsigned n_alloced_instances; /* Total allocated instances */
- unsigned n_alloced_bytes; /* Total bytes allocated from here */
- unsigned n_live_instances; /* Live instances for this site. */
- unsigned n_live_bytes; /* Live byte count for this site. */
-} SiteInfo;
-
-typedef struct IterateInfo {
- SiteIndex * site_nums;
- int count;
- int changed_only;
-} IterateInfo;
-
-/* Private internal functions. */
-
-static SiteKey*
-get_pkey(SiteIndex index)
-{
- void *key_ptr;
- int key_len;
-
- table_get_key(gdata->site_table, index, &key_ptr, &key_len);
- HPROF_ASSERT(key_len==sizeof(SiteKey));
- HPROF_ASSERT(key_ptr!=NULL);
- return (SiteKey*)key_ptr;
-}
-
-ClassIndex
-site_get_class_index(SiteIndex index)
-{
- SiteKey *pkey;
-
- pkey = get_pkey(index);
- return pkey->cnum;
-}
-
-TraceIndex
-site_get_trace_index(SiteIndex index)
-{
- SiteKey *pkey;
-
- pkey = get_pkey(index);
- return pkey->trace_index;
-}
-
-static SiteInfo *
-get_info(SiteIndex index)
-{
- SiteInfo *info;
-
- info = (SiteInfo*)table_get_info(gdata->site_table, index);
- return info;
-}
-
-static void
-list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- SiteKey *pkey;
- jlong n_alloced_instances;
- jlong n_alloced_bytes;
- jlong n_live_instances;
- jlong n_live_bytes;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len==sizeof(SiteKey));
- pkey = (SiteKey*)key_ptr;
-
- if ( info_ptr != NULL ) {
- SiteInfo *info;
-
- info = (SiteInfo *)info_ptr;
- n_alloced_instances = info->n_alloced_instances;
- n_alloced_bytes = info->n_alloced_bytes;
- n_live_instances = info->n_live_instances;
- n_live_bytes = info->n_live_bytes;
- } else {
- n_alloced_instances = 0;
- n_alloced_bytes = 0;
- n_live_instances = 0;
- n_live_bytes = 0;
- }
-
- debug_message( "Site 0x%08x: class=0x%08x, trace=0x%08x, "
- "Ninst=(%d,%d), Nbytes=(%d,%d), "
- "Nlive=(%d,%d), NliveBytes=(%d,%d)\n",
- i,
- pkey->cnum,
- pkey->trace_index,
- jlong_high(n_alloced_instances), jlong_low(n_alloced_instances),
- jlong_high(n_alloced_bytes), jlong_low(n_alloced_bytes),
- jlong_high(n_live_instances), jlong_low(n_live_instances),
- jlong_high(n_live_bytes), jlong_low(n_live_bytes));
-}
-
-static void
-collect_iterator(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- IterateInfo *iterate;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len==sizeof(SiteKey));
- HPROF_ASSERT(arg!=NULL);
- iterate = (IterateInfo *)arg;
-
- if ( iterate->changed_only ) {
- SiteInfo *info;
-
- info = (SiteInfo *)info_ptr;
- if ( info==NULL || !info->changed ) {
- return;
- }
- }
- iterate->site_nums[iterate->count++] = i;
-}
-
-static void
-mark_unchanged_iterator(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- SiteInfo *info;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len==sizeof(SiteKey));
-
- info = (SiteInfo *)info_ptr;
- if ( info != NULL ) {
- info->changed = 0;
- }
-}
-
-static int
-qsort_compare_allocated_bytes(const void *p_site1, const void *p_site2)
-{
- SiteIndex site1;
- SiteIndex site2;
- SiteInfo *info1;
- SiteInfo *info2;
-
- HPROF_ASSERT(p_site1!=NULL);
- HPROF_ASSERT(p_site2!=NULL);
- site1 = *(SiteIndex *)p_site1;
- site2 = *(SiteIndex *)p_site2;
- info1 = get_info(site1);
- info2 = get_info(site2);
- return info2->n_alloced_bytes - info1->n_alloced_bytes;
-}
-
-static int
-qsort_compare_live_bytes(const void *p_site1, const void *p_site2)
-{
- SiteIndex site1;
- SiteIndex site2;
- SiteInfo *info1;
- SiteInfo *info2;
-
- HPROF_ASSERT(p_site1!=NULL);
- HPROF_ASSERT(p_site2!=NULL);
- site1 = *(SiteIndex *)p_site1;
- site2 = *(SiteIndex *)p_site2;
- info1 = get_info(site1);
- info2 = get_info(site2);
- return info2->n_live_bytes - info1->n_live_bytes;
-}
-
-static ClassIndex
-find_cnum(jlong class_tag)
-{
- ClassIndex cnum;
- ObjectIndex class_object_index;
- SiteIndex class_site_index;
- SiteKey *pkey;
-
- HPROF_ASSERT(class_tag!=(jlong)0);
- class_object_index = tag_extract(class_tag);
- class_site_index = object_get_site(class_object_index);
- pkey = get_pkey(class_site_index);
- cnum = pkey->cnum;
- return cnum;
-}
-
-/* Create tag and object entry for an untagged object (should be rare) */
-static jlong
-make_new_tag(jlong class_tag, jlong size, TraceIndex trace_index,
- SerialNumber thread_serial_num,
- ObjectIndex *pindex, SiteIndex *psite)
-{
- ObjectIndex object_index;
- SiteIndex object_site_index;
-
- HPROF_ASSERT(class_tag!=(jlong)0);
- object_site_index = site_find_or_create(find_cnum(class_tag), trace_index);
- object_index = object_new(object_site_index, (jint)size,
- OBJECT_SYSTEM, thread_serial_num);
- if ( pindex != NULL ) {
- *pindex = object_index;
- }
- if ( psite != NULL ) {
- *psite = object_site_index;
- }
- return tag_create(object_index);
-}
-
-/* Setup tag on root object, if tagged return object index and site index */
-static void
-setup_tag_on_root(jlong *tag_ptr, jlong class_tag, jlong size,
- SerialNumber thread_serial_num,
- ObjectIndex *pindex, SiteIndex *psite)
-{
- HPROF_ASSERT(class_tag!=(jlong)0);
- if ( (*tag_ptr) != (jlong)0 ) {
- if ( pindex != NULL ) {
- *pindex = tag_extract(*tag_ptr);
- }
- if ( psite != NULL ) {
- *psite = object_get_site(tag_extract(*tag_ptr));
- }
- } else {
- /* Create and set the tag. */
- *tag_ptr = make_new_tag(class_tag, size, gdata->system_trace_index,
- thread_serial_num, pindex, psite);
- }
-}
-
-/* External interfaces */
-
-SiteIndex
-site_find_or_create(ClassIndex cnum, TraceIndex trace_index)
-{
- SiteIndex index;
- static SiteKey empty_key;
- SiteKey key;
-
- key = empty_key;
- HPROF_ASSERT(cnum!=0);
- HPROF_ASSERT(trace_index!=0);
- key.cnum = cnum;
- key.trace_index = trace_index;
- index = table_find_or_create_entry(gdata->site_table,
- &key, (int)sizeof(key), NULL, NULL);
- return index;
-}
-
-void
-site_init(void)
-{
- HPROF_ASSERT(gdata->site_table==NULL);
- gdata->site_table = table_initialize("Site",
- 1024, 1024, 511, (int)sizeof(SiteInfo));
-}
-
-void
-site_list(void)
-{
- debug_message(
- "--------------------- Site Table ------------------------\n");
- table_walk_items(gdata->site_table, &list_item, NULL);
- debug_message(
- "----------------------------------------------------------\n");
-}
-
-void
-site_cleanup(void)
-{
- table_cleanup(gdata->site_table, NULL, NULL);
- gdata->site_table = NULL;
-}
-
-void
-site_update_stats(SiteIndex index, jint size, jint hits)
-{
- SiteInfo *info;
-
- table_lock_enter(gdata->site_table); {
- info = get_info(index);
-
- info->n_live_instances += hits;
- info->n_live_bytes += size;
- info->changed = 1;
-
- gdata->total_live_bytes += size;
- gdata->total_live_instances += hits;
-
- if ( size > 0 ) {
- info->n_alloced_instances += hits;
- info->n_alloced_bytes += size;
- gdata->total_alloced_bytes =
- jlong_add(gdata->total_alloced_bytes, jint_to_jlong(size));
- gdata->total_alloced_instances =
- jlong_add(gdata->total_alloced_instances, jint_to_jlong(hits));
- }
- } table_lock_exit(gdata->site_table);
-}
-
-/* Output allocation sites, up to the given cut-off point, and according
- * to the given flags:
- *
- * SITE_DUMP_INCREMENTAL only dump what's changed since last dump.
- * SITE_SORT_BY_ALLOC sort sites by total allocation rather
- * than live data.
- * SITE_FORCE_GC force a GC before the site dump.
- */
-
-void
-site_write(JNIEnv *env, int flags, double cutoff)
-{
- HPROF_ASSERT(gdata->site_table!=NULL);
- LOG3("site_write", "flags", flags);
-
- if (flags & SITE_FORCE_GC) {
- runGC();
- }
-
- HPROF_ASSERT(gdata->total_live_bytes!=0);
-
- rawMonitorEnter(gdata->data_access_lock); {
-
- IterateInfo iterate;
- int site_table_size;
- double accum_percent;
- void * comment_str;
- int i;
- int cutoff_count;
- int nbytes;
-
- accum_percent = 0;
- site_table_size = table_element_count(gdata->site_table);
-
- (void)memset(&iterate, 0, sizeof(iterate));
- nbytes = site_table_size * (int)sizeof(SiteIndex);
- if ( nbytes > 0 ) {
- iterate.site_nums = HPROF_MALLOC(nbytes);
- (void)memset(iterate.site_nums, 0, nbytes);
- }
- iterate.count = 0;
- iterate.changed_only = flags & SITE_DUMP_INCREMENTAL;
- table_walk_items(gdata->site_table, &collect_iterator, &iterate);
-
- site_table_size = iterate.count;
-
- if (flags & SITE_SORT_BY_ALLOC) {
- comment_str = "allocated bytes";
- qsort(iterate.site_nums, site_table_size, sizeof(SiteIndex),
- &qsort_compare_allocated_bytes);
- } else {
- comment_str = "live bytes";
- qsort(iterate.site_nums, site_table_size, sizeof(SiteIndex),
- &qsort_compare_live_bytes);
- }
-
- trace_output_unmarked(env);
-
- cutoff_count = 0;
- for (i = 0; i < site_table_size; i++) {
- SiteInfo *info;
- SiteIndex index;
- double ratio;
-
- index= iterate.site_nums[i];
- HPROF_ASSERT(index!=0);
- info = get_info(index);
- ratio = (double)info->n_live_bytes / (double)gdata->total_live_bytes;
- if (ratio < cutoff) {
- break;
- }
- cutoff_count++;
- }
-
- io_write_sites_header( comment_str,
- flags,
- cutoff,
- gdata->total_live_bytes,
- gdata->total_live_instances,
- gdata->total_alloced_bytes,
- gdata->total_alloced_instances,
- cutoff_count);
-
- for (i = 0; i < cutoff_count; i++) {
- SiteInfo *info;
- SiteKey *pkey;
- SiteIndex index;
- char *class_signature;
- double ratio;
-
- index = iterate.site_nums[i];
- pkey = get_pkey(index);
- info = get_info(index);
-
- ratio = (double)info->n_live_bytes / (double)gdata->total_live_bytes;
- accum_percent += ratio;
-
- class_signature = string_get(class_get_signature(pkey->cnum));
-
- io_write_sites_elem(i + 1,
- ratio,
- accum_percent,
- class_signature,
- class_get_serial_number(pkey->cnum),
- trace_get_serial_number(pkey->trace_index),
- info->n_live_bytes,
- info->n_live_instances,
- info->n_alloced_bytes,
- info->n_alloced_instances);
- }
-
- io_write_sites_footer();
-
- table_walk_items(gdata->site_table, &mark_unchanged_iterator, NULL);
-
- if ( iterate.site_nums != NULL ) {
- HPROF_FREE(iterate.site_nums);
- }
-
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-/* Primitive array data callback for FollowReferences */
-static jint JNICALL
-cbPrimArrayData(jlong class_tag, jlong size, jlong* tag_ptr,
- jint element_count, jvmtiPrimitiveType element_type,
- const void* elements, void* user_data)
-{
- ObjectIndex object_index;
- RefIndex ref_index;
- RefIndex prev_ref_index;
-
- HPROF_ASSERT(tag_ptr!=NULL);
- HPROF_ASSERT(class_tag!=(jlong)0);
- HPROF_ASSERT((*tag_ptr)!=(jlong)0);
- if ( class_tag == (jlong)0 || (*tag_ptr) == (jlong)0 ) {
- /* We can't do anything with a class_tag==0, just skip it */
- return JVMTI_VISIT_OBJECTS;
- }
-
- /* Assume object has been tagged, get object index */
- object_index = tag_extract((*tag_ptr));
-
- /* Save string data */
- prev_ref_index = object_get_references(object_index);
- ref_index = reference_prim_array(prev_ref_index,
- element_type, elements, element_count);
- object_set_references(object_index, ref_index);
-
- return JVMTI_VISIT_OBJECTS;
-}
-
-/* Primitive field data callback for FollowReferences */
-static jint JNICALL
-cbPrimFieldData(jvmtiHeapReferenceKind reference_kind,
- const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
- jlong* tag_ptr, jvalue value, jvmtiPrimitiveType value_type,
- void* user_data)
-{
- ObjectIndex object_index;
- jint field_index;
- RefIndex ref_index;
- RefIndex prev_ref_index;
-
- HPROF_ASSERT(tag_ptr!=NULL);
- HPROF_ASSERT(class_tag!=(jlong)0);
- HPROF_ASSERT((*tag_ptr)!=(jlong)0);
- if ( class_tag == (jlong)0 || (*tag_ptr) == (jlong)0 ) {
- /* We can't do anything with a class_tag==0, just skip it */
- return JVMTI_VISIT_OBJECTS;
- }
-
- /* If the field is 0, just skip it, we assume 0 */
- if ( value.j == (jlong)0 ) {
- return JVMTI_VISIT_OBJECTS;
- }
-
- /* Get field index */
- field_index = reference_info->field.index;
-
- /* We assume the object was tagged */
- object_index = tag_extract((*tag_ptr));
-
- /* Save primitive field data */
- prev_ref_index = object_get_references(object_index);
- ref_index = reference_prim_field(prev_ref_index, reference_kind,
- value_type, value, field_index);
- object_set_references(object_index, ref_index);
-
- return JVMTI_VISIT_OBJECTS;
-}
-
-static SerialNumber
-checkThreadSerialNumber(SerialNumber thread_serial_num)
-{
- TlsIndex tls_index;
-
- if ( thread_serial_num == gdata->unknown_thread_serial_num ) {
- return thread_serial_num;
- }
- tls_index = tls_find(thread_serial_num);
- if ( tls_index != 0 && tls_get_in_heap_dump(tls_index) != 0 ) {
- return thread_serial_num;
- }
- return gdata->unknown_thread_serial_num;
-}
-
-/* Get the object index and thread serial number for this local object */
-static void
-localReference(jlong *tag_ptr, jlong class_tag, jlong thread_tag,
- jlong size, ObjectIndex *pobject_index, SerialNumber *pthread_serial_num)
-{
- ObjectIndex object_index;
- SerialNumber thread_serial_num;
-
- HPROF_ASSERT(pobject_index!=NULL);
- HPROF_ASSERT(pthread_serial_num!=NULL);
- HPROF_ASSERT(tag_ptr!=NULL);
- HPROF_ASSERT(class_tag!=(jlong)0);
-
- if ( (*tag_ptr) != (jlong)0 ) {
- object_index = tag_extract(*tag_ptr);
- thread_serial_num = object_get_thread_serial_number(object_index);
- thread_serial_num = checkThreadSerialNumber(thread_serial_num);
- } else {
- if ( thread_tag != (jlong)0 ) {
- ObjectIndex thread_object_index;
-
- thread_object_index = tag_extract(thread_tag);
- thread_serial_num =
- object_get_thread_serial_number(thread_object_index);
- thread_serial_num = checkThreadSerialNumber(thread_serial_num);
- } else {
- thread_serial_num = gdata->unknown_thread_serial_num;
- }
- /* Create and set the tag. */
- *tag_ptr = make_new_tag(class_tag, size, gdata->system_trace_index,
- thread_serial_num, &object_index, NULL);
- }
-
- HPROF_ASSERT(thread_serial_num!=0);
- HPROF_ASSERT(object_index!=0);
- *pobject_index = object_index;
- *pthread_serial_num = thread_serial_num;
-}
-
-/* Store away plain object reference information */
-static jint
-objectReference(jvmtiHeapReferenceKind reference_kind,
- const jvmtiHeapReferenceInfo* reference_info,
- jlong class_tag, jlong size, jlong* tag_ptr,
- jlong* referrer_tag_ptr, jint length)
-{
- ObjectIndex object_index;
- jint reference_index;
- RefIndex ref_index;
- RefIndex prev_ref_index;
- ObjectIndex referrer_object_index;
- jlong object_tag;
-
- HPROF_ASSERT(tag_ptr!=NULL);
- HPROF_ASSERT(class_tag!=(jlong)0);
- HPROF_ASSERT(referrer_tag_ptr!=NULL);
- HPROF_ASSERT((*referrer_tag_ptr)!=(jlong)0);
- if ( class_tag == (jlong)0 || (*referrer_tag_ptr) == (jlong)0 ) {
- /* We can't do anything with a class_tag==0, just skip it */
- return JVMTI_VISIT_OBJECTS;
- }
-
- switch ( reference_kind ) {
- case JVMTI_HEAP_REFERENCE_CLASS_LOADER:
- case JVMTI_HEAP_REFERENCE_INTERFACE:
- default:
- /* Currently we don't need these */
- return JVMTI_VISIT_OBJECTS;
- case JVMTI_HEAP_REFERENCE_FIELD:
- case JVMTI_HEAP_REFERENCE_STATIC_FIELD:
- reference_index = reference_info->field.index;
- break;
- case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
- reference_index = reference_info->array.index;
- break;
- case JVMTI_HEAP_REFERENCE_CONSTANT_POOL:
- reference_index = reference_info->constant_pool.index;
- break;
- case JVMTI_HEAP_REFERENCE_SIGNERS:
- case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:
- reference_index = 0;
- break;
- }
-
- /* We assume the referrer is tagged */
- referrer_object_index = tag_extract((*referrer_tag_ptr));
-
- /* Now check the referree */
- object_tag = *tag_ptr;
- if ( object_tag != (jlong)0 ) {
- object_index = tag_extract(object_tag);
- } else {
- /* Create and set the tag. */
- object_tag = make_new_tag(class_tag, size, gdata->system_trace_index,
- gdata->unknown_thread_serial_num,
- &object_index, NULL);
- *tag_ptr = object_tag;
- }
- HPROF_ASSERT(object_index!=0);
-
- /* Save reference information */
- prev_ref_index = object_get_references(referrer_object_index);
- ref_index = reference_obj(prev_ref_index, reference_kind,
- object_index, reference_index, length);
- object_set_references(referrer_object_index, ref_index);
-
- return JVMTI_VISIT_OBJECTS;
-}
-
-/* FollowReferences heap_reference_callback */
-static jint JNICALL
-cbReference(jvmtiHeapReferenceKind reference_kind,
- const jvmtiHeapReferenceInfo* reference_info,
- jlong class_tag, jlong referrer_class_tag,
- jlong size, jlong* tag_ptr,
- jlong* referrer_tag_ptr, jint length, void* user_data)
-{
- ObjectIndex object_index;
-
- /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
- * are allowed here (see the JVMTI Spec).
- */
-
- HPROF_ASSERT(tag_ptr!=NULL);
- HPROF_ASSERT(class_tag!=(jlong)0);
- if ( class_tag == (jlong)0 ) {
- /* We can't do anything with a class_tag==0, just skip it */
- return JVMTI_VISIT_OBJECTS;
- }
-
- switch ( reference_kind ) {
-
- case JVMTI_HEAP_REFERENCE_FIELD:
- case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
- case JVMTI_HEAP_REFERENCE_CLASS_LOADER:
- case JVMTI_HEAP_REFERENCE_SIGNERS:
- case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:
- case JVMTI_HEAP_REFERENCE_INTERFACE:
- case JVMTI_HEAP_REFERENCE_STATIC_FIELD:
- case JVMTI_HEAP_REFERENCE_CONSTANT_POOL:
- return objectReference(reference_kind, reference_info,
- class_tag, size, tag_ptr, referrer_tag_ptr, length);
-
- case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: {
- SerialNumber trace_serial_num;
- SerialNumber gref_serial_num;
- TraceIndex trace_index;
- SiteIndex object_site_index;
-
- setup_tag_on_root(tag_ptr, class_tag, size,
- gdata->unknown_thread_serial_num,
- &object_index, &object_site_index);
- if ( object_site_index != 0 ) {
- SiteKey *pkey;
-
- pkey = get_pkey(object_site_index);
- trace_index = pkey->trace_index;
- } else {
- trace_index = gdata->system_trace_index;
- }
- trace_serial_num = trace_get_serial_number(trace_index);
- gref_serial_num = gdata->gref_serial_number_counter++;
- io_heap_root_jni_global(object_index, gref_serial_num,
- trace_serial_num);
- }
- break;
-
- case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: {
- char *sig;
- SerialNumber class_serial_num;
- SiteIndex object_site_index;
-
- setup_tag_on_root(tag_ptr, class_tag, size,
- gdata->unknown_thread_serial_num,
- &object_index, &object_site_index);
- sig = "Unknown";
- class_serial_num = 0;
- if ( object_site_index != 0 ) {
- SiteKey *pkey;
-
- pkey = get_pkey(object_site_index);
- sig = string_get(class_get_signature(pkey->cnum));
- class_serial_num = class_get_serial_number(pkey->cnum);
- }
- io_heap_root_system_class(object_index, sig, class_serial_num);
- }
- break;
-
- case JVMTI_HEAP_REFERENCE_MONITOR:
- setup_tag_on_root(tag_ptr, class_tag, size,
- gdata->unknown_thread_serial_num,
- &object_index, NULL);
- io_heap_root_monitor(object_index);
- break;
-
- case JVMTI_HEAP_REFERENCE_STACK_LOCAL: {
- SerialNumber thread_serial_num;
- jlong thread_tag;
-
- thread_tag = reference_info->stack_local.thread_tag;
- localReference(tag_ptr, class_tag, thread_tag, size,
- &object_index, &thread_serial_num);
- io_heap_root_java_frame(object_index, thread_serial_num,
- reference_info->stack_local.depth);
- }
- break;
-
- case JVMTI_HEAP_REFERENCE_JNI_LOCAL: {
- SerialNumber thread_serial_num;
- jlong thread_tag;
-
- thread_tag = reference_info->jni_local.thread_tag;
- localReference(tag_ptr, class_tag, thread_tag, size,
- &object_index, &thread_serial_num);
- io_heap_root_jni_local(object_index, thread_serial_num,
- reference_info->jni_local.depth);
- }
- break;
-
- case JVMTI_HEAP_REFERENCE_THREAD: {
- SerialNumber thread_serial_num;
- SerialNumber trace_serial_num;
- TraceIndex trace_index;
- SiteIndex object_site_index;
- TlsIndex tls_index;
-
- /* It is assumed that tag_ptr is referring to a
- * java.lang.Thread object here.
- */
- if ( (*tag_ptr) != (jlong)0 ) {
- setup_tag_on_root(tag_ptr, class_tag, size, 0,
- &object_index, &object_site_index);
- trace_index = site_get_trace_index(object_site_index);
- /* Hopefully the ThreadStart event put this thread's
- * correct serial number on it's object.
- */
- thread_serial_num = object_get_thread_serial_number(object_index);
- } else {
- /* Rare situation that a Thread object is not tagged.
- * Create special unique thread serial number in this
- * case, probably means we never saw a thread start
- * or thread end, or even an allocation of the thread
- * object.
- */
- thread_serial_num = gdata->thread_serial_number_counter++;
- setup_tag_on_root(tag_ptr, class_tag, size,
- thread_serial_num,
- &object_index, &object_site_index);
- trace_index = gdata->system_trace_index;
- }
- /* Get tls_index and set in_heap_dump, if we find it. */
- tls_index = tls_find(thread_serial_num);
- if ( tls_index != 0 ) {
- tls_set_in_heap_dump(tls_index, 1);
- }
- trace_serial_num = trace_get_serial_number(trace_index);
- /* Issue thread object (must be before thread root) */
- io_heap_root_thread_object(object_index,
- thread_serial_num, trace_serial_num);
- /* Issue thread root */
- io_heap_root_thread(object_index, thread_serial_num);
- }
- break;
-
- case JVMTI_HEAP_REFERENCE_OTHER:
- setup_tag_on_root(tag_ptr, class_tag, size,
- gdata->unknown_thread_serial_num,
- &object_index, NULL);
- io_heap_root_unknown(object_index);
- break;
-
- default:
- /* Ignore anything else */
- break;
-
- }
-
- return JVMTI_VISIT_OBJECTS;
-}
-
-void
-site_heapdump(JNIEnv *env)
-{
-
- rawMonitorEnter(gdata->data_access_lock); {
-
- jvmtiHeapCallbacks heapCallbacks;
-
- /* Remove class dumped status, all classes must be dumped */
- class_all_status_remove(CLASS_DUMPED);
-
- /* Clear in_heap_dump flag */
- tls_clear_in_heap_dump();
-
- /* Dump the last thread traces and get the lists back we need */
- tls_dump_traces(env);
-
- /* Write header for heap dump */
- io_heap_header(gdata->total_live_instances, gdata->total_live_bytes);
-
- /* Setup a clean reference table */
- reference_init();
-
- /* Walk over all reachable objects and dump out roots */
- gdata->gref_serial_number_counter = gdata->gref_serial_number_start;
-
- /* Issue thread object for fake non-existent unknown thread
- * just in case someone refers to it. Real threads are handled
- * during iterate over reachable objects.
- */
- io_heap_root_thread_object(0, gdata->unknown_thread_serial_num,
- trace_get_serial_number(gdata->system_trace_index));
-
- /* Iterate over heap and get the real stuff */
- (void)memset(&heapCallbacks, 0, sizeof(heapCallbacks));
-
- /* Select callbacks */
- heapCallbacks.heap_reference_callback = &cbReference;
- if ( gdata->primfields == JNI_TRUE ) {
- heapCallbacks.primitive_field_callback = &cbPrimFieldData;
- }
- if ( gdata->primarrays == JNI_TRUE ) {
- heapCallbacks.array_primitive_value_callback = &cbPrimArrayData;
- }
- followReferences(&heapCallbacks, (void*)NULL);
-
- /* Process reference information. */
- object_reference_dump(env);
- object_clear_references();
- reference_cleanup();
-
- /* Dump the last thread traces and get the lists back we need */
- tls_dump_traces(env);
-
- /* Write out footer for heap dump */
- io_heap_footer();
-
- } rawMonitorExit(gdata->data_access_lock);
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_site.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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_SITE_H
-#define HPROF_SITE_H
-
-void site_init(void);
-SiteIndex site_find_or_create(ClassIndex cnum, TraceIndex trace_index);
-TraceIndex site_get_trace_index(SiteIndex index);
-ClassIndex site_get_class_index(SiteIndex index);
-
-void site_list(void);
-void site_cleanup(void);
-void site_update_stats(SiteIndex index, jint size, jint hits);
-void site_write(JNIEnv *env, int flags, double cutoff);
-
-void site_heapdump(JNIEnv *env);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_stack.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +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.
- */
-
-
-/* Simple stack storage mechanism (or simple List). */
-
-/*
- * Stack is any depth (grows as it needs to), elements are arbitrary
- * length but known at stack init time.
- *
- * Stack elements can be accessed via pointers (be careful, if stack
- * moved while you point into stack you have problems)
- *
- * Pointers to stack elements passed in are copied.
- *
- * Since the stack can be inspected, it can be used for more than just
- * a simple stack.
- *
- */
-
-#include "hprof.h"
-
-static void
-resize(Stack *stack)
-{
- void *old_elements;
- void *new_elements;
- int old_size;
- int new_size;
-
- HPROF_ASSERT(stack!=NULL);
- HPROF_ASSERT(stack->elements!=NULL);
- HPROF_ASSERT(stack->size>0);
- HPROF_ASSERT(stack->elem_size>0);
- HPROF_ASSERT(stack->incr_size>0);
- old_size = stack->size;
- old_elements = stack->elements;
- if ( (stack->resizes % 10) && stack->incr_size < (old_size >> 2) ) {
- stack->incr_size = old_size >> 2; /* 1/4 the old_size */
- }
- new_size = old_size + stack->incr_size;
- new_elements = HPROF_MALLOC(new_size*stack->elem_size);
- (void)memcpy(new_elements, old_elements, old_size*stack->elem_size);
- stack->size = new_size;
- stack->elements = new_elements;
- HPROF_FREE(old_elements);
- stack->resizes++;
-}
-
-Stack *
-stack_init(int init_size, int incr_size, int elem_size)
-{
- Stack *stack;
- void *elements;
-
- HPROF_ASSERT(init_size>0);
- HPROF_ASSERT(elem_size>0);
- HPROF_ASSERT(incr_size>0);
- stack = (Stack*)HPROF_MALLOC((int)sizeof(Stack));
- elements = HPROF_MALLOC(init_size*elem_size);
- stack->size = init_size;
- stack->incr_size = incr_size;
- stack->elem_size = elem_size;
- stack->count = 0;
- stack->elements = elements;
- stack->resizes = 0;
- return stack;
-}
-
-void *
-stack_element(Stack *stack, int i)
-{
- HPROF_ASSERT(stack!=NULL);
- HPROF_ASSERT(stack->elements!=NULL);
- HPROF_ASSERT(stack->count>i);
- HPROF_ASSERT(i>=0);
- return (void*)(((char*)stack->elements) + i * stack->elem_size);
-}
-
-void *
-stack_top(Stack *stack)
-{
- void *element;
-
- HPROF_ASSERT(stack!=NULL);
- element = NULL;
- if ( stack->count > 0 ) {
- element = stack_element(stack, (stack->count-1));
- }
- return element;
-}
-
-int
-stack_depth(Stack *stack)
-{
- HPROF_ASSERT(stack!=NULL);
- return stack->count;
-}
-
-void *
-stack_pop(Stack *stack)
-{
- void *element;
-
- element = stack_top(stack);
- if ( element != NULL ) {
- stack->count--;
- }
- return element;
-}
-
-void
-stack_push(Stack *stack, void *element)
-{
- void *top_element;
-
- HPROF_ASSERT(stack!=NULL);
- if ( stack->count >= stack->size ) {
- resize(stack);
- }
- stack->count++;
- top_element = stack_top(stack);
- (void)memcpy(top_element, element, stack->elem_size);
-}
-
-void
-stack_term(Stack *stack)
-{
- HPROF_ASSERT(stack!=NULL);
- if ( stack->elements != NULL ) {
- HPROF_FREE(stack->elements);
- }
- HPROF_FREE(stack);
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_stack.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +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_STACK_H
-#define HPROF_STACK_H
-
-typedef struct Stack {
- int elem_size;
- int incr_size;
- int size;
- int count;
- int resizes;
- void *elements;
-} Stack;
-
-Stack *stack_init(int init_size, int incr_size, int elem_size);
-void *stack_element(Stack *stack, int i);
-void *stack_top(Stack *stack);
-int stack_depth(Stack *stack);
-void *stack_pop(Stack *stack);
-void stack_push(Stack *stack, void *element);
-void stack_term(Stack *stack);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_string.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +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.
- */
-
-
-/* Table of byte arrays (e.g. char* string + NULL byte) */
-
-/*
- * Strings are unique by their own contents, since the string itself
- * is the Key, and the hprof_table.c guarantees that keys don't move,
- * this works out perfect. Any key in this table can be used as
- * an char*.
- *
- * This does mean that this table has dynamically sized keys.
- *
- * Care needs to be taken to make sure the NULL byte is included, not for
- * the sake of hprof_table.c, but so that the key can be used as a char*.
- *
- */
-
-#include "hprof.h"
-
-void
-string_init(void)
-{
- HPROF_ASSERT(gdata->string_table==NULL);
- gdata->string_table = table_initialize("Strings", 4096, 4096, 1024, 0);
-}
-
-StringIndex
-string_find_or_create(const char *str)
-{
- return table_find_or_create_entry(gdata->string_table,
- (void*)str, (int)strlen(str)+1, NULL, NULL);
-}
-
-static void
-list_item(TableIndex index, void *str, int len, void *info_ptr, void *arg)
-{
- debug_message( "0x%08x: String \"%s\"\n", index, (const char *)str);
-}
-
-void
-string_list(void)
-{
- debug_message(
- "-------------------- String Table ------------------------\n");
- table_walk_items(gdata->string_table, &list_item, NULL);
- debug_message(
- "----------------------------------------------------------\n");
-}
-
-void
-string_cleanup(void)
-{
- table_cleanup(gdata->string_table, NULL, NULL);
- gdata->string_table = NULL;
-}
-
-char *
-string_get(StringIndex index)
-{
- void *key;
- int key_len;
-
- table_get_key(gdata->string_table, index, &key, &key_len);
- HPROF_ASSERT(key_len>0);
- return (char*)key;
-}
-
-int
-string_get_len(StringIndex index)
-{
- void *key;
- int key_len;
-
- table_get_key(gdata->string_table, index, &key, &key_len);
- HPROF_ASSERT(key_len>0);
- return key_len-1;
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_string.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +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_STRING_H
-#define HPROF_STRING_H
-
-void string_init(void);
-StringIndex string_find_or_create(const char *name);
-char * string_get(StringIndex index);
-int string_get_len(StringIndex index);
-void string_list(void);
-void string_cleanup(void);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_table.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,954 +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.
- */
-
-
-/* Lookup Table of generic elements. */
-
-/*
- * Each table has a unique lock, all accesses are protected.
- *
- * Table elements are identified with a 32bit unsigned int.
- * (Also see HARE trick below, which makes the TableIndex unique per table).
- *
- * Each element has a key (N bytes) and possible additional info.
- *
- * Two elements with the same key should be the same element.
- *
- * The storage for the Key and Info cannot move, the table itself can.
- *
- * The hash table will only be allocated if we have keys, and will resize
- * when the table needs to resize. The hash buckets just provide the
- * reference to the first TableIndex in the hash bucket, the next
- * field of the TableElement takes you to the next item in the hash
- * bucket. Lookups will drift the looked up item to the head of the
- * list.
- *
- * The full 32bit hashcode and key length is saved for comparisons, the
- * last thing done is the actual comparison of the Key contents with
- * keys_equal().
- *
- * Freed elements (not many tables actually free items) are managed with
- * a bit vector and a low index where a freed element might be found.
- * Bytes are inspected until a non-zero byte indicates a freed bit is
- * set. A count of freed elements is also kept.
- *
- */
-
-#include "hprof.h"
-
-/* Macros for bit vectors: unsigned char 2^3==8 OR unsigned int 2^5==32 */
-
-#define BV_CHUNK_POWER_2 3 /* 2 to this power == BV_CHUNK_BITSIZE */
-#define BV_CHUNK_TYPE unsigned char
-
-#define BV_CHUNK_BITSIZE (((int)sizeof(BV_CHUNK_TYPE))<<3) /* x8 */
-#define BV_CHUNK_INDEX_MASK ( (1 << BV_CHUNK_POWER_2) - 1 )
-#define BV_ELEMENT_COUNT(nelems) ((((nelems+1)) >> BV_CHUNK_POWER_2) + 1)
-
-#define BV_CHUNK_ROUND(i) ((i) & ~(BV_CHUNK_INDEX_MASK))
-#define BV_CHUNK(ptr, i) \
- (((BV_CHUNK_TYPE*)(ptr))[(i) >> BV_CHUNK_POWER_2])
-#define BV_CHUNK_MASK(i) \
- (1 << ((i) & BV_CHUNK_INDEX_MASK))
-
-/* Hash code value */
-
-typedef unsigned HashCode;
-
-/* Basic key for an element. What makes the element unique. */
-
-typedef struct TableKey {
- void *ptr; /* Pointer to arbitrary data that forms the key. */
- int len; /* Length in bytes of this key. */
-} TableKey;
-
-/* Basic TableElement (but only allocated if keys are used) */
-
-typedef struct TableElement {
- TableKey key; /* The element key. */
- HashCode hcode; /* The full 32bit hashcode for the key. */
- TableIndex next; /* The next TableElement in the hash bucket chain. */
- void *info; /* Info pointer */
-} TableElement;
-
-/* Generic Lookup Table structure */
-
-typedef struct LookupTable {
- char name[48]; /* Name of table. */
- void *table; /* Pointer to array of elements. */
- TableIndex *hash_buckets; /* Pointer to hash bucket chains. */
- Blocks *info_blocks; /* Blocks space for info */
- Blocks *key_blocks; /* Blocks space for keys */
- TableIndex next_index; /* Next element available. */
- TableIndex table_size; /* Current size of table. */
- TableIndex table_incr; /* Suggested increment size. */
- TableIndex hash_bucket_count; /* Number of hash buckets. */
- int elem_size; /* Size of element. */
- int info_size; /* Size of info structure (can be 0). */
- void *freed_bv; /* Freed element bit vector */
- int freed_count; /* Count of freed'd elements */
- TableIndex freed_start; /* First freed in table */
- int resizes; /* Count of table resizes done. */
- unsigned bucket_walks; /* Count of bucket walks. */
- jrawMonitorID lock; /* Lock for table access. */
- SerialNumber serial_num; /* Table serial number. */
- TableIndex hare; /* Rabbit (HARE) trick. */
-} LookupTable;
-
-/* To get a pointer to an element, regardless of element size. */
-
-#define ELEMENT_PTR(ltable, i) \
- ((void*)(((char*)(ltable)->table) + (ltable)->elem_size * (i)))
-
-/* Sanity, check all the time. */
-
-#define SANITY_CHECK(condition) ( (condition) ? (void)0 : \
- HPROF_ERROR(JNI_FALSE, "SANITY IN QUESTION: " #condition))
-
-/* To see if an index is valid. */
-
-#define SANITY_CHECK_INDEX(ltable,i) SANITY_CHECK((i) < ltable->next_index)
-
-/* Small rabbits (hares) can be hidden in the index value returned.
- * Only the right rabbits are allowed in certain pens (LookupTables).
- * When herding rabbits it's important to keep them separate,
- * there are lots of rabbits, all different kinds and sizes,
- * keeping them all separate is important to avoid cross breeding.
- */
-
-#define _SANITY_USE_HARE
-#ifdef _SANITY_USE_HARE
- #define SANITY_ADD_HARE(i,hare) (SANITY_REMOVE_HARE(i) | (hare))
- #define SANITY_REMOVE_HARE(i) ((i) & 0x0FFFFFFF)
- #define SANITY_CHECK_HARE(i,hare) SANITY_CHECK(SANITY_ADD_HARE(i,hare)==(i))
-#else
- #define SANITY_ADD_HARE(i,hare) (i)
- #define SANITY_REMOVE_HARE(i) (i)
- #define SANITY_CHECK_HARE(i,hare)
-#endif
-
-static jrawMonitorID
-lock_create(char *name)
-{
- jrawMonitorID stanley;
-
- stanley = createRawMonitor(name);
- return stanley;
-}
-
-static void
-lock_destroy(jrawMonitorID stanley)
-{
- if ( stanley != NULL ) {
- destroyRawMonitor(stanley);
- }
-}
-
-static void
-lock_enter(jrawMonitorID stanley)
-{
- if ( stanley != NULL ) {
- rawMonitorEnter(stanley);
- }
-}
-
-static void
-lock_exit(jrawMonitorID stanley)
-{
- if ( stanley != NULL ) {
- rawMonitorExit(stanley);
- }
-}
-
-static void
-get_key(LookupTable *ltable, TableIndex index, void **pkey_ptr, int *pkey_len)
-{
- *pkey_ptr = ((TableElement*)ELEMENT_PTR(ltable,index))->key.ptr;
- *pkey_len = ((TableElement*)ELEMENT_PTR(ltable,index))->key.len;
-}
-
-static void *
-get_info(LookupTable *ltable, TableIndex index)
-{
- TableElement *element;
-
- element = (TableElement*)ELEMENT_PTR(ltable,index);
- return element->info;
-}
-
-static void
-hash_out(LookupTable *ltable, TableIndex index)
-{
- if ( ltable->hash_bucket_count > 0 ) {
- TableElement *element;
- TableElement *prev_e;
- TableIndex bucket;
- TableIndex i;
-
- element = (TableElement*)ELEMENT_PTR(ltable,index);
- bucket = (element->hcode % ltable->hash_bucket_count);
- i = ltable->hash_buckets[bucket];
- HPROF_ASSERT(i!=0);
- prev_e = NULL;
- while ( i != 0 && i != index ) {
- prev_e = (TableElement*)ELEMENT_PTR(ltable,i);
- i = prev_e->next;
- }
- HPROF_ASSERT(i==index);
- if ( prev_e == NULL ) {
- ltable->hash_buckets[bucket] = element->next;
- } else {
- prev_e->next = element->next;
- }
- element->next = 0;
- element->hcode = 0;
- }
-}
-
-static jboolean
-is_freed_entry(LookupTable *ltable, TableIndex index)
-{
- if ( ltable->freed_bv == NULL ) {
- return JNI_FALSE;
- }
- if ( ( BV_CHUNK(ltable->freed_bv, index) & BV_CHUNK_MASK(index) ) != 0 ) {
- return JNI_TRUE;
- }
- return JNI_FALSE;
-}
-
-static void
-set_freed_bit(LookupTable *ltable, TableIndex index)
-{
- void *p;
-
- HPROF_ASSERT(!is_freed_entry(ltable, index));
- p = ltable->freed_bv;
- if ( p == NULL ) {
- int size;
-
- /* First time for a free */
- HPROF_ASSERT(ltable->freed_start==0);
- HPROF_ASSERT(ltable->freed_start==0);
- size = BV_ELEMENT_COUNT(ltable->table_size);
- p = HPROF_MALLOC(size*(int)sizeof(BV_CHUNK_TYPE));
- ltable->freed_bv = p;
- (void)memset(p, 0, size*(int)sizeof(BV_CHUNK_TYPE));
- }
- BV_CHUNK(p, index) |= BV_CHUNK_MASK(index);
- ltable->freed_count++;
- if ( ltable->freed_count == 1 ) {
- /* Set freed_start for first time. */
- HPROF_ASSERT(ltable->freed_start==0);
- ltable->freed_start = index;
- } else if ( index < ltable->freed_start ) {
- /* Set freed_start to smaller value so we can be smart about search */
- HPROF_ASSERT(ltable->freed_start!=0);
- ltable->freed_start = index;
- }
- HPROF_ASSERT(ltable->freed_start!=0);
- HPROF_ASSERT(ltable->freed_start < ltable->next_index);
- HPROF_ASSERT(is_freed_entry(ltable, index));
-}
-
-static TableIndex
-find_freed_entry(LookupTable *ltable)
-{
- if ( ltable->freed_count > 0 ) {
- TableIndex i;
- TableIndex istart;
- void *p;
- BV_CHUNK_TYPE chunk;
-
- HPROF_ASSERT(BV_CHUNK_BITSIZE==(1<<BV_CHUNK_POWER_2));
-
- p = ltable->freed_bv;
- HPROF_ASSERT(p!=NULL);
-
- /* Go to beginning of chunk */
- HPROF_ASSERT(ltable->freed_start!=0);
- HPROF_ASSERT(ltable->freed_start < ltable->next_index);
- istart = BV_CHUNK_ROUND(ltable->freed_start);
-
- /* Find chunk with any bit set */
- chunk = 0;
- for( ; istart < ltable->next_index ; istart += BV_CHUNK_BITSIZE ) {
- chunk = BV_CHUNK(p, istart);
- if ( chunk != 0 ) {
- break;
- }
- }
- HPROF_ASSERT(chunk!=0);
- HPROF_ASSERT(chunk==BV_CHUNK(p,istart));
- HPROF_ASSERT(istart < ltable->next_index);
-
- /* Find bit in chunk and return index of freed item */
- for( i = istart ; i < (istart+BV_CHUNK_BITSIZE) ; i++) {
- BV_CHUNK_TYPE mask;
-
- mask = BV_CHUNK_MASK(i);
- if ( (chunk & mask) != 0 ) {
- HPROF_ASSERT(chunk==BV_CHUNK(p,i));
- chunk &= ~mask;
- BV_CHUNK(p, i) = chunk;
- ltable->freed_count--;
- HPROF_ASSERT(i < ltable->next_index);
- if ( ltable->freed_count > 0 ) {
- /* Set freed_start so we can be smart about search */
- HPROF_ASSERT((i+1) < ltable->next_index);
- ltable->freed_start = i+1;
- } else {
- /* Clear freed_start because there are no freed entries */
- ltable->freed_start = 0;
- }
- HPROF_ASSERT(!is_freed_entry(ltable, i));
- return i;
- }
- }
- HPROF_ASSERT(0);
- }
- return 0;
-}
-
-static void
-free_entry(LookupTable *ltable, TableIndex index)
-{
- set_freed_bit(ltable, index);
- hash_out(ltable, index);
-}
-
-/* Fairly generic hash code generator (not a hash table index) */
-static HashCode
-hashcode(void *key_ptr, int key_len)
-{
- unsigned char * p;
- HashCode hcode;
- int i;
-
- hcode = 0;
- if ( key_ptr == NULL || key_len == 0 ) {
- return hcode;
- }
- i = 0;
- p = (unsigned char*)key_ptr;
- for ( ; i < key_len-3 ; i += 4 ) {
- /* Do a little loop unrolling */
- hcode += (
- ( (unsigned)(p[i]) << 24 ) |
- ( (unsigned)(p[i+1]) << 16 ) |
- ( (unsigned)(p[i+2]) << 8 ) |
- ( (unsigned)(p[i+3]) )
- );
- }
- for ( ; i < key_len ; i++ ) {
- hcode += (unsigned)(p[i]);
- }
- return hcode;
-}
-
-static void
-hash_in(LookupTable *ltable, TableIndex index, HashCode hcode)
-{
- if ( ltable->hash_bucket_count > 0 ) {
- TableElement *element;
- TableIndex bucket;
-
- bucket = (hcode % ltable->hash_bucket_count);
- element = (TableElement*)ELEMENT_PTR(ltable, index);
- element->hcode = hcode;
- element->next = ltable->hash_buckets[bucket];
- ltable->hash_buckets[bucket] = index;
- }
-}
-
-static void
-resize_hash_buckets(LookupTable *ltable)
-{
- /* Don't want to do this too often. */
-
- /* Hash table needs resizing when it's smaller than 1/16 the number of
- * elements used in the table. This is just a guess.
- */
- if ( ( ltable->hash_bucket_count < (ltable->next_index >> 4) )
- && ( ltable->hash_bucket_count > 0 )
- && ( ( ltable->resizes % 10 ) == 0 )
- && ( ltable->bucket_walks > 1000*ltable->hash_bucket_count )
- ) {
- int old_size;
- int new_size;
- TableIndex *new_buckets;
- TableIndex *old_buckets;
- int bucket;
-
- /* Increase size of hash_buckets array, and rehash all elements */
-
- LOG3("Table resize", ltable->name, ltable->resizes);
-
- old_size = ltable->hash_bucket_count;
- old_buckets = ltable->hash_buckets;
- new_size = (ltable->next_index >> 3); /* 1/8 current used count */
- SANITY_CHECK(new_size > old_size);
- new_buckets = HPROF_MALLOC(new_size*(int)sizeof(TableIndex));
- (void)memset(new_buckets, 0, new_size*(int)sizeof(TableIndex));
- ltable->hash_bucket_count = new_size;
- ltable->hash_buckets = new_buckets;
-
- for ( bucket = 0 ; bucket < old_size ; bucket++ ) {
- TableIndex index;
-
- index = old_buckets[bucket];
- while ( index != 0 ) {
- TableElement *element;
- TableIndex next;
-
- element = (TableElement*)ELEMENT_PTR(ltable, index);
- next = element->next;
- element->next = 0;
- hash_in(ltable, index, element->hcode);
- index = next;
- }
- }
- HPROF_FREE(old_buckets);
-
- ltable->bucket_walks = 0;
- }
-}
-
-static void
-resize(LookupTable *ltable)
-{
- int old_size;
- int new_size;
- void *old_table;
- void *new_table;
- int nbytes;
- int obytes;
-
- LOG3("Table resize", ltable->name, ltable->resizes);
-
- /* Adjust increment on every resize
- * Minimum is 1/4 the size of the current table or 512.
- */
- old_size = ltable->table_size;
- if ( ltable->table_incr < (unsigned)(old_size >> 2) ) {
- ltable->table_incr = (old_size >> 2);
- }
- if ( ltable->table_incr < 512 ) {
- ltable->table_incr = 512;
- }
- new_size = old_size + ltable->table_incr;
-
- /* Basic table element array */
- obytes = old_size * ltable->elem_size;
- nbytes = new_size * ltable->elem_size;
- old_table = ltable->table;
- new_table = HPROF_MALLOC(nbytes);
- (void)memcpy(new_table, old_table, obytes);
- (void)memset(((char*)new_table)+obytes, 0, nbytes-obytes);
- ltable->table = new_table;
- ltable->table_size = new_size;
- HPROF_FREE(old_table);
-
- /* Then bit vector for freed entries */
- if ( ltable->freed_bv != NULL ) {
- void *old_bv;
- void *new_bv;
-
- obytes = BV_ELEMENT_COUNT(old_size)*(int)sizeof(BV_CHUNK_TYPE);
- nbytes = BV_ELEMENT_COUNT(new_size)*(int)sizeof(BV_CHUNK_TYPE);
- old_bv = ltable->freed_bv;
- new_bv = HPROF_MALLOC(nbytes);
- (void)memcpy(new_bv, old_bv, obytes);
- (void)memset(((char*)new_bv)+obytes, 0, nbytes-obytes);
- ltable->freed_bv = new_bv;
- HPROF_FREE(old_bv);
- }
-
- /* Check to see if the hash table needs resizing */
- resize_hash_buckets(ltable);
-
- ltable->resizes++;
-}
-
-static jboolean
-keys_equal(void *key_ptr1, void *key_ptr2, int key_len)
-{
- unsigned char * p1;
- unsigned char * p2;
- int i;
-
- if ( key_len == 0 ) {
- return JNI_TRUE;
- }
-
- /* We know these are aligned because we malloc'd them. */
-
- /* Compare word by word, then byte by byte */
- p1 = (unsigned char*)key_ptr1;
- p2 = (unsigned char*)key_ptr2;
- for ( i = 0 ; i < key_len-3 ; i += 4 ) {
- /*LINTED*/
- if ( *(unsigned*)(p1+i) != *(unsigned*)(p2+i) ) {
- return JNI_FALSE;
- }
- }
- for ( ; i < key_len ; i++ ) {
- if ( p1[i] != p2[i] ) {
- return JNI_FALSE;
- }
- }
- return JNI_TRUE;
-}
-
-static TableIndex
-find_entry(LookupTable *ltable, void *key_ptr, int key_len, HashCode hcode)
-{
- TableIndex index;
-
- HPROF_ASSERT(ltable!=NULL);
-
- index = 0;
- if ( ltable->hash_bucket_count > 0 ) {
- TableIndex bucket;
- TableIndex prev_index;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len>0);
- prev_index = 0;
- bucket = (hcode % ltable->hash_bucket_count);
- index = ltable->hash_buckets[bucket];
- while ( index != 0 ) {
- TableElement *element;
- TableElement *prev_element;
-
- element = (TableElement*)ELEMENT_PTR(ltable, index);
- if ( hcode == element->hcode &&
- key_len == element->key.len &&
- keys_equal(key_ptr, element->key.ptr, key_len) ) {
- /* Place this guy at the head of the bucket list */
- if ( prev_index != 0 ) {
- prev_element = (TableElement*)ELEMENT_PTR(ltable, prev_index);
- prev_element->next = element->next;
- element->next = ltable->hash_buckets[bucket];
- ltable->hash_buckets[bucket] = index;
- }
- break;
- }
- prev_index = index;
- index = element->next;
- ltable->bucket_walks++;
- }
- }
- return index;
-}
-
-static TableIndex
-setup_new_entry(LookupTable *ltable, void *key_ptr, int key_len, void *info_ptr)
-{
- TableIndex index;
- TableElement *element;
- void *info;
- void *dup_key;
-
- /* Assume we need new allocations for key and info */
- dup_key = NULL;
- info = NULL;
-
- /* Look for a freed element */
- index = 0;
- if ( ltable->freed_count > 0 ) {
- index = find_freed_entry(ltable);
- }
- if ( index != 0 ) {
- int old_key_len;
-
- /* Found a freed element, re-use what we can but clean it up. */
- element = (TableElement*)ELEMENT_PTR(ltable, index);
- dup_key = element->key.ptr;
- old_key_len = element->key.len;
- info = element->info;
- (void)memset(element, 0, ltable->elem_size);
-
- /* Toss the key space if size is too small to hold new key */
- if ( key_ptr != NULL ) {
- if ( old_key_len < key_len ) {
- /* This could leak space in the Blocks if keys are variable
- * in size AND the table does frees of elements.
- */
- dup_key = NULL;
- }
- }
- } else {
-
- /* Brand new table element */
- if ( ltable->next_index >= ltable->table_size ) {
- resize(ltable);
- }
- index = ltable->next_index++;
- element = (TableElement*)ELEMENT_PTR(ltable, index);
- }
-
- /* Setup info area */
- if ( ltable->info_size > 0 ) {
- if ( info == NULL ) {
- info = blocks_alloc(ltable->info_blocks, ltable->info_size);
- }
- if ( info_ptr==NULL ) {
- (void)memset(info, 0, ltable->info_size);
- } else {
- (void)memcpy(info, info_ptr, ltable->info_size);
- }
- }
-
- /* Setup key area if one was provided */
- if ( key_ptr != NULL ) {
- if ( dup_key == NULL ) {
- dup_key = blocks_alloc(ltable->key_blocks, key_len);
- }
- (void)memcpy(dup_key, key_ptr, key_len);
- }
-
- /* Fill in element */
- element->key.ptr = dup_key;
- element->key.len = key_len;
- element->info = info;
-
- return index;
-}
-
-LookupTable *
-table_initialize(const char *name, int size, int incr, int bucket_count,
- int info_size)
-{
- LookupTable * ltable;
- char lock_name[80];
- int elem_size;
- int key_size;
-
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(size>0);
- HPROF_ASSERT(incr>0);
- HPROF_ASSERT(bucket_count>=0);
- HPROF_ASSERT(info_size>=0);
-
- key_size = 1;
- ltable = (LookupTable *)HPROF_MALLOC((int)sizeof(LookupTable));
- (void)memset(ltable, 0, (int)sizeof(LookupTable));
-
- (void)strncpy(ltable->name, name, sizeof(ltable->name));
-
- elem_size = (int)sizeof(TableElement);
-
- ltable->next_index = 1; /* Never use index 0 */
- ltable->table_size = size;
- ltable->table_incr = incr;
- ltable->hash_bucket_count = bucket_count;
- ltable->elem_size = elem_size;
- ltable->info_size = info_size;
- if ( info_size > 0 ) {
- ltable->info_blocks = blocks_init(8, info_size, incr);
- }
- if ( key_size > 0 ) {
- ltable->key_blocks = blocks_init(8, key_size, incr);
- }
- ltable->table = HPROF_MALLOC(size * elem_size);
- (void)memset(ltable->table, 0, size * elem_size);
- if ( bucket_count > 0 ) {
- int nbytes;
-
- nbytes = (int)(bucket_count*sizeof(TableIndex));
- ltable->hash_buckets = (TableIndex*)HPROF_MALLOC(nbytes);
- (void)memset(ltable->hash_buckets, 0, nbytes);
- }
-
- (void)md_snprintf(lock_name, sizeof(lock_name),
- "HPROF %s table lock", name);
- lock_name[sizeof(lock_name)-1] = 0;
- ltable->lock = lock_create(lock_name);
- ltable->serial_num = gdata->table_serial_number_counter++;
- ltable->hare = (ltable->serial_num << 28);
-
- LOG3("Table initialized", ltable->name, ltable->table_size);
- return ltable;
-}
-
-int
-table_element_count(LookupTable *ltable)
-{
- int nelems;
-
- HPROF_ASSERT(ltable!=NULL);
-
- lock_enter(ltable->lock); {
- nelems = ltable->next_index-1;
- } lock_exit(ltable->lock);
-
- return nelems;
-}
-
-void
-table_free_entry(LookupTable *ltable, TableIndex index)
-{
- HPROF_ASSERT(ltable!=NULL);
- SANITY_CHECK_HARE(index, ltable->hare);
- index = SANITY_REMOVE_HARE(index);
- SANITY_CHECK_INDEX(ltable, index);
-
- lock_enter(ltable->lock); {
- HPROF_ASSERT(!is_freed_entry(ltable, index));
- free_entry(ltable, index);
- } lock_exit(ltable->lock);
-}
-
-void
-table_walk_items(LookupTable *ltable, LookupTableIterator func, void* arg)
-{
- if ( ltable == NULL || ltable->next_index <= 1 ) {
- return;
- }
- HPROF_ASSERT(func!=NULL);
-
- lock_enter(ltable->lock); {
- TableIndex index;
- int fcount;
-
- LOG3("table_walk_items() count+free", ltable->name, ltable->next_index);
- fcount = 0;
- for ( index = 1 ; index < ltable->next_index ; index++ ) {
- if ( ! is_freed_entry(ltable, index) ) {
- void *key_ptr;
- int key_len;
- void *info;
-
- get_key(ltable, index, &key_ptr, &key_len);
- if ( ltable->info_size == 0 ) {
- info = NULL;
- } else {
- info = get_info(ltable, index);
- }
- (*func)(SANITY_ADD_HARE(index, ltable->hare), key_ptr, key_len, info, arg);
- if ( is_freed_entry(ltable, index) ) {
- fcount++;
- }
- } else {
- fcount++;
- }
- }
- LOG3("table_walk_items() count-free", ltable->name, ltable->next_index);
- HPROF_ASSERT(fcount==ltable->freed_count);
- } lock_exit(ltable->lock);
-}
-
-void
-table_cleanup(LookupTable *ltable, LookupTableIterator func, void *arg)
-{
- if ( ltable == NULL ) {
- return;
- }
-
- if ( func != NULL ) {
- table_walk_items(ltable, func, arg);
- }
-
- lock_enter(ltable->lock); {
-
- HPROF_FREE(ltable->table);
- if ( ltable->hash_buckets != NULL ) {
- HPROF_FREE(ltable->hash_buckets);
- }
- if ( ltable->freed_bv != NULL ) {
- HPROF_FREE(ltable->freed_bv);
- }
- if ( ltable->info_blocks != NULL ) {
- blocks_term(ltable->info_blocks);
- ltable->info_blocks = NULL;
- }
- if ( ltable->key_blocks != NULL ) {
- blocks_term(ltable->key_blocks);
- ltable->key_blocks = NULL;
- }
-
- } lock_exit(ltable->lock);
-
- lock_destroy(ltable->lock);
- ltable->lock = NULL;
-
- HPROF_FREE(ltable);
- ltable = NULL;
-}
-
-TableIndex
-table_create_entry(LookupTable *ltable, void *key_ptr, int key_len, void *info_ptr)
-{
- TableIndex index;
- HashCode hcode;
-
- HPROF_ASSERT(ltable!=NULL);
-
- /* Create hash code if needed */
- hcode = 0;
- if ( ltable->hash_bucket_count > 0 ) {
- hcode = hashcode(key_ptr, key_len);
- }
-
- /* Create a new entry */
- lock_enter(ltable->lock); {
-
- /* Need to create a new entry */
- index = setup_new_entry(ltable, key_ptr, key_len, info_ptr);
-
- /* Add to hash table if we have one */
- if ( ltable->hash_bucket_count > 0 ) {
- hash_in(ltable, index, hcode);
- }
-
- } lock_exit(ltable->lock);
- return SANITY_ADD_HARE(index, ltable->hare);
-}
-
-TableIndex
-table_find_entry(LookupTable *ltable, void *key_ptr, int key_len)
-{
- TableIndex index;
- HashCode hcode;
-
- /* Create hash code if needed */
- hcode = 0;
- if ( ltable->hash_bucket_count > 0 ) {
- hcode = hashcode(key_ptr, key_len);
- }
-
- /* Look for element */
- lock_enter(ltable->lock); {
- index = find_entry(ltable, key_ptr, key_len, hcode);
- } lock_exit(ltable->lock);
-
- return index==0 ? index : SANITY_ADD_HARE(index, ltable->hare);
-}
-
-TableIndex
-table_find_or_create_entry(LookupTable *ltable, void *key_ptr, int key_len,
- jboolean *pnew_entry, void *info_ptr)
-{
- TableIndex index;
- HashCode hcode;
-
- /* Assume it is NOT a new entry for now */
- if ( pnew_entry ) {
- *pnew_entry = JNI_FALSE;
- }
-
- /* Create hash code if needed */
- hcode = 0;
- if ( ltable->hash_bucket_count > 0 ) {
- hcode = hashcode(key_ptr, key_len);
- }
-
- /* Look for element */
- index = 0;
- lock_enter(ltable->lock); {
- if ( ltable->hash_bucket_count > 0 ) {
- index = find_entry(ltable, key_ptr, key_len, hcode);
- }
- if ( index == 0 ) {
-
- /* Need to create a new entry */
- index = setup_new_entry(ltable, key_ptr, key_len, info_ptr);
-
- /* Add to hash table if we have one */
- if ( ltable->hash_bucket_count > 0 ) {
- hash_in(ltable, index, hcode);
- }
-
- if ( pnew_entry ) {
- *pnew_entry = JNI_TRUE;
- }
- }
- } lock_exit(ltable->lock);
-
- return SANITY_ADD_HARE(index, ltable->hare);
-}
-
-void *
-table_get_info(LookupTable *ltable, TableIndex index)
-{
- void *info;
-
- HPROF_ASSERT(ltable!=NULL);
- HPROF_ASSERT(ltable->info_size > 0);
- SANITY_CHECK_HARE(index, ltable->hare);
- index = SANITY_REMOVE_HARE(index);
- SANITY_CHECK_INDEX(ltable, index);
-
- lock_enter(ltable->lock); {
- HPROF_ASSERT(!is_freed_entry(ltable, index));
- info = get_info(ltable,index);
- } lock_exit(ltable->lock);
-
- return info;
-}
-
-void
-table_get_key(LookupTable *ltable, TableIndex index, void **pkey_ptr, int *pkey_len)
-{
- HPROF_ASSERT(ltable!=NULL);
- HPROF_ASSERT(pkey_ptr!=NULL);
- HPROF_ASSERT(pkey_len!=NULL);
- SANITY_CHECK_HARE(index, ltable->hare);
- HPROF_ASSERT(ltable->elem_size!=0);
- index = SANITY_REMOVE_HARE(index);
- SANITY_CHECK_INDEX(ltable, index);
-
- lock_enter(ltable->lock); {
- HPROF_ASSERT(!is_freed_entry(ltable, index));
- get_key(ltable, index, pkey_ptr, pkey_len);
- } lock_exit(ltable->lock);
-}
-
-void
-table_lock_enter(LookupTable *ltable)
-{
- lock_enter(ltable->lock);
-}
-
-void
-table_lock_exit(LookupTable *ltable)
-{
- lock_exit(ltable->lock);
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_table.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +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_TABLE_H
-#define HPROF_TABLE_H
-
-/* Key based generic lookup table */
-
-struct LookupTable;
-
-typedef void (*LookupTableIterator)
- (TableIndex, void *key_ptr, int key_len, void*, void*);
-
-struct LookupTable * table_initialize(const char *name, int size,
- int incr, int buckets, int esize);
-int table_element_count(struct LookupTable *ltable);
-TableIndex table_create_entry(struct LookupTable *ltable,
- void *key_ptr, int key_len, void *info_ptr);
-TableIndex table_find_entry(struct LookupTable *ltable,
- void *key_ptr, int key_len);
-TableIndex table_find_or_create_entry(struct LookupTable *ltable,
- void *key_ptr, int key_len,
- jboolean *pnew_entry, void *info_ptr);
-void table_free_entry(struct LookupTable *ltable,
- TableIndex index);
-void table_cleanup(struct LookupTable *ltable,
- LookupTableIterator func, void *arg);
-void table_walk_items(struct LookupTable *ltable,
- LookupTableIterator func, void *arg);
-void * table_get_info(struct LookupTable *ltable,
- TableIndex index);
-void table_get_key(struct LookupTable *ltable,
- TableIndex index, void **pkey_ptr,
- int *pkey_len);
-void table_lock_enter(struct LookupTable *ltable);
-void table_lock_exit(struct LookupTable *ltable);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_tag.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +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.
- */
-
-
-/* JVMTI tag definitions. */
-
-/*
- * JVMTI tags are jlongs (64 bits) and how the hprof information is
- * turned into a tag and/or extracted from a tag is here.
- *
- * Currently a special TAG_CHECK is placed in the high order 32 bits of
- * the tag as a check.
- *
- */
-
-#include "hprof.h"
-
-#define TAG_CHECK 0xfad4dead
-
-jlong
-tag_create(ObjectIndex object_index)
-{
- jlong tag;
-
- HPROF_ASSERT(object_index != 0);
- tag = TAG_CHECK;
- tag = (tag << 32) | object_index;
- return tag;
-}
-
-ObjectIndex
-tag_extract(jlong tag)
-{
- HPROF_ASSERT(tag != (jlong)0);
- if ( ((tag >> 32) & 0xFFFFFFFF) != TAG_CHECK) {
- HPROF_ERROR(JNI_TRUE, "JVMTI tag value is not 0 and missing TAG_CHECK");
- }
- return (ObjectIndex)(tag & 0xFFFFFFFF);
-}
-
-/* Tag a new jobject */
-void
-tag_new_object(jobject object, ObjectKind kind, SerialNumber thread_serial_num,
- jint size, SiteIndex site_index)
-{
- ObjectIndex object_index;
- jlong tag;
-
- HPROF_ASSERT(site_index!=0);
- /* New object for this site. */
- object_index = object_new(site_index, size, kind, thread_serial_num);
- /* Create and set the tag. */
- tag = tag_create(object_index);
- setTag(object, tag);
- LOG3("tag_new_object", "tag", (int)tag);
-}
-
-/* Tag a jclass jobject if it hasn't been tagged. */
-void
-tag_class(JNIEnv *env, jclass klass, ClassIndex cnum,
- SerialNumber thread_serial_num, SiteIndex site_index)
-{
- ObjectIndex object_index;
-
- /* If the ClassIndex has an ObjectIndex, then we have tagged it. */
- object_index = class_get_object_index(cnum);
-
- if ( object_index == 0 ) {
- jint size;
- jlong tag;
-
- HPROF_ASSERT(site_index!=0);
-
- /* If we don't know the size of a java.lang.Class object, get it */
- size = gdata->system_class_size;
- if ( size == 0 ) {
- size = (jint)getObjectSize(klass);
- gdata->system_class_size = size;
- }
-
- /* Tag this java.lang.Class object if it hasn't been already */
- tag = getTag(klass);
- if ( tag == (jlong)0 ) {
- /* New object for this site. */
- object_index = object_new(site_index, size, OBJECT_CLASS,
- thread_serial_num);
- /* Create and set the tag. */
- tag = tag_create(object_index);
- setTag(klass, tag);
- } else {
- /* Get the ObjectIndex from the tag. */
- object_index = tag_extract(tag);
- }
-
- /* Record this object index in the Class table */
- class_set_object_index(cnum, object_index);
- }
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_tag.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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_TAG_H
-#define HPROF_TAG_H
-
-jlong tag_create(ObjectIndex object_index);
-ObjectIndex tag_extract(jlong tag);
-
-void tag_new_object(jobject object, ObjectKind kind,
- SerialNumber thread_serial_num,
- jint size, SiteIndex site_index);
-void tag_class(JNIEnv *env, jclass klass, ClassIndex cnum,
- SerialNumber thread_serial_num, SiteIndex site_index);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_tls.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1190 +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"
-
-/* Thread Local Storage Table and method entry/exit handling. */
-
-/*
- * The tls table items have a key of it's serial number, but may be
- * searched via a walk of the table looking for a jthread match.
- * This isn't a performance
- * issue because the table index should normally be stored in the
- * Thread Local Storage for the thread. The table is only searched
- * when the jthread is seen before the Thread Local Storage is set
- * (e.g. before VM_INIT or the ThreadStart).
- * The key is only used when we need to lookup a tls table entry by
- * way of it's serial number, which should be unique per thread.
- *
- * Each active thread that we have seen should have a unique TlsIndex
- * which is an index into this table.
- *
- * For cpu=times, each table entry will have a stack to hold the method
- * that have been called, effectively keeping an active stack trace
- * for the thread. As each method exits, the statistics for the trace
- * associated with the current stack contents is updated.
- *
- * For cpu=samples, each thread is checked to see if it's runnable,
- * and not suspended, and has a stack associated with it, and then
- * that stack trace is updated with an additional 'hit'.
- *
- * This file also contains the dump logic for owned monitors, and for
- * threads.
- *
- */
-
-/*
- * Initial number of stack elements to track per thread. This
- * value should be set to a reasonable guess as to the number of
- * methods deep a thread calls. This stack doubles in size for each
- * reallocation and does not shrink.
- */
-
-#define INITIAL_THREAD_STACK_LIMIT 64
-
-typedef struct StackElement {
- FrameIndex frame_index; /* Frame (method/location(-1)) */
- jmethodID method; /* Method ID */
- jlong method_start_time; /* method start time */
- jlong time_in_callees; /* time in callees */
-} StackElement;
-
-typedef struct TlsInfo {
- jint sample_status; /* Thread status for cpu sampling */
- jboolean agent_thread; /* Is thread our own agent thread? */
- jthread globalref; /* Global reference for thread */
- Stack *stack; /* Stack of StackElements entry/exit */
- MonitorIndex monitor_index; /* last contended mon */
- jint tracker_status; /* If we are inside Tracker class */
- FrameIndex *frames_buffer; /* Buffer used to create TraceIndex */
- jvmtiFrameInfo *jframes_buffer; /* Buffer used to create TraceIndex */
- int buffer_depth; /* Frames allowed in buffer */
- TraceIndex last_trace; /* Last trace for this thread */
- ObjectIndex thread_object_index;/* If heap=dump */
- jlong monitor_start_time; /* Start time for monitor */
- jint in_heap_dump; /* If we are an object in the dump */
-} TlsInfo;
-
-typedef struct SearchData {
- JNIEnv *env;
- jthread thread;
- TlsIndex found;
-} SearchData;
-
-typedef struct IterateInfo {
- TlsIndex * ptls_index;
- jthread * pthreads;
- jint count;
-} IterateInfo;
-
-typedef struct ThreadList {
- jthread *threads;
- SerialNumber *serial_nums;
- TlsInfo **infos;
- jint count;
- JNIEnv *env;
-} ThreadList;
-
-typedef struct SampleData {
- ObjectIndex thread_object_index;
- jint sample_status;
-} SampleData;
-
-/* Private internal functions. */
-
-static SerialNumber
-get_key(TlsIndex index)
-{
- SerialNumber *pkey;
- int key_len;
-
- if ( index == 0 ) {
- return 0;
- }
- pkey = NULL;
- key_len = 0;
- table_get_key(gdata->tls_table, index, (void**)&pkey, &key_len);
- HPROF_ASSERT(pkey!=NULL);
- HPROF_ASSERT(key_len==(int)sizeof(SerialNumber));
- return *pkey;
-}
-
-static TlsInfo *
-get_info(TlsIndex index)
-{
- return (TlsInfo*)table_get_info(gdata->tls_table, index);
-}
-
-static void
-delete_globalref(JNIEnv *env, TlsInfo *info)
-{
- jthread ref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(info!=NULL);
- ref = info->globalref;
- info->globalref = NULL;
- if ( ref != NULL ) {
- deleteWeakGlobalReference(env, ref);
- }
-}
-
-static void
-clean_info(TlsInfo *info)
-{
- /* Free up any allocated space in this TlsInfo structure */
- if ( info->stack != NULL ) {
- stack_term(info->stack);
- info->stack = NULL;
- }
- if ( info->frames_buffer != NULL ) {
- HPROF_FREE(info->frames_buffer);
- info->frames_buffer = NULL;
- }
- if ( info->jframes_buffer != NULL ) {
- HPROF_FREE(info->jframes_buffer);
- info->jframes_buffer = NULL;
- }
-}
-
-static void
-cleanup_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
- TlsInfo * info;
-
- info = (TlsInfo*)info_ptr;
- clean_info(info);
-}
-
-static void
-delete_ref_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
- delete_globalref((JNIEnv*)arg, (TlsInfo*)info_ptr);
-}
-
-static void
-list_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
- TlsInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
-
- info = (TlsInfo*)info_ptr;
- debug_message( "Tls 0x%08x: SN=%u, sample_status=%d, agent=%d, "
- "thread=%p, monitor=0x%08x, "
- "tracker_status=%d\n",
- index,
- *(SerialNumber*)key_ptr,
- info->sample_status,
- info->agent_thread,
- (void*)info->globalref,
- info->monitor_index,
- info->tracker_status);
-}
-
-static void
-search_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
- TlsInfo *info;
- SearchData *data;
- jobject lref;
-
- HPROF_ASSERT(info_ptr!=NULL);
- HPROF_ASSERT(arg!=NULL);
- info = (TlsInfo*)info_ptr;
- data = (SearchData*)arg;
- lref = newLocalReference(data->env, info->globalref);
- if ( lref != NULL ) {
- if ( isSameObject(data->env, data->thread, lref) ) {
- HPROF_ASSERT(data->found==0); /* Did we find more than one? */
- data->found = index;
- }
- deleteLocalReference(data->env, lref);
- }
-}
-
-static TlsIndex
-search(JNIEnv *env, jthread thread)
-{
- SearchData data;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(thread!=NULL);
-
- data.env = env;
- data.thread = thread;
- data.found = 0;
- table_walk_items(gdata->tls_table, &search_item, (void*)&data);
- return data.found;
-}
-
-static void
-garbage_collect_item(TableIndex index, void *key_ptr, int key_len,
- void *info_ptr, void *arg)
-{
- TlsInfo *info;
- JNIEnv *env;
- jobject lref;
-
- HPROF_ASSERT(info_ptr!=NULL);
- HPROF_ASSERT(arg!=NULL);
- info = (TlsInfo*)info_ptr;
- env = (JNIEnv*)arg;
- lref = newLocalReference(env, info->globalref);
- if ( lref == NULL ) {
- delete_globalref(env, info);
- clean_info(info);
- table_free_entry(gdata->tls_table, index);
- } else {
- deleteLocalReference(env, lref);
- }
-}
-
-void
-tls_garbage_collect(JNIEnv *env)
-{
- HPROF_ASSERT(env!=NULL);
- rawMonitorEnter(gdata->data_access_lock); {
- table_walk_items(gdata->tls_table, &garbage_collect_item, (void*)env);
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-static void
-sum_sample_status_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TlsInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
- info = (TlsInfo*)info_ptr;
- if ( !info->agent_thread ) {
- (*(jint*)arg) += info->sample_status;
- }
-}
-
-static void
-setup_trace_buffers(TlsInfo *info, int max_depth)
-{
- int nbytes;
- int max_frames;
-
- if ( info->frames_buffer != NULL && info->buffer_depth >= max_depth ) {
- return;
- }
- if ( info->frames_buffer != NULL ) {
- HPROF_FREE(info->frames_buffer);
- }
- if ( info->jframes_buffer != NULL ) {
- HPROF_FREE(info->jframes_buffer);
- }
- info->buffer_depth = max_depth;
- max_frames = max_depth + 4; /* Allow for BCI & <init> */
- nbytes = (int)sizeof(FrameIndex)*(max_frames+1);
- info->frames_buffer = HPROF_MALLOC(nbytes);
- nbytes = (int)sizeof(jvmtiFrameInfo)*(max_frames+1);
- info->jframes_buffer = HPROF_MALLOC(nbytes);
-}
-
-static TraceIndex
-get_trace(jthread thread, SerialNumber thread_serial_num,
- int depth, jboolean skip_init,
- FrameIndex *frames_buffer, jvmtiFrameInfo *jframes_buffer)
-{
- TraceIndex trace_index;
-
- trace_index = gdata->system_trace_index;
- if ( thread != NULL ) {
- trace_index = trace_get_current(thread,
- thread_serial_num, depth, skip_init,
- frames_buffer, jframes_buffer);
- }
- return trace_index;
-}
-
-/* Find thread with certain object index */
-static void
-sample_setter(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TlsInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
-
- info = (TlsInfo*)info_ptr;
- if ( info->globalref != NULL && !info->agent_thread ) {
- SampleData *data;
-
- data = (SampleData*)arg;
- if ( data->thread_object_index == info->thread_object_index ) {
- info->sample_status = data->sample_status;
- }
- }
-}
-
-/* Get various lists on known threads */
-static void
-get_thread_list(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- SerialNumber thread_serial_num;
- TlsInfo *info;
- ThreadList *list;
- jthread thread;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(info_ptr!=NULL);
-
- thread_serial_num = *(SerialNumber*)key_ptr;
- info = (TlsInfo*)info_ptr;
- list = (ThreadList*)arg;
- thread = newLocalReference(list->env, info->globalref);
- if ( thread != NULL && info->sample_status != 0 && !info->agent_thread ) {
- if ( list->infos != NULL ) {
- list->infos[list->count] = info;
- }
- if ( list->serial_nums != NULL ) {
- list->serial_nums[list->count] = thread_serial_num;
- }
- list->threads[list->count] = thread;
- list->count++;
- /* Local reference gets freed by caller */
- } else {
- /* If we don't use the local reference, delete it now */
- if ( thread != NULL ) {
- deleteLocalReference(list->env, thread);
- }
- }
-}
-
-static void
-adjust_stats(jlong total_time, jlong self_time, TraceIndex trace_index,
- StackElement *parent)
-{
- if ( total_time > 0 && parent != NULL ) { /* if a caller exists */
- parent->time_in_callees += total_time;
- }
- trace_increment_cost(trace_index, 1, self_time, total_time);
-}
-
-static void
-push_method(Stack *stack, jlong method_start_time, jmethodID method)
-{
- StackElement new_element;
- FrameIndex frame_index;
-
- HPROF_ASSERT(method!=NULL);
- HPROF_ASSERT(stack!=NULL);
-
- frame_index = frame_find_or_create(method, -1);
- HPROF_ASSERT(frame_index != 0);
- new_element.frame_index = frame_index;
- new_element.method = method;
- new_element.method_start_time= method_start_time;
- new_element.time_in_callees = (jlong)0;
- stack_push(stack, &new_element);
-}
-
-static Stack *
-insure_method_on_stack(jthread thread, TlsInfo *info, jlong current_time,
- FrameIndex frame_index, jmethodID method)
-{
- StackElement element;
- void *p;
- int depth;
- int count;
- int fcount;
- int i;
- Stack *new_stack;
- Stack *stack;
-
- stack = info->stack;
-
- HPROF_ASSERT(method!=NULL);
-
- /* If this method is on the stack, just return */
- depth = stack_depth(stack);
- p = stack_top(stack);
- if ( p != NULL ) {
- element = *(StackElement*)p;
- if ( element.frame_index == frame_index ) {
- return stack;
- }
- }
- for ( i = 0 ; i < depth ; i++ ) {
- p = stack_element(stack, i);
- element = *(StackElement*)p;
- if ( element.frame_index == frame_index ) {
- return stack;
- }
- }
-
- /* It wasn't found, create a new stack */
- getFrameCount(thread, &count);
- if ( count <= 0 ) {
- HPROF_ERROR(JNI_FALSE, "no frames, method can't be on stack");
- }
- setup_trace_buffers(info, count);
- getStackTrace(thread, info->jframes_buffer, count, &fcount);
- HPROF_ASSERT(count==fcount);
-
- /* Create a new stack */
- new_stack = stack_init(INITIAL_THREAD_STACK_LIMIT,
- INITIAL_THREAD_STACK_LIMIT,
- (int)sizeof(StackElement));
- for ( i = count-1; i >= 0 ; i-- ) {
- push_method(new_stack, current_time, info->jframes_buffer[i].method);
- }
- if ( depth > 0 ) {
- for ( i = depth-1 ; i >= 0; i-- ) {
- stack_push(new_stack, stack_element(stack, i));
- }
- }
- stack_term(stack);
- return new_stack;
-}
-
-static void
-pop_method(TlsIndex index, jlong current_time, jmethodID method, FrameIndex frame_index)
-{
- SerialNumber thread_serial_num;
- TlsInfo * info;
- StackElement element;
- void *p;
- int depth;
- int trace_depth;
- jlong total_time;
- jlong self_time;
- int i;
- TraceIndex trace_index;
-
- HPROF_ASSERT(method!=NULL);
- HPROF_ASSERT(frame_index!=0);
-
- thread_serial_num = get_key(index);
- info = get_info(index);
- HPROF_ASSERT(info!=NULL);
- HPROF_ASSERT(info->stack!=NULL);
- depth = stack_depth(info->stack);
- p = stack_pop(info->stack);
- if (p == NULL) {
- HPROF_ERROR(JNI_FALSE, "method return tracked, but stack is empty");
- return;
- }
- element = *(StackElement*)p;
- HPROF_ASSERT(element.frame_index!=0);
-
- /* The depth of frames we should keep track for reporting */
- if (gdata->prof_trace_depth > depth) {
- trace_depth = depth;
- } else {
- trace_depth = gdata->prof_trace_depth;
- }
-
- /* Create a trace entry */
- HPROF_ASSERT(info->frames_buffer!=NULL);
- HPROF_ASSERT(info->jframes_buffer!=NULL);
- setup_trace_buffers(info, trace_depth);
- info->frames_buffer[0] = element.frame_index;
- for (i = 1; i < trace_depth; i++) {
- StackElement e;
-
- e = *(StackElement*)stack_element(info->stack, (depth - i) - 1);
- info->frames_buffer[i] = e.frame_index;
- HPROF_ASSERT(e.frame_index!=0);
- }
- trace_index = trace_find_or_create(thread_serial_num,
- trace_depth, info->frames_buffer, info->jframes_buffer);
-
- /* Calculate time spent */
- total_time = current_time - element.method_start_time;
- if ( total_time < 0 ) {
- total_time = 0;
- self_time = 0;
- } else {
- self_time = total_time - element.time_in_callees;
- }
-
- /* Update stats */
- p = stack_top(info->stack);
- if ( p != NULL ) {
- adjust_stats(total_time, self_time, trace_index, (StackElement*)p);
- } else {
- adjust_stats(total_time, self_time, trace_index, NULL);
- }
-}
-
-static void
-dump_thread_state(TlsIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- SerialNumber thread_serial_num;
- TlsInfo *info;
- jthread thread;
- JNIEnv *env;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(info_ptr!=NULL);
- env = (JNIEnv*)arg;
- thread_serial_num = *(SerialNumber*)key_ptr;
- info = (TlsInfo*)info_ptr;
- thread = newLocalReference(env, info->globalref);
- if ( thread != NULL ) {
- jint threadState;
- SerialNumber trace_serial_num;
-
- getThreadState(thread, &threadState);
- /* A 0 trace at this time means the thread is in unknown territory.
- * The trace serial number MUST be a valid serial number, so we use
- * the system trace (empty) just so it has a valid trace.
- */
- if ( info->last_trace == 0 ) {
- trace_serial_num = trace_get_serial_number(gdata->system_trace_index);
- } else {
- trace_serial_num = trace_get_serial_number(info->last_trace);
- }
- io_write_monitor_dump_thread_state(thread_serial_num,
- trace_serial_num, threadState);
- deleteLocalReference(env, thread);
- }
-}
-
-static SerialNumber
-get_serial_number(JNIEnv *env, jthread thread)
-{
- TlsIndex index;
-
- if ( thread == NULL ) {
- return gdata->unknown_thread_serial_num;
- }
- HPROF_ASSERT(env!=NULL);
- index = tls_find_or_create(env, thread);
- return get_key(index);
-}
-
-static void
-dump_monitor_state(TlsIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TlsInfo *info;
- jthread thread;
- JNIEnv *env;
-
- HPROF_ASSERT(info_ptr!=NULL);
- env = (JNIEnv*)arg;
- info = (TlsInfo*)info_ptr;
- thread = newLocalReference(env, info->globalref);
- if ( thread != NULL ) {
- jobject *objects;
- jint ocount;
- int i;
-
- getOwnedMonitorInfo(thread, &objects, &ocount);
- if ( ocount > 0 ) {
- for ( i = 0 ; i < ocount ; i++ ) {
- jvmtiMonitorUsage usage;
- SerialNumber *waiter_nums;
- SerialNumber *notify_waiter_nums;
- int t;
- char * sig;
-
- WITH_LOCAL_REFS(env, 1) {
- jclass clazz;
-
- clazz = getObjectClass(env, objects[i]);
- getClassSignature(clazz, &sig, NULL);
- } END_WITH_LOCAL_REFS;
-
- getObjectMonitorUsage(objects[i], &usage);
- waiter_nums = HPROF_MALLOC(usage.waiter_count*
- (int)sizeof(SerialNumber)+1);
- for ( t = 0 ; t < usage.waiter_count ; t++ ) {
- waiter_nums[t] =
- get_serial_number(env, usage.waiters[t]);
- }
- notify_waiter_nums = HPROF_MALLOC(usage.notify_waiter_count*
- (int)sizeof(SerialNumber)+1);
- for ( t = 0 ; t < usage.notify_waiter_count ; t++ ) {
- notify_waiter_nums[t] =
- get_serial_number(env, usage.notify_waiters[t]);
- }
- io_write_monitor_dump_state(sig,
- get_serial_number(env, usage.owner),
- usage.entry_count,
- waiter_nums, usage.waiter_count,
- notify_waiter_nums, usage.notify_waiter_count);
- jvmtiDeallocate(sig);
- jvmtiDeallocate(usage.waiters);
- jvmtiDeallocate(usage.notify_waiters);
- HPROF_FREE(waiter_nums);
- HPROF_FREE(notify_waiter_nums);
- }
- }
- jvmtiDeallocate(objects);
- deleteLocalReference(env, thread);
- }
-}
-
-static jlong
-monitor_time(void)
-{
- jlong mtime;
-
- mtime = md_get_timemillis(); /* gettimeofday() */
- return mtime;
-}
-
-static jlong
-method_time(void)
-{
- jlong method_time;
-
- method_time = md_get_thread_cpu_timemillis(); /* thread CPU time */
- return method_time;
-}
-
-/* External interfaces */
-
-TlsIndex
-tls_find_or_create(JNIEnv *env, jthread thread)
-{
- SerialNumber thread_serial_num;
- static TlsInfo empty_info;
- TlsInfo info;
- TlsIndex index;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(thread!=NULL);
-
- /*LINTED*/
- index = (TlsIndex)(ptrdiff_t)getThreadLocalStorage(thread);
- if ( index != 0 ) {
- HPROF_ASSERT(isSameObject(env, thread, get_info(index)->globalref));
- return index;
- }
- index = search(env, thread);
- if ( index != 0 ) {
- setThreadLocalStorage(thread, (void*)(ptrdiff_t)index);
- return index;
- }
- thread_serial_num = gdata->thread_serial_number_counter++;
- info = empty_info;
- info.monitor_index = 0;
- info.sample_status = 1;
- info.agent_thread = JNI_FALSE;
- info.stack = stack_init(INITIAL_THREAD_STACK_LIMIT,
- INITIAL_THREAD_STACK_LIMIT,
- (int)sizeof(StackElement));
- setup_trace_buffers(&info, gdata->max_trace_depth);
- info.globalref = newWeakGlobalReference(env, thread);
- index = table_create_entry(gdata->tls_table, &thread_serial_num, (int)sizeof(SerialNumber), (void*)&info);
- setThreadLocalStorage(thread, (void*)(ptrdiff_t)index);
- HPROF_ASSERT(search(env,thread)==index);
- return index;
-}
-
-/* Mark a new or existing entry as being an agent thread */
-void
-tls_agent_thread(JNIEnv *env, jthread thread)
-{
- TlsIndex index;
- TlsInfo *info;
-
- index = tls_find_or_create(env, thread);
- info = get_info(index);
- info->agent_thread = JNI_TRUE;
-}
-
-void
-tls_init(void)
-{
- gdata->tls_table = table_initialize("TLS",
- 16, 16, 16, (int)sizeof(TlsInfo));
-}
-
-void
-tls_list(void)
-{
- debug_message(
- "--------------------- TLS Table ------------------------\n");
- table_walk_items(gdata->tls_table, &list_item, NULL);
- debug_message(
- "----------------------------------------------------------\n");
-}
-
-jint
-tls_sum_sample_status(void)
-{
- jint sample_status_total;
-
- sample_status_total = 0;
- table_walk_items(gdata->tls_table, &sum_sample_status_item, (void*)&sample_status_total);
- return sample_status_total;
-}
-
-void
-tls_set_sample_status(ObjectIndex object_index, jint sample_status)
-{
- SampleData data;
-
- data.thread_object_index = object_index;
- data.sample_status = sample_status;
- table_walk_items(gdata->tls_table, &sample_setter, (void*)&data);
-}
-
-jint
-tls_get_tracker_status(JNIEnv *env, jthread thread, jboolean skip_init,
- jint **ppstatus, TlsIndex* pindex,
- SerialNumber *pthread_serial_num, TraceIndex *ptrace_index)
-{
- TlsInfo *info;
- TlsIndex index;
- SerialNumber thread_serial_num;
- jint status;
-
- index = tls_find_or_create(env, thread);
- info = get_info(index);
- *ppstatus = &(info->tracker_status);
- status = **ppstatus;
- thread_serial_num = get_key(index);
-
- if ( pindex != NULL ) {
- *pindex = index;
- }
- if ( status != 0 ) {
- return status;
- }
- if ( ptrace_index != NULL ) {
- setup_trace_buffers(info, gdata->max_trace_depth);
- *ptrace_index = get_trace(thread, thread_serial_num,
- gdata->max_trace_depth, skip_init,
- info->frames_buffer, info->jframes_buffer);
- }
- if ( pthread_serial_num != NULL ) {
- *pthread_serial_num = thread_serial_num;
- }
- return status;
-}
-
-MonitorIndex
-tls_get_monitor(TlsIndex index)
-{
- TlsInfo *info;
-
- info = get_info(index);
- return info->monitor_index;
-}
-
-void
-tls_set_thread_object_index(TlsIndex index, ObjectIndex thread_object_index)
-{
- TlsInfo *info;
-
- info = get_info(index);
- info->thread_object_index = thread_object_index;
-}
-
-SerialNumber
-tls_get_thread_serial_number(TlsIndex index)
-{
- return get_key(index);
-}
-
-void
-tls_set_monitor(TlsIndex index, MonitorIndex monitor_index)
-{
- TlsInfo *info;
-
- info = get_info(index);
- info->monitor_index = monitor_index;
-}
-
-void
-tls_cleanup(void)
-{
- table_cleanup(gdata->tls_table, &cleanup_item, NULL);
- gdata->tls_table = NULL;
-}
-
-void
-tls_delete_global_references(JNIEnv *env)
-{
- table_walk_items(gdata->tls_table, &delete_ref_item, (void*)env);
-}
-
-void
-tls_thread_ended(JNIEnv *env, TlsIndex index)
-{
- HPROF_ASSERT(env!=NULL);
-
- /* Sample thread stack for last time, do NOT free the entry yet. */
- table_lock_enter(gdata->tls_table); {
- SerialNumber thread_serial_num;
- TlsInfo *info;
- jthread thread;
-
- thread_serial_num = get_key(index);
- info = get_info(index);
- thread = newLocalReference(env, info->globalref);
- if (gdata->heap_dump && thread!=NULL) {
- setup_trace_buffers(info, gdata->max_trace_depth);
- info->last_trace = get_trace(thread, thread_serial_num,
- gdata->max_trace_depth, JNI_FALSE,
- info->frames_buffer, info->jframes_buffer);
- }
- if ( thread != NULL ) {
- deleteLocalReference(env, thread);
- }
- } table_lock_exit(gdata->tls_table);
-
-}
-
-/* Sample ALL threads and update the trace costs */
-void
-tls_sample_all_threads(JNIEnv *env)
-{
- ThreadList list;
- jthread *threads;
- SerialNumber *serial_nums;
-
- table_lock_enter(gdata->tls_table); {
- int max_count;
- int nbytes;
- int i;
-
- /* Get buffers to hold thread list and serial number list */
- max_count = table_element_count(gdata->tls_table);
- nbytes = (int)sizeof(jthread)*max_count;
- threads = (jthread*)HPROF_MALLOC(nbytes);
- nbytes = (int)sizeof(SerialNumber)*max_count;
- serial_nums = (SerialNumber*)HPROF_MALLOC(nbytes);
-
- /* Get list of threads and serial numbers */
- list.threads = threads;
- list.infos = NULL;
- list.serial_nums = serial_nums;
- list.count = 0;
- list.env = env;
- table_walk_items(gdata->tls_table, &get_thread_list, (void*)&list);
-
- /* Increment the cost on the traces for these threads */
- trace_increment_all_sample_costs(list.count, threads, serial_nums,
- gdata->max_trace_depth, JNI_FALSE);
-
- /* Loop over local refs and free them */
- for ( i = 0 ; i < list.count ; i++ ) {
- if ( threads[i] != NULL ) {
- deleteLocalReference(env, threads[i]);
- }
- }
-
- } table_lock_exit(gdata->tls_table);
-
- /* Free up allocated space */
- HPROF_FREE(threads);
- HPROF_FREE(serial_nums);
-
-}
-
-void
-tls_push_method(TlsIndex index, jmethodID method)
-{
- jlong method_start_time;
- TlsInfo *info;
-
- HPROF_ASSERT(method!=NULL);
- info = get_info(index);
- HPROF_ASSERT(info!=NULL);
- method_start_time = method_time();
- HPROF_ASSERT(info->stack!=NULL);
- push_method(info->stack, method_start_time, method);
-}
-
-void
-tls_pop_exception_catch(TlsIndex index, jthread thread, jmethodID method)
-{
- TlsInfo *info;
- StackElement element;
- void *p;
- FrameIndex frame_index;
- jlong current_time;
-
- HPROF_ASSERT(method!=NULL);
- frame_index = frame_find_or_create(method, -1);
- HPROF_ASSERT(frame_index != 0);
-
- info = get_info(index);
-
- HPROF_ASSERT(info!=NULL);
- HPROF_ASSERT(info->stack!=NULL);
- HPROF_ASSERT(frame_index!=0);
- current_time = method_time();
- info->stack = insure_method_on_stack(thread, info, current_time,
- frame_index, method);
- p = stack_top(info->stack);
- if (p == NULL) {
- HPROF_ERROR(JNI_FALSE, "expection pop, nothing on stack");
- return;
- }
- element = *(StackElement*)p;
- HPROF_ASSERT(element.frame_index!=0);
- while ( element.frame_index != frame_index ) {
- pop_method(index, current_time, element.method, frame_index);
- p = stack_top(info->stack);
- if ( p == NULL ) {
- break;
- }
- element = *(StackElement*)p;
- }
- if (p == NULL) {
- HPROF_ERROR(JNI_FALSE, "exception pop stack empty");
- }
-}
-
-void
-tls_pop_method(TlsIndex index, jthread thread, jmethodID method)
-{
- TlsInfo *info;
- StackElement element;
- void *p;
- FrameIndex frame_index;
- jlong current_time;
-
- HPROF_ASSERT(method!=NULL);
- frame_index = frame_find_or_create(method, -1);
- HPROF_ASSERT(frame_index != 0);
-
- info = get_info(index);
- HPROF_ASSERT(info!=NULL);
- HPROF_ASSERT(info->stack!=NULL);
- current_time = method_time();
- HPROF_ASSERT(frame_index!=0);
- info->stack = insure_method_on_stack(thread, info, current_time,
- frame_index, method);
- p = stack_top(info->stack);
- HPROF_ASSERT(p!=NULL);
- element = *(StackElement*)p;
- while ( element.frame_index != frame_index ) {
- pop_method(index, current_time, element.method, frame_index);
- p = stack_top(info->stack);
- if ( p == NULL ) {
- break;
- }
- element = *(StackElement*)p;
- }
- pop_method(index, current_time, method, frame_index);
-}
-
-/* For all TLS entries, update the last_trace on all threads */
-static void
-update_all_last_traces(JNIEnv *env)
-{
- jthread *threads;
- TlsInfo **infos;
- SerialNumber *serial_nums;
- TraceIndex *traces;
-
- if ( gdata->max_trace_depth == 0 ) {
- return;
- }
-
- table_lock_enter(gdata->tls_table); {
-
- ThreadList list;
- int max_count;
- int nbytes;
- int i;
-
- /* Get buffers to hold thread list and serial number list */
- max_count = table_element_count(gdata->tls_table);
- nbytes = (int)sizeof(jthread)*max_count;
- threads = (jthread*)HPROF_MALLOC(nbytes);
- nbytes = (int)sizeof(SerialNumber)*max_count;
- serial_nums = (SerialNumber*)HPROF_MALLOC(nbytes);
- nbytes = (int)sizeof(TlsInfo*)*max_count;
- infos = (TlsInfo**)HPROF_MALLOC(nbytes);
-
- /* Get list of threads, serial numbers, and info pointers */
- list.threads = threads;
- list.serial_nums = serial_nums;
- list.infos = infos;
- list.count = 0;
- list.env = env;
- table_walk_items(gdata->tls_table, &get_thread_list, (void*)&list);
-
- /* Get all stack trace index's for all these threadss */
- nbytes = (int)sizeof(TraceIndex)*max_count;
- traces = (TraceIndex*)HPROF_MALLOC(nbytes);
- trace_get_all_current(list.count, threads, serial_nums,
- gdata->max_trace_depth, JNI_FALSE,
- traces, JNI_TRUE);
-
- /* Loop over traces and update last_trace's */
- for ( i = 0 ; i < list.count ; i++ ) {
- if ( threads[i] != NULL ) {
- deleteLocalReference(env, threads[i]);
- }
- infos[i]->last_trace = traces[i];
- }
-
- } table_lock_exit(gdata->tls_table);
-
- /* Free up all allocated space */
- HPROF_FREE(threads);
- HPROF_FREE(serial_nums);
- HPROF_FREE(infos);
- HPROF_FREE(traces);
-
-}
-
-void
-tls_dump_traces(JNIEnv *env)
-{
- rawMonitorEnter(gdata->data_access_lock); {
- update_all_last_traces(env);
- trace_output_unmarked(env);
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-void
-tls_dump_monitor_state(JNIEnv *env)
-{
- HPROF_ASSERT(env!=NULL);
-
- rawMonitorEnter(gdata->data_access_lock); {
- tls_dump_traces(env);
- io_write_monitor_dump_header();
- table_walk_items(gdata->tls_table, &dump_thread_state, (void*)env);
- table_walk_items(gdata->tls_table, &dump_monitor_state, (void*)env);
- io_write_monitor_dump_footer();
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-void
-tls_monitor_start_timer(TlsIndex index)
-{
- TlsInfo *info;
-
- info = get_info(index);
- HPROF_ASSERT(info!=NULL);
- HPROF_ASSERT(info->globalref!=NULL);
- info->monitor_start_time = monitor_time();
-}
-
-jlong
-tls_monitor_stop_timer(TlsIndex index)
-{
- TlsInfo *info;
- jlong t;
-
- info = get_info(index);
- HPROF_ASSERT(info!=NULL);
- t = monitor_time() - info->monitor_start_time;
- info->monitor_start_time = 0;
- return t;
-}
-
-TraceIndex
-tls_get_trace(TlsIndex index, JNIEnv *env, int depth, jboolean skip_init)
-{
- SerialNumber thread_serial_num;
- TraceIndex trace_index;
- TlsInfo *info;
- jthread thread;
-
- thread_serial_num = get_key(index);
- info = get_info(index);
- HPROF_ASSERT(info!=NULL);
- setup_trace_buffers(info, depth);
- thread = newLocalReference(env, info->globalref);
- if ( thread != NULL ) {
- trace_index = get_trace(thread, thread_serial_num, depth, skip_init,
- info->frames_buffer, info->jframes_buffer);
- deleteLocalReference(env, thread);
- } else {
- trace_index = gdata->system_trace_index;
- }
- return trace_index;
-}
-
-void
-tls_set_in_heap_dump(TlsIndex index, jint in_heap_dump)
-{
- TlsInfo *info;
-
- info = get_info(index);
- info->in_heap_dump = in_heap_dump;
-}
-
-jint
-tls_get_in_heap_dump(TlsIndex index)
-{
- TlsInfo *info;
-
- info = get_info(index);
- return info->in_heap_dump;
-}
-
-static void
-clean_in_heap_dump(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TlsInfo *info;
-
- HPROF_ASSERT(info_ptr!=NULL);
- info = (TlsInfo*)info_ptr;
- info->in_heap_dump = 0;
-}
-
-void
-tls_clear_in_heap_dump(void)
-{
- table_walk_items(gdata->tls_table, &clean_in_heap_dump, NULL);
-}
-
-TlsIndex
-tls_find(SerialNumber thread_serial_num)
-{
- TlsIndex index;
-
- if ( thread_serial_num == 0 ) {
- return 0;
- }
- index = table_find_entry(gdata->tls_table,
- (void*)&thread_serial_num, (int)sizeof(SerialNumber));
- return index;
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_tls.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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_TLS_H
-#define HPROF_TLS_H
-
-void tls_init(void);
-TlsIndex tls_find_or_create(JNIEnv *env, jthread thread);
-void tls_agent_thread(JNIEnv *env, jthread thread);
-SerialNumber tls_get_thread_serial_number(TlsIndex index);
-void tls_list(void);
-void tls_delete_global_references(JNIEnv *env);
-void tls_garbage_collect(JNIEnv *env);
-void tls_cleanup(void);
-void tls_thread_ended(JNIEnv *env, TlsIndex index);
-void tls_sample_all_threads(JNIEnv *env);
-
-MonitorIndex tls_get_monitor(TlsIndex index);
-void tls_set_monitor(TlsIndex index, MonitorIndex monitor_index);
-
-void tls_set_thread_object_index(TlsIndex index,
- ObjectIndex thread_object_index);
-
-jint tls_get_tracker_status(JNIEnv *env, jthread thread,
- jboolean skip_init, jint **ppstatus, TlsIndex* pindex,
- SerialNumber *pthread_serial_num,
- TraceIndex *ptrace_index);
-
-void tls_set_sample_status(ObjectIndex object_index, jint sample_status);
-jint tls_sum_sample_status(void);
-
-void tls_dump_traces(JNIEnv *env);
-
-void tls_monitor_start_timer(TlsIndex index);
-jlong tls_monitor_stop_timer(TlsIndex index);
-
-void tls_dump_monitor_state(JNIEnv *env);
-
-void tls_push_method(TlsIndex index, jmethodID method);
-void tls_pop_method(TlsIndex index, jthread thread, jmethodID method);
-void tls_pop_exception_catch(TlsIndex index, jthread thread, jmethodID method);
-
-TraceIndex tls_get_trace(TlsIndex index, JNIEnv *env,
- int depth, jboolean skip_init);
-
-void tls_set_in_heap_dump(TlsIndex index, jint in_heap_dump);
-jint tls_get_in_heap_dump(TlsIndex index);
-void tls_clear_in_heap_dump(void);
-
-TlsIndex tls_find(SerialNumber thread_serial_num);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_trace.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,869 +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.
- */
-
-
-/* Trace table. */
-
-/*
- * A trace is an optional thread serial number plus N frames.
- *
- * The thread serial number is added to the key only if the user asks for
- * threads in traces, which will cause many more traces to be created.
- * Without it all threads share the traces.
- *
- * This is a variable length Key, depending on the number of frames.
- * The frames are FrameIndex values into the frame table.
- *
- * It is important that the thread serial number is used and not the
- * TlsIndex, threads come and go, and TlsIndex values are re-used
- * but the thread serial number is unique per thread.
- *
- * The cpu=times and cpu=samples dumps rely heavily on traces, the trace
- * dump preceeds the cpu information and uses the trace information.
- * Depending on the cpu= request, different sorts are applied to the
- * traces that are dumped.
- *
- */
-
-#include "hprof.h"
-
-typedef struct TraceKey {
- SerialNumber thread_serial_num; /* Thread serial number */
- short n_frames; /* Number of frames that follow. */
- jvmtiPhase phase : 8; /* Makes some traces unique */
- FrameIndex frames[1]; /* Variable length */
-} TraceKey;
-
-typedef struct TraceInfo {
- SerialNumber serial_num; /* Trace serial number */
- jint num_hits; /* Number of hits this trace has */
- jlong total_cost; /* Total cost associated with trace */
- jlong self_cost; /* Total cost without children cost */
- jint status; /* Status of dump of trace */
-} TraceInfo;
-
-typedef struct IterateInfo {
- TraceIndex* traces;
- int count;
- jlong grand_total_cost;
-} IterateInfo;
-
-/* Private internal functions. */
-
-static TraceKey*
-get_pkey(TraceIndex index)
-{
- void * pkey;
- int key_len;
-
- table_get_key(gdata->trace_table, index, &pkey, &key_len);
- HPROF_ASSERT(pkey!=NULL);
- HPROF_ASSERT(key_len>=(int)sizeof(TraceKey));
- HPROF_ASSERT(((TraceKey*)pkey)->n_frames<=1?key_len==(int)sizeof(TraceKey) :
- key_len==(int)sizeof(TraceKey)+
- (int)sizeof(FrameIndex)*(((TraceKey*)pkey)->n_frames-1));
- return (TraceKey*)pkey;
-}
-
-static TraceInfo *
-get_info(TraceIndex index)
-{
- TraceInfo * info;
-
- info = (TraceInfo*)table_get_info(gdata->trace_table, index);
- return info;
-}
-
-static TraceIndex
-find_or_create(SerialNumber thread_serial_num, jint n_frames,
- FrameIndex *frames, jvmtiPhase phase, TraceKey *trace_key_buffer)
-{
- TraceInfo * info;
- TraceKey * pkey;
- int key_len;
- TraceIndex index;
- jboolean new_one;
- static TraceKey empty_key;
-
- HPROF_ASSERT(frames!=NULL);
- HPROF_ASSERT(trace_key_buffer!=NULL);
- key_len = (int)sizeof(TraceKey);
- if ( n_frames > 1 ) {
- key_len += (int)((n_frames-1)*(int)sizeof(FrameIndex));
- }
- pkey = trace_key_buffer;
- *pkey = empty_key;
- pkey->thread_serial_num = (gdata->thread_in_traces ? thread_serial_num : 0);
- pkey->n_frames = (short)n_frames;
- pkey->phase = phase;
- if ( n_frames > 0 ) {
- (void)memcpy(pkey->frames, frames, (n_frames*(int)sizeof(FrameIndex)));
- }
-
- new_one = JNI_FALSE;
- index = table_find_or_create_entry(gdata->trace_table,
- pkey, key_len, &new_one, NULL);
- if ( new_one ) {
- info = get_info(index);
- info->serial_num = gdata->trace_serial_number_counter++;
- }
- return index;
-}
-
-static void
-list_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TraceInfo *info;
- TraceKey *key;
- int i;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len>0);
- HPROF_ASSERT(info_ptr!=NULL);
- key = (TraceKey*)key_ptr;
- info = (TraceInfo *)info_ptr;
-
- debug_message( "Trace 0x%08x: SN=%u, threadSN=%u, n_frames=%d, frames=(",
- index,
- info->serial_num,
- key->thread_serial_num,
- key->n_frames);
- for ( i = 0 ; i < key->n_frames ; i++ ) {
- debug_message( "0x%08x, ", key->frames[i]);
- }
- debug_message( "), traceSN=%u, num_hits=%d, self_cost=(%d,%d), "
- "total_cost=(%d,%d), status=0x%08x\n",
- info->serial_num,
- info->num_hits,
- jlong_high(info->self_cost),
- jlong_low(info->self_cost),
- jlong_high(info->total_cost),
- jlong_low(info->total_cost),
- info->status);
-}
-
-static void
-clear_cost(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TraceInfo *info;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len>0);
- HPROF_ASSERT(info_ptr!=NULL);
- info = (TraceInfo *)info_ptr;
- info->num_hits = 0;
- info->total_cost = 0;
- info->self_cost = 0;
-}
-
-/* Get the names for a frame in order to dump it. */
-static void
-get_frame_details(JNIEnv *env, FrameIndex frame_index,
- SerialNumber *frame_serial_num, char **pcsig, ClassIndex *pcnum,
- char **pmname, char **pmsig, char **psname, jint *plineno)
-{
- jmethodID method;
- jlocation location;
- jint lineno;
-
- HPROF_ASSERT(frame_index!=0);
- *pmname = NULL;
- *pmsig = NULL;
- *pcsig = NULL;
- if ( psname != NULL ) {
- *psname = NULL;
- }
- if ( plineno != NULL ) {
- *plineno = -1;
- }
- if ( pcnum != NULL ) {
- *pcnum = 0;
- }
- frame_get_location(frame_index, frame_serial_num, &method, &location, &lineno);
- if ( plineno != NULL ) {
- *plineno = lineno;
- }
- WITH_LOCAL_REFS(env, 1) {
- jclass klass;
-
- getMethodClass(method, &klass);
- getClassSignature(klass, pcsig, NULL);
- if ( pcnum != NULL ) {
- LoaderIndex loader_index;
- jobject loader;
-
- loader = getClassLoader(klass);
- loader_index = loader_find_or_create(env, loader);
- *pcnum = class_find_or_create(*pcsig, loader_index);
- (void)class_new_classref(env, *pcnum, klass);
- }
- if ( psname != NULL ) {
- getSourceFileName(klass, psname);
- }
- } END_WITH_LOCAL_REFS;
- getMethodName(method, pmname, pmsig);
-}
-
-/* Write out a stack trace. */
-static void
-output_trace(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TraceKey *key;
- TraceInfo *info;
- SerialNumber serial_num;
- SerialNumber thread_serial_num;
- jint n_frames;
- JNIEnv *env;
- int i;
- char *phase_str;
- struct FrameNames {
- SerialNumber serial_num;
- char * sname;
- char * csig;
- char * mname;
- int lineno;
- } *finfo;
-
- info = (TraceInfo*)info_ptr;
- if ( info->status != 0 ) {
- return;
- }
-
- env = (JNIEnv*)arg;
-
- key = (TraceKey*)key_ptr;
- thread_serial_num = key->thread_serial_num;
- serial_num = info->serial_num;
- info->status = 1;
- finfo = NULL;
-
- n_frames = (jint)key->n_frames;
- if ( n_frames > 0 ) {
- finfo = (struct FrameNames *)HPROF_MALLOC(n_frames*(int)sizeof(struct FrameNames));
-
- /* Write frames, but save information for trace later */
- for (i = 0; i < n_frames; i++) {
- FrameIndex frame_index;
- char *msig;
- ClassIndex cnum;
-
- frame_index = key->frames[i];
- get_frame_details(env, frame_index, &finfo[i].serial_num,
- &finfo[i].csig, &cnum,
- &finfo[i].mname, &msig, &finfo[i].sname, &finfo[i].lineno);
-
- if (frame_get_status(frame_index) == 0) {
- io_write_frame(frame_index, finfo[i].serial_num,
- finfo[i].mname, msig,
- finfo[i].sname, class_get_serial_number(cnum),
- finfo[i].lineno);
- frame_set_status(frame_index, 1);
- }
- jvmtiDeallocate(msig);
- }
- }
-
- /* Find phase string */
- if ( key->phase == JVMTI_PHASE_LIVE ) {
- phase_str = NULL; /* Normal trace, no phase annotation */
- } else {
- phase_str = phaseString(key->phase);
- }
-
- io_write_trace_header(serial_num, thread_serial_num, n_frames, phase_str);
-
- for (i = 0; i < n_frames; i++) {
- io_write_trace_elem(serial_num, key->frames[i], finfo[i].serial_num,
- finfo[i].csig,
- finfo[i].mname, finfo[i].sname, finfo[i].lineno);
- jvmtiDeallocate(finfo[i].csig);
- jvmtiDeallocate(finfo[i].mname);
- jvmtiDeallocate(finfo[i].sname);
- }
-
- io_write_trace_footer(serial_num, thread_serial_num, n_frames);
-
- if ( finfo != NULL ) {
- HPROF_FREE(finfo);
- }
-}
-
-/* Output a specific list of traces. */
-static void
-output_list(JNIEnv *env, TraceIndex *list, jint count)
-{
- rawMonitorEnter(gdata->data_access_lock); {
- int i;
-
- for ( i = 0; i < count ; i++ ) {
- TraceIndex index;
- TraceInfo *info;
- void * pkey;
- int key_len;
-
- index = list[i];
- table_get_key(gdata->trace_table, index, &pkey, &key_len);
- info = get_info(index);
- output_trace(index, pkey, key_len, info, (void*)env);
- }
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-static void
-collect_iterator(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
-{
- TraceInfo *info;
- IterateInfo *iterate;
-
- HPROF_ASSERT(key_ptr!=NULL);
- HPROF_ASSERT(key_len>0);
- HPROF_ASSERT(arg!=NULL);
- HPROF_ASSERT(info_ptr!=NULL);
- iterate = (IterateInfo *)arg;
- info = (TraceInfo *)info_ptr;
- iterate->traces[iterate->count++] = index;
- iterate->grand_total_cost += info->self_cost;
-}
-
-static int
-qsort_compare_cost(const void *p_trace1, const void *p_trace2)
-{
- TraceIndex trace1;
- TraceIndex trace2;
- TraceInfo * info1;
- TraceInfo * info2;
-
- HPROF_ASSERT(p_trace1!=NULL);
- HPROF_ASSERT(p_trace2!=NULL);
- trace1 = *(TraceIndex *)p_trace1;
- trace2 = *(TraceIndex *)p_trace2;
- info1 = get_info(trace1);
- info2 = get_info(trace2);
- /*LINTED*/
- return (int)(info2->self_cost - info1->self_cost);
-}
-
-static int
-qsort_compare_num_hits(const void *p_trace1, const void *p_trace2)
-{
- TraceIndex trace1;
- TraceIndex trace2;
- TraceInfo * info1;
- TraceInfo * info2;
-
- HPROF_ASSERT(p_trace1!=NULL);
- HPROF_ASSERT(p_trace2!=NULL);
- trace1 = *(TraceIndex *)p_trace1;
- trace2 = *(TraceIndex *)p_trace2;
- info1 = get_info(trace1);
- info2 = get_info(trace2);
- return info2->num_hits - info1->num_hits;
-}
-
-/* External interfaces. */
-
-void
-trace_init(void)
-{
- gdata->trace_table = table_initialize("Trace",
- 256, 256, 511, (int)sizeof(TraceInfo));
-}
-
-void
-trace_list(void)
-{
- debug_message(
- "--------------------- Trace Table ------------------------\n");
- table_walk_items(gdata->trace_table, &list_item, NULL);
- debug_message(
- "----------------------------------------------------------\n");
-}
-
-void
-trace_cleanup(void)
-{
- table_cleanup(gdata->trace_table, NULL, NULL);
- gdata->trace_table = NULL;
-}
-
-SerialNumber
-trace_get_serial_number(TraceIndex index)
-{
- TraceInfo *info;
-
- if ( index == 0 ) {
- return 0;
- }
- info = get_info(index);
- return info->serial_num;
-}
-
-void
-trace_increment_cost(TraceIndex index, jint num_hits, jlong self_cost, jlong total_cost)
-{
- TraceInfo *info;
-
- table_lock_enter(gdata->trace_table); {
- info = get_info(index);
- info->num_hits += num_hits;
- info->self_cost += self_cost;
- info->total_cost += total_cost;
- } table_lock_exit(gdata->trace_table);
-}
-
-TraceIndex
-trace_find_or_create(SerialNumber thread_serial_num, jint n_frames, FrameIndex *frames, jvmtiFrameInfo *jframes_buffer)
-{
- return find_or_create(thread_serial_num, n_frames, frames, getPhase(),
- (TraceKey*)jframes_buffer);
-}
-
-/* We may need to ask for more frames than the user asked for */
-static int
-get_real_depth(int depth, jboolean skip_init)
-{
- int extra_frames;
-
- extra_frames = 0;
- /* This is only needed if we are doing BCI */
- if ( gdata->bci && depth > 0 ) {
- /* Account for Java and native Tracker methods */
- extra_frames = 2;
- if ( skip_init ) {
- /* Also allow for ignoring the java.lang.Object.<init> method */
- extra_frames += 1;
- }
- }
- return depth + extra_frames;
-}
-
-/* Fill in FrameIndex array from jvmtiFrameInfo array, return n_frames */
-static int
-fill_frame_buffer(int depth, int real_depth,
- int frame_count, jboolean skip_init,
- jvmtiFrameInfo *jframes_buffer, FrameIndex *frames_buffer)
-{
- int n_frames;
- jint topframe;
-
- /* If real_depth is 0, just return 0 */
- if ( real_depth == 0 ) {
- return 0;
- }
-
- /* Assume top frame index is 0 for now */
- topframe = 0;
-
- /* Possible top frames belong to the hprof Tracker class, remove them */
- if ( gdata->bci ) {
- while ( ( ( frame_count - topframe ) > 0 ) &&
- ( topframe < (real_depth-depth) ) &&
- ( tracker_method(jframes_buffer[topframe].method) ||
- ( skip_init
- && jframes_buffer[topframe].method==gdata->object_init_method ) )
- ) {
- topframe++;
- }
- }
-
- /* Adjust count to match depth request */
- if ( ( frame_count - topframe ) > depth ) {
- frame_count = depth + topframe;
- }
-
- /* The actual frame count we will process */
- n_frames = frame_count - topframe;
- if ( n_frames > 0 ) {
- int i;
-
- for (i = 0; i < n_frames; i++) {
- jmethodID method;
- jlocation location;
-
- method = jframes_buffer[i+topframe].method;
- location = jframes_buffer[i+topframe].location;
- frames_buffer[i] = frame_find_or_create(method, location);
- }
- }
- return n_frames;
-}
-
-/* Get the trace for the supplied thread */
-TraceIndex
-trace_get_current(jthread thread, SerialNumber thread_serial_num,
- int depth, jboolean skip_init,
- FrameIndex *frames_buffer,
- jvmtiFrameInfo *jframes_buffer)
-{
- TraceIndex index;
- jint frame_count;
- int real_depth;
- int n_frames;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(frames_buffer!=NULL);
- HPROF_ASSERT(jframes_buffer!=NULL);
-
- /* We may need to ask for more frames than the user asked for */
- real_depth = get_real_depth(depth, skip_init);
-
- /* Get the stack trace for this one thread */
- frame_count = 0;
- if ( real_depth > 0 ) {
- getStackTrace(thread, jframes_buffer, real_depth, &frame_count);
- }
-
- /* Create FrameIndex's */
- n_frames = fill_frame_buffer(depth, real_depth, frame_count, skip_init,
- jframes_buffer, frames_buffer);
-
- /* Lookup or create new TraceIndex */
- index = find_or_create(thread_serial_num, n_frames, frames_buffer,
- getPhase(), (TraceKey*)jframes_buffer);
- return index;
-}
-
-/* Get traces for all threads in list (traces[i]==0 if thread not running) */
-void
-trace_get_all_current(jint thread_count, jthread *threads,
- SerialNumber *thread_serial_nums,
- int depth, jboolean skip_init,
- TraceIndex *traces, jboolean always_care)
-{
- jvmtiStackInfo *stack_info;
- int nbytes;
- int real_depth;
- int i;
- FrameIndex *frames_buffer;
- TraceKey *trace_key_buffer;
- jvmtiPhase phase;
-
- HPROF_ASSERT(threads!=NULL);
- HPROF_ASSERT(thread_serial_nums!=NULL);
- HPROF_ASSERT(traces!=NULL);
- HPROF_ASSERT(thread_count > 0);
-
- /* Find out what the phase is for all these traces */
- phase = getPhase();
-
- /* We may need to ask for more frames than the user asked for */
- real_depth = get_real_depth(depth, skip_init);
-
- /* Get the stack traces for all the threads */
- getThreadListStackTraces(thread_count, threads, real_depth, &stack_info);
-
- /* Allocate a frames_buffer and trace key buffer */
- nbytes = (int)sizeof(FrameIndex)*real_depth;
- frames_buffer = (FrameIndex*)HPROF_MALLOC(nbytes);
- nbytes += (int)sizeof(TraceKey);
- trace_key_buffer = (TraceKey*)HPROF_MALLOC(nbytes);
-
- /* Loop over the stack traces we have for these 'thread_count' threads */
- for ( i = 0 ; i < thread_count ; i++ ) {
- int n_frames;
-
- /* Assume 0 at first (no trace) */
- traces[i] = 0;
-
- /* If thread has frames, is runnable, and isn't suspended, we care */
- if ( always_care ||
- ( stack_info[i].frame_count > 0
- && (stack_info[i].state & JVMTI_THREAD_STATE_RUNNABLE)!=0
- && (stack_info[i].state & JVMTI_THREAD_STATE_SUSPENDED)==0
- && (stack_info[i].state & JVMTI_THREAD_STATE_INTERRUPTED)==0 )
- ) {
-
- /* Create FrameIndex's */
- n_frames = fill_frame_buffer(depth, real_depth,
- stack_info[i].frame_count,
- skip_init,
- stack_info[i].frame_buffer,
- frames_buffer);
-
- /* Lookup or create new TraceIndex */
- traces[i] = find_or_create(thread_serial_nums[i],
- n_frames, frames_buffer, phase, trace_key_buffer);
- }
- }
-
- /* Make sure we free the space */
- HPROF_FREE(frames_buffer);
- HPROF_FREE(trace_key_buffer);
- jvmtiDeallocate(stack_info);
-}
-
-/* Increment the trace costs for all the threads (for cpu=samples) */
-void
-trace_increment_all_sample_costs(jint thread_count, jthread *threads,
- SerialNumber *thread_serial_nums,
- int depth, jboolean skip_init)
-{
- TraceIndex *traces;
- int nbytes;
-
- HPROF_ASSERT(threads!=NULL);
- HPROF_ASSERT(thread_serial_nums!=NULL);
- HPROF_ASSERT(thread_count > 0);
- HPROF_ASSERT(depth >= 0);
-
- if ( depth == 0 ) {
- return;
- }
-
- /* Allocate a traces array */
- nbytes = (int)sizeof(TraceIndex)*thread_count;
- traces = (TraceIndex*)HPROF_MALLOC(nbytes);
-
- /* Get all the current traces for these threads */
- trace_get_all_current(thread_count, threads, thread_serial_nums,
- depth, skip_init, traces, JNI_FALSE);
-
- /* Increment the cpu=samples cost on these traces */
- table_lock_enter(gdata->trace_table); {
- int i;
-
- for ( i = 0 ; i < thread_count ; i++ ) {
- /* Each trace gets a hit and an increment of it's total cost */
- if ( traces[i] != 0 ) {
- TraceInfo *info;
-
- info = get_info(traces[i]);
- info->num_hits += 1;
- info->self_cost += (jlong)1;
- info->total_cost += (jlong)1;
- }
- }
- } table_lock_exit(gdata->trace_table);
-
- /* Free up the memory allocated */
- HPROF_FREE(traces);
-}
-
-void
-trace_output_unmarked(JNIEnv *env)
-{
- rawMonitorEnter(gdata->data_access_lock); {
- table_walk_items(gdata->trace_table, &output_trace, (void*)env);
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-/* output info on the cost associated with traces */
-void
-trace_output_cost(JNIEnv *env, double cutoff)
-{
- IterateInfo iterate;
- int i, trace_table_size, n_items;
- double accum;
- int n_entries;
-
- rawMonitorEnter(gdata->data_access_lock); {
-
- n_entries = table_element_count(gdata->trace_table);
- iterate.traces = HPROF_MALLOC(n_entries*(int)sizeof(TraceIndex)+1);
- iterate.count = 0;
- iterate.grand_total_cost = 0;
- table_walk_items(gdata->trace_table, &collect_iterator, &iterate);
-
- trace_table_size = iterate.count;
-
- /* sort all the traces according to the cost */
- qsort(iterate.traces, trace_table_size, sizeof(TraceIndex),
- &qsort_compare_cost);
-
- n_items = 0;
- for (i = 0; i < trace_table_size; i++) {
- TraceInfo *info;
- TraceIndex trace_index;
- double percent;
-
- trace_index = iterate.traces[i];
- info = get_info(trace_index);
- /* As soon as a trace with zero hits is seen, we need no others */
- if (info->num_hits == 0 ) {
- break;
- }
- percent = (double)info->self_cost / (double)iterate.grand_total_cost;
- if (percent < cutoff) {
- break;
- }
- n_items++;
- }
-
- /* Now write all trace we might refer to. */
- output_list(env, iterate.traces, n_items);
-
- io_write_cpu_samples_header(iterate.grand_total_cost, n_items);
-
- accum = 0;
-
- for (i = 0; i < n_items; i++) {
- SerialNumber frame_serial_num;
- TraceInfo *info;
- TraceKey *key;
- TraceIndex trace_index;
- double percent;
- char *csig;
- char *mname;
- char *msig;
-
- trace_index = iterate.traces[i];
- info = get_info(trace_index);
- key = get_pkey(trace_index);
- percent = ((double)info->self_cost / (double)iterate.grand_total_cost) * 100.0;
- accum += percent;
-
- csig = NULL;
- mname = NULL;
- msig = NULL;
-
- if (key->n_frames > 0) {
- get_frame_details(env, key->frames[0], &frame_serial_num,
- &csig, NULL, &mname, &msig, NULL, NULL);
- }
-
- io_write_cpu_samples_elem(i+1, percent, accum, info->num_hits,
- (jint)info->self_cost, info->serial_num,
- key->n_frames, csig, mname);
-
- jvmtiDeallocate(csig);
- jvmtiDeallocate(mname);
- jvmtiDeallocate(msig);
- }
-
- io_write_cpu_samples_footer();
-
- HPROF_FREE(iterate.traces);
-
- } rawMonitorExit(gdata->data_access_lock);
-
-}
-
-/* output the trace cost in old prof format */
-void
-trace_output_cost_in_prof_format(JNIEnv *env)
-{
- IterateInfo iterate;
- int i, trace_table_size;
- int n_entries;
-
- rawMonitorEnter(gdata->data_access_lock); {
-
- n_entries = table_element_count(gdata->trace_table);
- iterate.traces = HPROF_MALLOC(n_entries*(int)sizeof(TraceIndex)+1);
- iterate.count = 0;
- iterate.grand_total_cost = 0;
- table_walk_items(gdata->trace_table, &collect_iterator, &iterate);
-
- trace_table_size = iterate.count;
-
- /* sort all the traces according to the number of hits */
- qsort(iterate.traces, trace_table_size, sizeof(TraceIndex),
- &qsort_compare_num_hits);
-
- io_write_oldprof_header();
-
- for (i = 0; i < trace_table_size; i++) {
- SerialNumber frame_serial_num;
- TraceInfo *info;
- TraceKey *key;
- TraceIndex trace_index;
- int num_frames;
- int num_hits;
- char *csig_callee;
- char *mname_callee;
- char *msig_callee;
- char *csig_caller;
- char *mname_caller;
- char *msig_caller;
-
- trace_index = iterate.traces[i];
- key = get_pkey(trace_index);
- info = get_info(trace_index);
- num_hits = info->num_hits;
-
- if (num_hits == 0) {
- break;
- }
-
- csig_callee = NULL;
- mname_callee = NULL;
- msig_callee = NULL;
- csig_caller = NULL;
- mname_caller = NULL;
- msig_caller = NULL;
-
- num_frames = (int)key->n_frames;
-
- if (num_frames >= 1) {
- get_frame_details(env, key->frames[0], &frame_serial_num,
- &csig_callee, NULL,
- &mname_callee, &msig_callee, NULL, NULL);
- }
-
- if (num_frames > 1) {
- get_frame_details(env, key->frames[1], &frame_serial_num,
- &csig_caller, NULL,
- &mname_caller, &msig_caller, NULL, NULL);
- }
-
- io_write_oldprof_elem(info->num_hits, num_frames,
- csig_callee, mname_callee, msig_callee,
- csig_caller, mname_caller, msig_caller,
- (int)info->total_cost);
-
- jvmtiDeallocate(csig_callee);
- jvmtiDeallocate(mname_callee);
- jvmtiDeallocate(msig_callee);
- jvmtiDeallocate(csig_caller);
- jvmtiDeallocate(mname_caller);
- jvmtiDeallocate(msig_caller);
- }
-
- io_write_oldprof_footer();
-
- HPROF_FREE(iterate.traces);
-
- } rawMonitorExit(gdata->data_access_lock);
-}
-
-void
-trace_clear_cost(void)
-{
- table_walk_items(gdata->trace_table, &clear_cost, NULL);
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_trace.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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_TRACE_H
-#define HPROF_TRACE_H
-
-void trace_increment_all_sample_costs(jint count, jthread *threads,
- SerialNumber *thread_serial_nums, int depth,
- jboolean skip_init);
-
-void trace_get_all_current(jint count, jthread *threads,
- SerialNumber *thread_serial_nums, int depth,
- jboolean skip_init, TraceIndex *traces,
- jboolean always_care);
-
-TraceIndex trace_get_current(jthread thread,
- SerialNumber thread_serial_num, int depth,
- jboolean skip_init,
- FrameIndex *frames_buffer,
- jvmtiFrameInfo *jframes_buffer);
-
-void trace_init(void);
-TraceIndex trace_find_or_create(SerialNumber thread_serial_num,
- jint n_frames, FrameIndex *frames,
- jvmtiFrameInfo *jframes_buffer);
-SerialNumber trace_get_serial_number(TraceIndex index);
-void trace_increment_cost(TraceIndex index,
- jint num_hits, jlong self_cost, jlong total_cost);
-void trace_list(void);
-void trace_cleanup(void);
-
-void trace_clear_cost(void);
-void trace_output_unmarked(JNIEnv *env);
-void trace_output_cost(JNIEnv *env, double cutoff);
-void trace_output_cost_in_prof_format(JNIEnv *env);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_tracker.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,320 +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.
- */
-
-
-/* Tracker class support functions. */
-
-/*
- * This file contains the native support calls for the Tracker
- * class. These native methods are registered and not made extern.
- * Tracking is engaged by using JNI to assign to a static field in the
- * Tracker class.
- *
- * Just like JVMTI callbacks, it's best that we keep track of these so that
- * when the VM_DEATH happens we know to wait for them to complete.
- *
- * This file also contains the functions that will initialize the Tracker
- * interface for BCI and identify the Tracker methods to make sure
- * they are not included in any stack traces obtained from JVMTI.
- *
- * RFE: The performance of the java injected code calling native methods
- * could be an issue here, cpu=times seems to be the worst where
- * a native call is made for entry and exit, even on the smallest
- * Java method. The alternative would be to cache the data on
- * the Java side, and either push it out to the native side, or
- * use some kind of pull from the native side, or even using
- * shared memory or a socket. However having said that, the
- * current performance issues are more around sheer memory needed,
- * and repeated calls to GetThreadCpuTime(), which is being investigated.
- *
- */
-
-#include "hprof.h"
-
-/* Macros to surround tracker based callback code.
- * Also see BEGIN_CALLBACK and END_CALLBACK in hprof_init.c.
- * If the VM_DEATH callback is active in the begining, then this callback
- * just blocks (it is assumed we don't want to return to the VM).
- * 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.
- *
- * WARNING: No not 'return' or 'goto' out of the BEGIN_TRACKER_CALLBACK/END_TRACKER_CALLBACK
- * block, this will mess up the count.
- */
-
-#define BEGIN_TRACKER_CALLBACK() \
-{ /* BEGIN OF TRACKER_CALLBACK */ \
- jboolean bypass = JNI_TRUE; \
- rawMonitorEnter(gdata->callbackLock); { \
- if ( gdata->tracking_engaged != 0 ) { \
- if (!gdata->vm_death_callback_active) { \
- gdata->active_callbacks++; \
- bypass = JNI_FALSE; \
- } \
- } \
- } rawMonitorExit(gdata->callbackLock); \
- if ( !bypass ) { \
- /* BODY OF TRACKER_CALLBACK CODE */
-
-#define END_TRACKER_CALLBACK() /* Part of bypass if body */ \
- rawMonitorEnter(gdata->callbackLock); { \
- gdata->active_callbacks--; \
- if (gdata->active_callbacks < 0) { \
- HPROF_ERROR(JNI_TRUE, "Problems tracking callbacks"); \
- } \
- if (gdata->vm_death_callback_active) { \
- if (gdata->active_callbacks == 0) { \
- rawMonitorNotifyAll(gdata->callbackLock); \
- } \
- } \
- } rawMonitorExit(gdata->callbackLock); \
- } \
-} /* END OF TRACKER_CALLBACK */
-
-
-/*
- * Class: Tracker
- * Method: nativeNewArray
- * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
- */
-static void JNICALL
-Tracker_nativeNewArray
- (JNIEnv *env, jclass clazz, jobject thread, jobject obj)
-{
- BEGIN_TRACKER_CALLBACK() {
- event_newarray(env, thread, obj);
- } END_TRACKER_CALLBACK();
-}
-
-/*
- * Class: Tracker
- * Method: nativeObjectInit
- * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
- */
-static void JNICALL
-Tracker_nativeObjectInit
- (JNIEnv *env, jclass clazz, jobject thread, jobject obj)
-{
- BEGIN_TRACKER_CALLBACK() {
- event_object_init(env, thread, obj);
- } END_TRACKER_CALLBACK();
-}
-
-/*
- * Class: Tracker
- * Method: nativeCallSite
- * Signature: (Ljava/lang/Object;II)V
- */
-static void JNICALL
-Tracker_nativeCallSite
- (JNIEnv *env, jclass clazz, jobject thread, jint cnum, jint mnum)
-{
- BEGIN_TRACKER_CALLBACK() {
- event_call(env, thread, cnum, mnum);
- } END_TRACKER_CALLBACK();
-}
-
-/*
- * Class: Tracker
- * Method: nativeReturnSite
- * Signature: (Ljava/lang/Object;II)V
- */
-static void JNICALL
-Tracker_nativeReturnSite
- (JNIEnv *env, jclass clazz, jobject thread, jint cnum, jint mnum)
-{
- BEGIN_TRACKER_CALLBACK() {
- event_return(env, thread, cnum, mnum);
- } END_TRACKER_CALLBACK();
-}
-
-
-/* ------------------------------------------------------------------- */
-/* Set Java static field to turn on native code calls in Tracker. */
-
-static void
-set_engaged(JNIEnv *env, jint engaged)
-{
- LOG3("set_engaged()", "engaging tracking", engaged);
-
- if ( ! gdata->bci ) {
- return;
- }
- rawMonitorEnter(gdata->callbackLock); {
- if ( gdata->tracking_engaged != engaged ) {
- jfieldID field;
- jclass tracker_class;
-
- tracker_class = class_get_class(env, gdata->tracker_cnum);
- gdata->tracking_engaged = 0;
- /* Activate or deactivate the injection code on the Java side */
- HPROF_ASSERT(tracker_class!=NULL);
- exceptionClear(env);
- field = getStaticFieldID(env, tracker_class,
- TRACKER_ENGAGED_NAME, TRACKER_ENGAGED_SIG);
- setStaticIntField(env, tracker_class, field, engaged);
- exceptionClear(env);
-
- LOG3("set_engaged()", "tracking engaged", engaged);
-
- gdata->tracking_engaged = engaged;
- }
- } rawMonitorExit(gdata->callbackLock);
-}
-
-void
-tracker_engage(JNIEnv *env)
-{
- set_engaged(env, 0xFFFF);
-}
-
-void
-tracker_disengage(JNIEnv *env)
-{
- set_engaged(env, 0);
-}
-
-jboolean
-tracker_method(jmethodID method)
-{
- int i;
-
- if ( ! gdata->bci ) {
- return JNI_FALSE;
- }
-
- HPROF_ASSERT(method!=NULL);
- HPROF_ASSERT(gdata->tracker_method_count > 0);
- for ( i = 0 ; i < gdata->tracker_method_count ; i++ ) {
- HPROF_ASSERT(gdata->tracker_methods[i].method!=NULL);
- if ( method == gdata->tracker_methods[i].method ) {
- return JNI_TRUE;
- }
- }
- return JNI_FALSE;
-}
-
-static JNINativeMethod registry[4] =
-{
- { TRACKER_NEWARRAY_NATIVE_NAME, TRACKER_NEWARRAY_NATIVE_SIG,
- (void*)&Tracker_nativeNewArray },
- { TRACKER_OBJECT_INIT_NATIVE_NAME, TRACKER_OBJECT_INIT_NATIVE_SIG,
- (void*)&Tracker_nativeObjectInit },
- { TRACKER_CALL_NATIVE_NAME, TRACKER_CALL_NATIVE_SIG,
- (void*)&Tracker_nativeCallSite },
- { TRACKER_RETURN_NATIVE_NAME, TRACKER_RETURN_NATIVE_SIG,
- (void*)&Tracker_nativeReturnSite }
-};
-
-static struct {
- char *name;
- char *sig;
-} tracker_methods[] =
- {
- { TRACKER_NEWARRAY_NAME, TRACKER_NEWARRAY_SIG },
- { TRACKER_OBJECT_INIT_NAME, TRACKER_OBJECT_INIT_SIG },
- { TRACKER_CALL_NAME, TRACKER_CALL_SIG },
- { TRACKER_RETURN_NAME, TRACKER_RETURN_SIG },
- { TRACKER_NEWARRAY_NATIVE_NAME, TRACKER_NEWARRAY_NATIVE_SIG },
- { TRACKER_OBJECT_INIT_NATIVE_NAME, TRACKER_OBJECT_INIT_NATIVE_SIG },
- { TRACKER_CALL_NATIVE_NAME, TRACKER_CALL_NATIVE_SIG },
- { TRACKER_RETURN_NATIVE_NAME, TRACKER_RETURN_NATIVE_SIG }
- };
-
-void
-tracker_setup_class(void)
-{
- ClassIndex cnum;
- LoaderIndex loader_index;
-
- HPROF_ASSERT(gdata->tracker_cnum==0);
- loader_index = loader_find_or_create(NULL,NULL);
- cnum = class_find_or_create(TRACKER_CLASS_SIG, loader_index);
- gdata->tracker_cnum = cnum;
- HPROF_ASSERT(cnum!=0);
- class_add_status(cnum, CLASS_SPECIAL);
-}
-
-void
-tracker_setup_methods(JNIEnv *env)
-{
- ClassIndex cnum;
- LoaderIndex loader_index;
- int i;
- jclass object_class;
- jclass tracker_class;
-
- if ( ! gdata->bci ) {
- return;
- }
-
- loader_index = loader_find_or_create(NULL,NULL);
- cnum = class_find_or_create(OBJECT_CLASS_SIG, loader_index);
- object_class = class_get_class(env, cnum);
- tracker_class = class_get_class(env, gdata->tracker_cnum);
-
- CHECK_EXCEPTIONS(env) {
- registerNatives(env, tracker_class, registry,
- (int)sizeof(registry)/(int)sizeof(registry[0]));
- } END_CHECK_EXCEPTIONS;
-
- HPROF_ASSERT(tracker_class!=NULL);
-
- gdata->tracker_method_count =
- (int)sizeof(tracker_methods)/(int)sizeof(tracker_methods[0]);
-
- HPROF_ASSERT(gdata->tracker_method_count <=
- (int)(sizeof(gdata->tracker_methods)/sizeof(gdata->tracker_methods[0])));
-
- CHECK_EXCEPTIONS(env) {
- gdata->object_init_method = getMethodID(env, object_class,
- OBJECT_INIT_NAME, OBJECT_INIT_SIG);
- for ( i=0 ; i < gdata->tracker_method_count ; i++ ) {
- gdata->tracker_methods[i].name =
- string_find_or_create(tracker_methods[i].name);
- gdata->tracker_methods[i].sig =
- string_find_or_create(tracker_methods[i].sig);
- gdata->tracker_methods[i].method =
- getStaticMethodID(env, tracker_class,
- tracker_methods[i].name, tracker_methods[i].sig);
- HPROF_ASSERT(gdata->tracker_methods[i].method!=NULL);
- LOG2("tracker_setup_methods(): Found", tracker_methods[i].name);
- }
- } END_CHECK_EXCEPTIONS;
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_tracker.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +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_TRACKER_H
-#define HPROF_TRACKER_H
-
-/* The internal qualified classname */
-
-#define OBJECT_CLASS_SIG "Ljava/lang/Object;"
-#define OBJECT_INIT_NAME "<init>"
-#define OBJECT_INIT_SIG "()V"
-
-#define TRACKER_PACKAGE "com/sun/demo/jvmti/hprof"
-#define TRACKER_CLASS_NAME TRACKER_PACKAGE "/Tracker"
-#define TRACKER_CLASS_SIG "L" TRACKER_CLASS_NAME ";"
-
-#define TRACKER_NEWARRAY_NAME "NewArray"
-#define TRACKER_NEWARRAY_SIG "(Ljava/lang/Object;)V"
-#define TRACKER_NEWARRAY_NATIVE_NAME "nativeNewArray"
-#define TRACKER_NEWARRAY_NATIVE_SIG "(Ljava/lang/Object;Ljava/lang/Object;)V"
-
-#define TRACKER_OBJECT_INIT_NAME "ObjectInit"
-#define TRACKER_OBJECT_INIT_SIG "(Ljava/lang/Object;)V"
-#define TRACKER_OBJECT_INIT_NATIVE_NAME "nativeObjectInit"
-#define TRACKER_OBJECT_INIT_NATIVE_SIG "(Ljava/lang/Object;Ljava/lang/Object;)V"
-
-#define TRACKER_CALL_NAME "CallSite"
-#define TRACKER_CALL_SIG "(II)V"
-#define TRACKER_CALL_NATIVE_NAME "nativeCallSite"
-#define TRACKER_CALL_NATIVE_SIG "(Ljava/lang/Object;II)V"
-
-
-#define TRACKER_RETURN_NAME "ReturnSite"
-#define TRACKER_RETURN_SIG "(II)V"
-#define TRACKER_RETURN_NATIVE_NAME "nativeReturnSite"
-#define TRACKER_RETURN_NATIVE_SIG "(Ljava/lang/Object;II)V"
-
-#define TRACKER_ENGAGED_NAME "engaged"
-#define TRACKER_ENGAGED_SIG "I"
-
-void tracker_setup_class(void);
-void tracker_setup_methods(JNIEnv *env);
-void tracker_engage(JNIEnv *env);
-void tracker_disengage(JNIEnv *env);
-jboolean tracker_method(jmethodID method);
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_util.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1738 +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.
- */
-
-
-/* General utility functions. */
-
-/*
- * Wrappers over JVM, JNI, and JVMTI functions are placed here.
- *
- * All memory allocation and deallocation goes through jvmtiAllocate()
- * and jvmtiDeallocate().
- *
- */
-
-
-#include "hprof.h"
-
-/* Macro to get JNI function pointer. */
-#define JNI_FUNC_PTR(env,f) (*((*(env))->f))
-
-/* Macro to get JVM function pointer. */
-#define JVM_FUNC_PTR(env,f) (*((*(env))->f))
-
-/* Macro to get JVMTI function pointer. */
-#define JVMTI_FUNC_PTR(env,f) (*((*(env))->f))
-
-/* ------------------------------------------------------------------- */
-/* JVM functions */
-
-JNIEnv *
-getEnv(void)
-{
- JNIEnv *env;
- jint res;
-
- res = JVM_FUNC_PTR(gdata->jvm,GetEnv)
- (gdata->jvm, (void **)&env, JNI_VERSION_1_2);
- if (res != JNI_OK) {
- char buf[256];
-
- (void)md_snprintf(buf, sizeof(buf),
- "Unable to access JNI Version 1.2 (0x%x),"
- " is your JDK a 5.0 or newer version?"
- " JNIEnv's GetEnv() returned %d",
- JNI_VERSION_1_2, res);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_FALSE, buf);
- error_exit_process(1); /* Kill entire process, no core dump */
- }
- return env;
-}
-
-/* ------------------------------------------------------------------- */
-/* Memory Allocation */
-
-void *
-jvmtiAllocate(int size)
-{
- jvmtiError error;
- unsigned char *ptr;
-
- HPROF_ASSERT(size>=0);
- ptr = NULL;
- if ( size == 0 ) {
- return ptr;
- }
- error = JVMTI_FUNC_PTR(gdata->jvmti,Allocate)
- (gdata->jvmti, (jlong)size, &ptr);
- if ( error != JVMTI_ERROR_NONE || ptr == NULL ) {
- HPROF_JVMTI_ERROR(error, "Cannot allocate jvmti memory");
- }
- return (void*)ptr;
-}
-
-void
-jvmtiDeallocate(void *ptr)
-{
- if ( ptr != NULL ) {
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,Deallocate)
- (gdata->jvmti, (unsigned char*)ptr);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot deallocate jvmti memory");
- }
- }
-}
-
-#ifdef DEBUG
-
-void *
-hprof_debug_malloc(int size, char *file, int line)
-{
- void *ptr;
-
- HPROF_ASSERT(size>0);
-
- rawMonitorEnter(gdata->debug_malloc_lock); {
- ptr = debug_malloc(size, file, line);
- } rawMonitorExit(gdata->debug_malloc_lock);
-
- if ( ptr == NULL ) {
- HPROF_ERROR(JNI_TRUE, "Cannot allocate malloc memory");
- }
- return ptr;
-}
-
-void
-hprof_debug_free(void *ptr, char *file, int line)
-{
- HPROF_ASSERT(ptr!=NULL);
-
- rawMonitorEnter(gdata->debug_malloc_lock); {
- (void)debug_free(ptr, file, line);
- } rawMonitorExit(gdata->debug_malloc_lock);
-}
-
-#endif
-
-void *
-hprof_malloc(int size)
-{
- void *ptr;
-
- HPROF_ASSERT(size>0);
- ptr = malloc(size);
- if ( ptr == NULL ) {
- HPROF_ERROR(JNI_TRUE, "Cannot allocate malloc memory");
- }
- return ptr;
-}
-
-void
-hprof_free(void *ptr)
-{
- HPROF_ASSERT(ptr!=NULL);
- (void)free(ptr);
-}
-
-/* ------------------------------------------------------------------- */
-/* JVMTI Version functions */
-
-jint
-jvmtiVersion(void)
-{
- if (gdata->cachedJvmtiVersion == 0) {
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)
- (gdata->jvmti, &(gdata->cachedJvmtiVersion));
- if (error != JVMTI_ERROR_NONE) {
- HPROF_JVMTI_ERROR(error, "Cannot get jvmti version number");
- }
- }
- return gdata->cachedJvmtiVersion;
-}
-
-static jint
-jvmtiMajorVersion(void)
-{
- return (jvmtiVersion() & JVMTI_VERSION_MASK_MAJOR)
- >> JVMTI_VERSION_SHIFT_MAJOR;
-}
-
-static jint
-jvmtiMinorVersion(void)
-{
- return (jvmtiVersion() & JVMTI_VERSION_MASK_MINOR)
- >> JVMTI_VERSION_SHIFT_MINOR;
-}
-
-static jint
-jvmtiMicroVersion(void)
-{
- return (jvmtiVersion() & JVMTI_VERSION_MASK_MICRO)
- >> JVMTI_VERSION_SHIFT_MICRO;
-}
-
-/* Logic to determine JVMTI version compatibility */
-static jboolean
-compatible_versions(jint major_runtime, jint minor_runtime,
- jint major_compiletime, jint minor_compiletime)
-{
- /* Runtime major version must match. */
- if ( major_runtime != major_compiletime ) {
- return JNI_FALSE;
- }
- /* Runtime minor version must be >= the version compiled with. */
- if ( minor_runtime < minor_compiletime ) {
- return JNI_FALSE;
- }
- /* Assumed compatible */
- return JNI_TRUE;
-}
-
-/* ------------------------------------------------------------------- */
-/* JVMTI Raw Monitor support functions */
-
-jrawMonitorID
-createRawMonitor(const char *str)
-{
- jvmtiError error;
- jrawMonitorID m;
-
- m = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,CreateRawMonitor)
- (gdata->jvmti, str, &m);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot create raw monitor");
- }
- return m;
-}
-
-void
-rawMonitorEnter(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorEnter)
- (gdata->jvmti, m);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok, after agent shutdown CALLBACK code may call this */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot enter with raw monitor");
- }
-}
-
-void
-rawMonitorWait(jrawMonitorID m, jlong pause_time)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorWait)
- (gdata->jvmti, m, pause_time);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot wait with raw monitor");
- }
-}
-
-void
-rawMonitorNotifyAll(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll)
- (gdata->jvmti, m);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot notify all with raw monitor");
- }
-}
-
-void
-rawMonitorExit(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorExit)
- (gdata->jvmti, m);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok, after agent shutdown CALLBACK code may call this */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot exit with raw monitor");
- }
-}
-
-void
-destroyRawMonitor(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,DestroyRawMonitor)
- (gdata->jvmti, m);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot destroy raw monitor");
- }
-}
-
-/* ------------------------------------------------------------------- */
-/* JVMTI Event enabling/disabilin */
-
-void
-setEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event, jthread thread)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode)
- (gdata->jvmti, mode, event, thread);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot set event notification");
- }
-}
-
-/* ---------------------------------------------------------------------- */
-/* JNI Support Functions */
-
-jobject
-exceptionOccurred(JNIEnv *env)
-{
- return JNI_FUNC_PTR(env,ExceptionOccurred)(env);
-}
-
-void
-exceptionDescribe(JNIEnv *env)
-{
- JNI_FUNC_PTR(env,ExceptionDescribe)(env);
-}
-
-void
-exceptionClear(JNIEnv *env)
-{
- JNI_FUNC_PTR(env,ExceptionClear)(env);
-}
-
-jobject
-newGlobalReference(JNIEnv *env, jobject object)
-{
- jobject gref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- gref = JNI_FUNC_PTR(env,NewGlobalRef)(env, object);
- HPROF_ASSERT(gref!=NULL);
- return gref;
-}
-
-jobject
-newWeakGlobalReference(JNIEnv *env, jobject object)
-{
- jobject gref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- gref = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, object);
- HPROF_ASSERT(gref!=NULL);
- return gref;
-}
-
-void
-deleteGlobalReference(JNIEnv *env, jobject object)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- JNI_FUNC_PTR(env,DeleteGlobalRef)(env, object);
-}
-
-jobject
-newLocalReference(JNIEnv *env, jobject object)
-{
- jobject lref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- lref = JNI_FUNC_PTR(env,NewLocalRef)(env, object);
- /* Possible for a non-null weak reference to return a NULL localref */
- return lref;
-}
-
-void
-deleteLocalReference(JNIEnv *env, jobject object)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- JNI_FUNC_PTR(env,DeleteLocalRef)(env, object);
-}
-
-void
-deleteWeakGlobalReference(JNIEnv *env, jobject object)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, object);
-}
-
-jclass
-getObjectClass(JNIEnv *env, jobject object)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass clazz;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
- HPROF_ASSERT(clazz!=NULL);
- return clazz;
-}
-
-jclass
-getSuperclass(JNIEnv *env, jclass klass)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass super_klass;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(klass!=NULL);
- super_klass = JNI_FUNC_PTR(env,GetSuperclass)(env, klass);
- return super_klass;
-}
-
-jmethodID
-getStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
- jmethodID method;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(sig!=NULL);
- CHECK_EXCEPTIONS(env) {
- method = JNI_FUNC_PTR(env,GetStaticMethodID)(env, clazz, name, sig);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(method!=NULL);
- return method;
-}
-
-jmethodID
-getMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
- jmethodID method;
- jobject exception;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(sig!=NULL);
- method = JNI_FUNC_PTR(env,GetMethodID)(env, clazz, name, sig);
- /* Might be a static method */
- exception = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
- if ( exception != NULL ) {
- JNI_FUNC_PTR(env,ExceptionClear)(env);
- method = getStaticMethodID(env, clazz, name, sig);
- }
- HPROF_ASSERT(method!=NULL);
- return method;
-}
-
-jclass
-findClass(JNIEnv *env, const char *name)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass clazz;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(name!=NULL);
- LOG2("FindClass", name);
- CHECK_EXCEPTIONS(env) {
- clazz = JNI_FUNC_PTR(env,FindClass)(env, name);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(clazz!=NULL);
- return clazz;
-}
-
-jfieldID
-getStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
- jfieldID field;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(sig!=NULL);
- CHECK_EXCEPTIONS(env) {
- field = JNI_FUNC_PTR(env,GetStaticFieldID)(env, clazz, name, sig);
- } END_CHECK_EXCEPTIONS;
- return field;
-}
-
-void
-setStaticIntField(JNIEnv *env, jclass clazz, jfieldID field, jint value)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(field!=NULL);
- CHECK_EXCEPTIONS(env) {
- JNI_FUNC_PTR(env,SetStaticIntField)(env, clazz, field, value);
- } END_CHECK_EXCEPTIONS;
-}
-
-static jobject
-callStaticObjectMethod(JNIEnv *env, jclass klass, jmethodID method)
-{
- jobject x;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(klass!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- x = JNI_FUNC_PTR(env,CallStaticObjectMethod)(env, klass, method);
- } END_CHECK_EXCEPTIONS;
- return x;
-}
-
-static jlong
-callLongMethod(JNIEnv *env, jobject object, jmethodID method)
-{
- jlong x;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- x = JNI_FUNC_PTR(env,CallLongMethod)(env, object, method);
- } END_CHECK_EXCEPTIONS;
- return x;
-}
-
-static void
-callVoidMethod(JNIEnv *env, jobject object, jmethodID method, jboolean arg)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- JNI_FUNC_PTR(env,CallVoidMethod)(env, object, method, arg);
- } END_CHECK_EXCEPTIONS;
-}
-
-static jstring
-newStringUTF(JNIEnv *env, const char *name)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jstring string;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(name!=NULL);
- CHECK_EXCEPTIONS(env) {
- string = JNI_FUNC_PTR(env,NewStringUTF)(env, name);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(string!=NULL);
- return string;
-}
-
-static jobject
-newThreadObject(JNIEnv *env, jclass clazz, jmethodID method,
- jthreadGroup group, jstring name)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jthread thread;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- thread = JNI_FUNC_PTR(env,NewObject)(env, clazz, method, group, name);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(thread!=NULL);
- return thread;
-}
-
-jboolean
-isSameObject(JNIEnv *env, jobject o1, jobject o2)
-{
- HPROF_ASSERT(env!=NULL);
- if ( o1 == o2 || JNI_FUNC_PTR(env,IsSameObject)(env, o1, o2) ) {
- return JNI_TRUE;
- }
- return JNI_FALSE;
-}
-
-void
-pushLocalFrame(JNIEnv *env, jint capacity)
-{
- HPROF_ASSERT(env!=NULL);
- CHECK_EXCEPTIONS(env) {
- jint ret;
-
- ret = JNI_FUNC_PTR(env,PushLocalFrame)(env, capacity);
- if ( ret != 0 ) {
- HPROF_ERROR(JNI_TRUE, "JNI PushLocalFrame returned non-zero");
- }
- } END_CHECK_EXCEPTIONS;
-}
-
-void
-popLocalFrame(JNIEnv *env, jobject result)
-{
- jobject ret;
-
- HPROF_ASSERT(env!=NULL);
- ret = JNI_FUNC_PTR(env,PopLocalFrame)(env, result);
- if ( (result != NULL && ret == NULL) || (result == NULL && ret != NULL) ) {
- HPROF_ERROR(JNI_TRUE, "JNI PopLocalFrame returned wrong object");
- }
-}
-
-void
-registerNatives(JNIEnv *env, jclass clazz,
- JNINativeMethod *methods, jint count)
-{
- jint ret;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(methods!=NULL);
- HPROF_ASSERT(count>0);
- ret = JNI_FUNC_PTR(env,RegisterNatives)(env, clazz, methods, count);
- if ( ret != 0 ) {
- HPROF_ERROR(JNI_TRUE, "JNI RegisterNatives returned non-zero");
- }
-}
-
-/* ---------------------------------------------------------------------- */
-/* JVMTI Support Functions */
-
-char *
-getErrorName(jvmtiError error_number)
-{
- char *error_name;
-
- error_name = NULL;
- (void)JVMTI_FUNC_PTR(gdata->jvmti,GetErrorName)
- (gdata->jvmti, error_number, &error_name);
- return error_name;
-}
-
-jvmtiPhase
-getPhase(void)
-{
- jvmtiPhase phase;
-
- phase = 0;
- (void)JVMTI_FUNC_PTR(gdata->jvmti,GetPhase)(gdata->jvmti, &phase);
- return phase;
-}
-
-char *
-phaseString(jvmtiPhase phase)
-{
- switch ( phase ) {
- case JVMTI_PHASE_ONLOAD:
- return "onload";
- case JVMTI_PHASE_PRIMORDIAL:
- return "primordial";
- case JVMTI_PHASE_START:
- return "start";
- case JVMTI_PHASE_LIVE:
- return "live";
- case JVMTI_PHASE_DEAD:
- return "dead";
- }
- return "unknown";
-}
-
-void
-disposeEnvironment(void)
-{
- (void)JVMTI_FUNC_PTR(gdata->jvmti,DisposeEnvironment)
- (gdata->jvmti);
-}
-
-jlong
-getObjectSize(jobject object)
-{
- jlong size;
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- size = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectSize)
- (gdata->jvmti, object, &size);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get object size");
- }
- return size;
-}
-
-static jboolean
-isInterface(jclass klass)
-{
- jvmtiError error;
- jboolean answer;
-
- HPROF_ASSERT(klass!=NULL);
- answer = JNI_FALSE;
- error = JVMTI_FUNC_PTR(gdata->jvmti,IsInterface)
- (gdata->jvmti, klass, &answer);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot call IsInterface");
- }
- return answer;
-}
-
-jint
-getClassStatus(jclass klass)
-{
- jvmtiError error;
- jint status;
-
- HPROF_ASSERT(klass!=NULL);
- status = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassStatus)
- (gdata->jvmti, klass, &status);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- status = 0;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class status");
- }
- return status;
-}
-
-jobject
-getClassLoader(jclass klass)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
- jobject loader;
-
- HPROF_ASSERT(klass!=NULL);
- loader = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoader)
- (gdata->jvmti, klass, &loader);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class loader");
- }
- return loader;
-}
-
-jlong
-getTag(jobject object)
-{
- jlong tag;
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- tag = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetTag)
- (gdata->jvmti, object, &tag);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get object tag");
- }
- return tag;
-}
-
-void
-setTag(jobject object, jlong tag)
-{
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetTag)
- (gdata->jvmti, object, tag);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot set object tag");
- }
-}
-
-void
-getObjectMonitorUsage(jobject object, jvmtiMonitorUsage *uinfo)
-{
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectMonitorUsage)
- (gdata->jvmti, object, uinfo);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get monitor usage info");
- }
-}
-
-void
-getOwnedMonitorInfo(jthread thread, jobject **ppobjects, jint *pcount)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(ppobjects!=NULL);
- HPROF_ASSERT(pcount!=NULL);
- *pcount = 0;
- *ppobjects = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorInfo)
- (gdata->jvmti, thread, pcount, ppobjects);
- if ( error == JVMTI_ERROR_THREAD_NOT_ALIVE ) {
- *pcount = 0;
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread owned monitor info");
- }
-}
-
-void
-getSystemProperty(const char *name, char **value)
-{
- jvmtiError error;
-
- HPROF_ASSERT(name!=NULL);
- *value = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetSystemProperty)
- (gdata->jvmti, name, value);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get system property");
- }
-}
-
-void
-getClassSignature(jclass klass, char** psignature, char **pgeneric_signature)
-{
- jvmtiError error;
- char *generic_signature;
-
- HPROF_ASSERT(klass!=NULL);
- *psignature = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassSignature)
- (gdata->jvmti, klass, psignature, &generic_signature);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class signature");
- }
- if ( pgeneric_signature != NULL ) {
- *pgeneric_signature = generic_signature;
- } else {
- jvmtiDeallocate(generic_signature);
- }
-}
-
-void
-getSourceFileName(jclass klass, char** pname)
-{
- jvmtiError error;
-
- HPROF_ASSERT(klass!=NULL);
- *pname = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName)
- (gdata->jvmti, klass, pname);
- if ( error == JVMTI_ERROR_ABSENT_INFORMATION ) {
- error = JVMTI_ERROR_NONE;
- *pname = NULL;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get source file name");
- }
-}
-
-static void
-getClassFields(jclass klass, jint* pn_fields, jfieldID** pfields)
-{
- jvmtiError error;
- jint status;
-
- HPROF_ASSERT(klass!=NULL);
- *pn_fields = 0;
- *pfields = NULL;
-
- /* Get class status */
- status = getClassStatus(klass);
-
- /* Arrays have no fields */
- if ( status & JVMTI_CLASS_STATUS_ARRAY ) {
- return;
- }
-
- /* Primitives have no fields */
- if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {
- return;
- }
-
- /* If the class is not prepared, we have a problem? */
- if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {
- HPROF_ERROR(JNI_FALSE, "Class not prepared when needing fields");
- return;
- }
-
- /* Now try and get all the fields */
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassFields)
- (gdata->jvmti, klass, pn_fields, pfields);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class field list");
- }
-}
-
-static jint
-getFieldModifiers(jclass klass, jfieldID field)
-{
- jvmtiError error;
- jint modifiers;
-
- HPROF_ASSERT(klass!=NULL);
- HPROF_ASSERT(field!=NULL);
- modifiers = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldModifiers)
- (gdata->jvmti, klass, field, &modifiers);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get field modifiers");
- }
- return modifiers;
-}
-
-static void
-getFieldName(jclass klass, jfieldID field, char** pname, char** psignature,
- char **pgeneric_signature)
-{
- jvmtiError error;
- char *generic_signature;
-
- generic_signature = NULL;
- *pname = NULL;
- *psignature = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldName)
- (gdata->jvmti, klass, field, pname, psignature, &generic_signature);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get field name");
- }
- if ( pgeneric_signature != NULL ) {
- *pgeneric_signature = generic_signature;
- } else {
- jvmtiDeallocate(generic_signature);
- }
-}
-
-static void
-getImplementedInterfaces(jclass klass, jint* pn_interfaces,
- jclass** pinterfaces)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- *pn_interfaces = 0;
- *pinterfaces = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetImplementedInterfaces)
- (gdata->jvmti, klass, pn_interfaces, pinterfaces);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class interface list");
- }
-}
-
-static ClassIndex
-get_cnum(JNIEnv *env, jclass klass)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- ClassIndex cnum;
- LoaderIndex loader_index;
- char *sig;
- jobject loader;
-
- loader = getClassLoader(klass);
- loader_index = loader_find_or_create(env, loader);
- getClassSignature(klass, &sig, NULL);
- cnum = class_find_or_create(sig, loader_index);
- jvmtiDeallocate(sig);
- (void)class_new_classref(env, cnum, klass);
- return cnum;
-}
-
-/* From primitive type, get signature letter */
-char
-primTypeToSigChar(jvmtiPrimitiveType primType)
-{
- char sig_ch;
-
- sig_ch = 0;
- switch ( primType ) {
- case JVMTI_PRIMITIVE_TYPE_BYTE:
- sig_ch = JVM_SIGNATURE_BYTE;
- break;
- case JVMTI_PRIMITIVE_TYPE_CHAR:
- sig_ch = JVM_SIGNATURE_CHAR;
- break;
- case JVMTI_PRIMITIVE_TYPE_FLOAT:
- sig_ch = JVM_SIGNATURE_FLOAT;
- break;
- case JVMTI_PRIMITIVE_TYPE_DOUBLE:
- sig_ch = JVM_SIGNATURE_DOUBLE;
- break;
- case JVMTI_PRIMITIVE_TYPE_INT:
- sig_ch = JVM_SIGNATURE_INT;
- break;
- case JVMTI_PRIMITIVE_TYPE_LONG:
- sig_ch = JVM_SIGNATURE_LONG;
- break;
- case JVMTI_PRIMITIVE_TYPE_SHORT:
- sig_ch = JVM_SIGNATURE_SHORT;
- break;
- case JVMTI_PRIMITIVE_TYPE_BOOLEAN:
- sig_ch = JVM_SIGNATURE_BOOLEAN;
- break;
- default:
- sig_ch = 0;
- break;
- }
- return sig_ch;
-}
-
-/* From signature, get primitive type */
-jvmtiPrimitiveType
-sigToPrimType(char *sig)
-{
- jvmtiPrimitiveType primType;
-
- primType = 0;
- if ( sig == NULL || sig[0] == 0 ) {
- return primType;
- }
- switch ( sig[0] ) {
- case JVM_SIGNATURE_BYTE:
- primType = JVMTI_PRIMITIVE_TYPE_BYTE;
- break;
- case JVM_SIGNATURE_CHAR:
- primType = JVMTI_PRIMITIVE_TYPE_CHAR;
- break;
- case JVM_SIGNATURE_FLOAT:
- primType = JVMTI_PRIMITIVE_TYPE_FLOAT;
- break;
- case JVM_SIGNATURE_DOUBLE:
- primType = JVMTI_PRIMITIVE_TYPE_DOUBLE;
- break;
- case JVM_SIGNATURE_INT:
- primType = JVMTI_PRIMITIVE_TYPE_INT;
- break;
- case JVM_SIGNATURE_LONG:
- primType = JVMTI_PRIMITIVE_TYPE_LONG;
- break;
- case JVM_SIGNATURE_SHORT:
- primType = JVMTI_PRIMITIVE_TYPE_SHORT;
- break;
- case JVM_SIGNATURE_BOOLEAN:
- primType = JVMTI_PRIMITIVE_TYPE_BOOLEAN;
- break;
- }
- return primType;
-}
-
-/* From signature, get primitive size */
-int
-sigToPrimSize(char *sig)
-{
- unsigned size;
-
- size = 0;
- if ( sig == NULL || sig[0] == 0 ) {
- return size;
- }
- switch ( sig[0] ) {
- case JVM_SIGNATURE_BYTE:
- case JVM_SIGNATURE_BOOLEAN:
- size = 1;
- break;
- case JVM_SIGNATURE_CHAR:
- case JVM_SIGNATURE_SHORT:
- size = 2;
- break;
- case JVM_SIGNATURE_FLOAT:
- case JVM_SIGNATURE_INT:
- size = 4;
- break;
- case JVM_SIGNATURE_DOUBLE:
- case JVM_SIGNATURE_LONG:
- size = 8;
- break;
- }
- return size;
-}
-
-static void
-add_class_fields(JNIEnv *env, ClassIndex top_cnum, ClassIndex cnum,
- jclass klass, Stack *field_list, Stack *class_list)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass *interfaces;
- jint n_interfaces;
- jfieldID *idlist;
- jint n_fields;
- int i;
- int depth;
- int skip_static_field_names;
- jint status;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(klass!=NULL);
- HPROF_ASSERT(field_list!=NULL);
- HPROF_ASSERT(class_list!=NULL);
-
- /* If not the initial class, we can skip the static fields (perf issue) */
- skip_static_field_names = (cnum != top_cnum);
-
- /* Get class status */
- status = getClassStatus(klass);
-
- /* Arrays have no fields */
- if ( status & JVMTI_CLASS_STATUS_ARRAY ) {
- return;
- }
-
- /* Primitives have no fields */
- if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {
- return;
- }
-
- /* If the class is not prepared, we have a problem? */
- if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {
- char *sig;
-
- getClassSignature(klass, &sig, NULL);
- debug_message("Class signature is: %s\n", sig);
- HPROF_ERROR(JNI_FALSE, "Class not prepared when needing all fields");
- jvmtiDeallocate(sig);
- return;
- }
-
- /* See if class already processed */
- depth = stack_depth(class_list);
- for ( i = depth-1 ; i >= 0 ; i-- ) {
- if ( isSameObject(env, klass, *(jclass*)stack_element(class_list, i)) ) {
- return;
- }
- }
-
- /* Class or Interface, do implemented interfaces recursively */
- getImplementedInterfaces(klass, &n_interfaces, &interfaces);
- for ( i = 0 ; i < n_interfaces ; i++ ) {
- add_class_fields(env, top_cnum,
- get_cnum(env, interfaces[i]), interfaces[i],
- field_list, class_list);
- }
- jvmtiDeallocate(interfaces);
-
- /* Begin graph traversal, go up super chain recursively */
- if ( !isInterface(klass) ) {
- jclass super_klass;
-
- super_klass = getSuperclass(env, klass);
- if ( super_klass != NULL ) {
- add_class_fields(env, top_cnum,
- get_cnum(env, super_klass), super_klass,
- field_list, class_list);
- }
- }
-
-
- /* Only now we add klass to list so we don't repeat it later */
- stack_push(class_list, &klass);
-
- /* Now actually add the fields for this klass */
- getClassFields(klass, &n_fields, &idlist);
- for ( i = 0 ; i < n_fields ; i++ ) {
- FieldInfo finfo;
- static FieldInfo empty_finfo;
-
- finfo = empty_finfo;
- finfo.cnum = cnum;
- finfo.modifiers = (unsigned short)getFieldModifiers(klass, idlist[i]);
- if ( ( finfo.modifiers & JVM_ACC_STATIC ) == 0 ||
- !skip_static_field_names ) {
- char *field_name;
- char *field_sig;
-
- getFieldName(klass, idlist[i], &field_name, &field_sig, NULL);
- finfo.name_index = string_find_or_create(field_name);
- finfo.sig_index = string_find_or_create(field_sig);
- finfo.primType = sigToPrimType(field_sig);
- finfo.primSize = sigToPrimSize(field_sig);
- jvmtiDeallocate(field_name);
- jvmtiDeallocate(field_sig);
- }
- stack_push(field_list, &finfo);
- }
- jvmtiDeallocate(idlist);
-}
-
-void
-getAllClassFieldInfo(JNIEnv *env, jclass klass,
- jint* pn_fields, FieldInfo** pfields)
-{
- ClassIndex cnum;
-
- *pfields = NULL;
- *pn_fields = 0;
-
- WITH_LOCAL_REFS(env, 1) {
- Stack *class_list;
- Stack *field_list;
- int nbytes;
-
- cnum = get_cnum(env, klass);
- class_list = stack_init( 16, 16, (int)sizeof(jclass));
- field_list = stack_init(128, 128, (int)sizeof(FieldInfo));
- add_class_fields(env, cnum, cnum, klass, field_list, class_list);
- *pn_fields = stack_depth(field_list);
- if ( (*pn_fields) > 0 ) {
- nbytes = (*pn_fields) * (int)sizeof(FieldInfo);
- *pfields = (FieldInfo*)HPROF_MALLOC(nbytes);
- (void)memcpy(*pfields, stack_element(field_list, 0), nbytes);
- }
- stack_term(field_list);
- stack_term(class_list);
- } END_WITH_LOCAL_REFS;
-}
-
-void
-getMethodClass(jmethodID method, jclass *pclazz)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(method!=NULL);
- *pclazz = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
- (gdata->jvmti, method, pclazz);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get method class");
- }
-}
-
-jboolean
-isMethodNative(jmethodID method)
-{
- jvmtiError error;
- jboolean isNative;
-
- HPROF_ASSERT(method!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodNative)
- (gdata->jvmti, method, &isNative);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot check is method native");
- }
- return isNative;
-}
-
-void
-getMethodName(jmethodID method, char** pname, char** psignature)
-{
- jvmtiError error;
- char *generic_signature;
-
- HPROF_ASSERT(method!=NULL);
- generic_signature = NULL;
- *pname = NULL;
- *psignature = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodName)
- (gdata->jvmti, method, pname, psignature, &generic_signature);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get method name");
- }
- jvmtiDeallocate(generic_signature);
-}
-
-void
-getPotentialCapabilities(jvmtiCapabilities *pcapabilities)
-{
- jvmtiError error;
-
- (void)memset(pcapabilities,0,sizeof(jvmtiCapabilities));
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetPotentialCapabilities)
- (gdata->jvmti, pcapabilities);
- if (error != JVMTI_ERROR_NONE) {
- HPROF_ERROR(JNI_FALSE, "Unable to get potential JVMTI capabilities.");
- error_exit_process(1); /* Kill entire process, no core dump wanted */
- }
-}
-
-void
-addCapabilities(jvmtiCapabilities *pcapabilities)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,AddCapabilities)
- (gdata->jvmti, pcapabilities);
- if (error != JVMTI_ERROR_NONE) {
- HPROF_ERROR(JNI_FALSE, "Unable to get necessary JVMTI capabilities.");
- error_exit_process(1); /* Kill entire process, no core dump wanted */
- }
-}
-
-void
-setEventCallbacks(jvmtiEventCallbacks *pcallbacks)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
- (gdata->jvmti, pcallbacks, (int)sizeof(jvmtiEventCallbacks));
- if (error != JVMTI_ERROR_NONE) {
- HPROF_JVMTI_ERROR(error, "Cannot set jvmti callbacks");
- }
-
-}
-
-void *
-getThreadLocalStorage(jthread thread)
-{
- jvmtiError error;
- void *ptr;
-
- HPROF_ASSERT(thread!=NULL);
- ptr = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadLocalStorage)
- (gdata->jvmti, thread, &ptr);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- ptr = NULL;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread local storage");
- }
- return ptr;
-}
-
-void
-setThreadLocalStorage(jthread thread, void *ptr)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetThreadLocalStorage)
- (gdata->jvmti, thread, (const void *)ptr);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot set thread local storage");
- }
-}
-
-void
-getThreadState(jthread thread, jint *threadState)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(threadState!=NULL);
- *threadState = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadState)
- (gdata->jvmti, thread, threadState);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread state");
- }
-}
-
-void
-getThreadInfo(jthread thread, jvmtiThreadInfo *info)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(info!=NULL);
- (void)memset((void*)info, 0, sizeof(jvmtiThreadInfo));
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
- (gdata->jvmti, thread, info);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread info");
- }
-}
-
-void
-getThreadGroupInfo(jthreadGroup thread_group, jvmtiThreadGroupInfo *info)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(info!=NULL);
- (void)memset((void*)info, 0, sizeof(jvmtiThreadGroupInfo));
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadGroupInfo)
- (gdata->jvmti, thread_group, info);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread group info");
- }
-}
-
-void
-getLoadedClasses(jclass **ppclasses, jint *pcount)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- *ppclasses = NULL;
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetLoadedClasses)
- (gdata->jvmti, pcount, ppclasses);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get all loaded class list");
- }
-}
-
-static void
-getLineNumberTable(jmethodID method, jvmtiLineNumberEntry **ppentries,
- jint *pcount)
-{
- jvmtiError error;
-
- HPROF_ASSERT(method!=NULL);
- *ppentries = NULL;
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetLineNumberTable)
- (gdata->jvmti, method, pcount, ppentries);
- if ( error == JVMTI_ERROR_ABSENT_INFORMATION ) {
- error = JVMTI_ERROR_NONE;
- *ppentries = NULL;
- *pcount = 0;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get source line numbers");
- }
-}
-
-static jint
-map_loc2line(jlocation location, jvmtiLineNumberEntry *table, jint count)
-{
- jint line_number;
- int i;
- int start;
- int half;
-
- HPROF_ASSERT(location>=0);
- HPROF_ASSERT(count>=0);
-
- line_number = -1;
- if ( count == 0 ) {
- return line_number;
- }
-
- /* Do a binary search */
- half = count >> 1;
- start = 0;
- while ( half > 0 ) {
- jlocation start_location;
-
- start_location = table[start + half].start_location;
- if ( location > start_location ) {
- start = start + half;
- } else if ( location == start_location ) {
- start = start + half;
- break;
- }
- half = half >> 1;
- }
-
- HPROF_ASSERT(start < count);
-
- /* Now start the table search */
- for ( i = start ; i < count ; i++ ) {
- if ( location < table[i].start_location ) {
- HPROF_ASSERT( ((int)location) < ((int)table[i].start_location) );
- break;
- }
- line_number = table[i].line_number;
- }
- HPROF_ASSERT(line_number > 0);
- return line_number;
-}
-
-jint
-getLineNumber(jmethodID method, jlocation location)
-{
- jvmtiLineNumberEntry *line_table;
- jint line_count;
- jint lineno;
-
- HPROF_ASSERT(method!=NULL);
- if ( location < 0 ) {
- HPROF_ASSERT(location > -4);
- return (jint)location;
- }
- lineno = -1;
-
- getLineNumberTable(method, &line_table, &line_count);
- lineno = map_loc2line(location, line_table, line_count);
- jvmtiDeallocate(line_table);
-
- return lineno;
-}
-
-jlong
-getMaxMemory(JNIEnv *env)
-{
- jlong max;
-
- HPROF_ASSERT(env!=NULL);
-
- max = (jlong)0;
- WITH_LOCAL_REFS(env, 1) {
- jclass clazz;
- jmethodID getRuntime;
- jobject runtime;
- jmethodID maxMemory;
-
- clazz = findClass(env, "java/lang/Runtime");
- getRuntime = getStaticMethodID(env, clazz, "getRuntime",
- "()Ljava/lang/Runtime;");
- runtime = callStaticObjectMethod(env, clazz, getRuntime);
- maxMemory = getMethodID(env, clazz, "maxMemory", "()J");
- max = callLongMethod(env, runtime, maxMemory);
- } END_WITH_LOCAL_REFS;
- return max;
-}
-
-void
-createAgentThread(JNIEnv *env, const char *name, jvmtiStartFunction func)
-{
- jvmtiError error;
-
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(func!=NULL);
-
- WITH_LOCAL_REFS(env, 1) {
- jclass clazz;
- jmethodID threadConstructor;
- jmethodID threadSetDaemon;
- jthread thread;
- jstring nameString;
- jthreadGroup systemThreadGroup;
- jthreadGroup * groups;
- jint groupCount;
-
- thread = NULL;
- systemThreadGroup = NULL;
- groups = NULL;
- clazz = class_get_class(env, gdata->thread_cnum);
- HPROF_ASSERT(clazz!=NULL);
- threadConstructor = getMethodID(env, clazz, "<init>",
- "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
- threadSetDaemon = getMethodID(env, clazz, "setDaemon",
- "(Z)V");
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
- (gdata->jvmti, &groupCount, &groups);
- if ( error == JVMTI_ERROR_NONE ) {
- if ( groupCount > 0 ) {
- systemThreadGroup = groups[0];
- }
- jvmtiDeallocate(groups);
-
- nameString = newStringUTF(env, name);
- HPROF_ASSERT(nameString!=NULL);
- thread = newThreadObject(env, clazz, threadConstructor,
- systemThreadGroup, nameString);
- HPROF_ASSERT(thread!=NULL);
- callVoidMethod(env, thread, threadSetDaemon, JNI_TRUE);
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RunAgentThread)
- (gdata->jvmti, thread, func, NULL, JVMTI_THREAD_MAX_PRIORITY);
-
- /* After the thread is running... */
-
- /* Make sure the TLS table has this thread as an agent thread */
- tls_agent_thread(env, thread);
- }
- } END_WITH_LOCAL_REFS;
-
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot create agent thread");
- }
-}
-
-jlong
-getThreadCpuTime(jthread thread)
-{
- jvmtiError error;
- jlong cpuTime;
-
- HPROF_ASSERT(thread!=NULL);
- cpuTime = -1;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadCpuTime)
- (gdata->jvmti, thread, &cpuTime);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get cpu time");
- }
- return cpuTime;
-}
-
-/* Get frame count */
-void
-getFrameCount(jthread thread, jint *pcount)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(pcount!=NULL);
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
- (gdata->jvmti, thread, pcount);
- if ( error != JVMTI_ERROR_NONE ) {
- *pcount = 0;
- }
-}
-
-/* Get call trace */
-void
-getStackTrace(jthread thread, jvmtiFrameInfo *pframes, jint depth, jint *pcount)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(pframes!=NULL);
- HPROF_ASSERT(depth >= 0);
- HPROF_ASSERT(pcount!=NULL);
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetStackTrace)
- (gdata->jvmti, thread, 0, depth, pframes, pcount);
- if ( error != JVMTI_ERROR_NONE ) {
- *pcount = 0;
- }
-}
-
-void
-getThreadListStackTraces(jint count, jthread *threads,
- jint depth, jvmtiStackInfo **stack_info)
-{
- jvmtiError error;
-
- HPROF_ASSERT(threads!=NULL);
- HPROF_ASSERT(stack_info!=NULL);
- HPROF_ASSERT(depth >= 0);
- HPROF_ASSERT(count > 0);
- *stack_info = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadListStackTraces)
- (gdata->jvmti, count, threads, depth, stack_info);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread list stack info");
- }
-}
-
-void
-followReferences(jvmtiHeapCallbacks *pHeapCallbacks, void *user_data)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,FollowReferences)
- (gdata->jvmti, 0, NULL, NULL, pHeapCallbacks, user_data);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot follow references");
- }
-}
-
-/* GC control */
-void
-runGC(void)
-{
- jvmtiError error;
- error = JVMTI_FUNC_PTR(gdata->jvmti,ForceGarbageCollection)
- (gdata->jvmti);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot force garbage collection");
- }
-}
-
-/* ------------------------------------------------------------------- */
-/* Getting the initial JVMTI environment */
-
-void
-getJvmti(void)
-{
- jvmtiEnv *jvmti = NULL;
- jint res;
- jint jvmtiCompileTimeMajorVersion;
- jint jvmtiCompileTimeMinorVersion;
- jint jvmtiCompileTimeMicroVersion;
-
- res = JVM_FUNC_PTR(gdata->jvm,GetEnv)
- (gdata->jvm, (void **)&jvmti, JVMTI_VERSION_1);
- if (res != JNI_OK) {
- char buf[256];
-
- (void)md_snprintf(buf, sizeof(buf),
- "Unable to access JVMTI Version 1 (0x%x),"
- " is your JDK a 5.0 or newer version?"
- " JNIEnv's GetEnv() returned %d",
- JVMTI_VERSION_1, res);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_FALSE, buf);
- error_exit_process(1); /* Kill entire process, no core dump */
- }
- gdata->jvmti = jvmti;
-
- /* Check to make sure the version of jvmti.h we compiled with
- * matches the runtime version we are using.
- */
- jvmtiCompileTimeMajorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MAJOR )
- >> JVMTI_VERSION_SHIFT_MAJOR;
- jvmtiCompileTimeMinorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MINOR )
- >> JVMTI_VERSION_SHIFT_MINOR;
- jvmtiCompileTimeMicroVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MICRO )
- >> JVMTI_VERSION_SHIFT_MICRO;
- if ( !compatible_versions(jvmtiMajorVersion(), jvmtiMinorVersion(),
- jvmtiCompileTimeMajorVersion, jvmtiCompileTimeMinorVersion) ) {
- char buf[256];
-
- (void)md_snprintf(buf, sizeof(buf),
- "This " AGENTNAME " native library will not work with this VM's "
- "version of JVMTI (%d.%d.%d), it needs JVMTI %d.%d[.%d]."
- ,
- jvmtiMajorVersion(),
- jvmtiMinorVersion(),
- jvmtiMicroVersion(),
- jvmtiCompileTimeMajorVersion,
- jvmtiCompileTimeMinorVersion,
- jvmtiCompileTimeMicroVersion);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_FALSE, buf);
- error_exit_process(1); /* Kill entire process, no core dump wanted */
- }
-}
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_util.h Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +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_UTIL_H
-#define HPROF_UTIL_H
-
-/* Use THIS_FILE when it is available. */
-#ifndef THIS_FILE
- #define THIS_FILE __FILE__
-#endif
-
-/* Macros that protect code from accidently using a local ref improperly */
-#define WITH_LOCAL_REFS(env, number) \
- { \
- JNIEnv *_env = (env); \
- pushLocalFrame(_env, number); \
- { /* BEGINNING OF WITH SCOPE */
-
-#define END_WITH_LOCAL_REFS \
- } /* END OF WITH SCOPE */ \
- popLocalFrame(_env, NULL); \
- }
-
-/* Macro to check for exceptions after JNI calls. */
-#define CHECK_EXCEPTIONS(env) \
- { \
- JNIEnv *_env = (env); \
- jobject _exception; \
- _exception = exceptionOccurred(_env); \
- if ( _exception != NULL ) { \
- exceptionDescribe(_env); \
- HPROF_ERROR(JNI_TRUE, "Unexpected Exception found beforehand");\
- } \
- {
-
-#define END_CHECK_EXCEPTIONS \
- } \
- _exception = exceptionOccurred(_env); \
- if ( _exception != NULL ) { \
- exceptionDescribe(_env); \
- HPROF_ERROR(JNI_TRUE, "Unexpected Exception found afterward");\
- } \
- }
-
-JNIEnv * getEnv(void);
-
-/* JNI support functions */
-jobject newGlobalReference(JNIEnv *env, jobject object);
-jobject newWeakGlobalReference(JNIEnv *env, jobject object);
-void deleteGlobalReference(JNIEnv *env, jobject object);
-jobject newLocalReference(JNIEnv *env, jobject object);
-void deleteLocalReference(JNIEnv *env, jobject object);
-void deleteWeakGlobalReference(JNIEnv *env, jobject object);
-jclass getObjectClass(JNIEnv *env, jobject object);
-jmethodID getMethodID(JNIEnv *env, jclass clazz, const char* name,
- const char *sig);
-jclass getSuperclass(JNIEnv *env, jclass klass);
-jmethodID getStaticMethodID(JNIEnv *env, jclass clazz, const char* name,
- const char *sig);
-jfieldID getStaticFieldID(JNIEnv *env, jclass clazz, const char* name,
- const char *sig);
-jclass findClass(JNIEnv *env, const char *name);
-void setStaticIntField(JNIEnv *env, jclass clazz, jfieldID field,
- jint value);
-jboolean isSameObject(JNIEnv *env, jobject o1, jobject o2);
-void pushLocalFrame(JNIEnv *env, jint capacity);
-void popLocalFrame(JNIEnv *env, jobject ret);
-jobject exceptionOccurred(JNIEnv *env);
-void exceptionDescribe(JNIEnv *env);
-void exceptionClear(JNIEnv *env);
-void registerNatives(JNIEnv *env, jclass clazz,
- JNINativeMethod *methods, jint count);
-
-/* More JVMTI support functions */
-char * getErrorName(jvmtiError error_number);
-jvmtiPhase getPhase(void);
-char * phaseString(jvmtiPhase phase);
-void disposeEnvironment(void);
-jlong getObjectSize(jobject object);
-jobject getClassLoader(jclass klass);
-jint getClassStatus(jclass klass);
-jlong getTag(jobject object);
-void setTag(jobject object, jlong tag);
-void getObjectMonitorUsage(jobject object, jvmtiMonitorUsage *uinfo);
-void getOwnedMonitorInfo(jthread thread, jobject **ppobjects,
- jint *pcount);
-void getSystemProperty(const char *name, char **value);
-void getClassSignature(jclass klass, char**psignature,
- char **pgeneric_signature);
-void getSourceFileName(jclass klass, char** src_name_ptr);
-
-jvmtiPrimitiveType sigToPrimType(char *sig);
-int sigToPrimSize(char *sig);
-char primTypeToSigChar(jvmtiPrimitiveType primType);
-
-void getAllClassFieldInfo(JNIEnv *env, jclass klass,
- jint* field_count_ptr, FieldInfo** fields_ptr);
-void getMethodName(jmethodID method, char** name_ptr,
- char** signature_ptr);
-void getMethodClass(jmethodID method, jclass *pclazz);
-jboolean isMethodNative(jmethodID method);
-void getPotentialCapabilities(jvmtiCapabilities *capabilities);
-void addCapabilities(jvmtiCapabilities *capabilities);
-void setEventCallbacks(jvmtiEventCallbacks *pcallbacks);
-void setEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event,
- jthread thread);
-void * getThreadLocalStorage(jthread thread);
-void setThreadLocalStorage(jthread thread, void *ptr);
-void getThreadState(jthread thread, jint *threadState);
-void getThreadInfo(jthread thread, jvmtiThreadInfo *info);
-void getThreadGroupInfo(jthreadGroup thread_group, jvmtiThreadGroupInfo *info);
-void getLoadedClasses(jclass **ppclasses, jint *pcount);
-jint getLineNumber(jmethodID method, jlocation location);
-jlong getMaxMemory(JNIEnv *env);
-void createAgentThread(JNIEnv *env, const char *name,
- jvmtiStartFunction func);
-jlong getThreadCpuTime(jthread thread);
-void getStackTrace(jthread thread, jvmtiFrameInfo *pframes, jint depth,
- jint *pcount);
-void getThreadListStackTraces(jint count, jthread *threads,
- jint depth, jvmtiStackInfo **stack_info);
-void getFrameCount(jthread thread, jint *pcount);
-void followReferences(jvmtiHeapCallbacks *pHeapCallbacks, void *user_data);
-
-/* GC control */
-void runGC(void);
-
-/* Get initial JVMTI environment */
-void getJvmti(void);
-
-/* Get current runtime JVMTI version */
-jint jvmtiVersion(void);
-
-/* Raw monitor functions */
-jrawMonitorID createRawMonitor(const char *str);
-void rawMonitorEnter(jrawMonitorID m);
-void rawMonitorWait(jrawMonitorID m, jlong pause_time);
-void rawMonitorNotifyAll(jrawMonitorID m);
-void rawMonitorExit(jrawMonitorID m);
-void destroyRawMonitor(jrawMonitorID m);
-
-/* JVMTI alloc/dealloc */
-void * jvmtiAllocate(int size);
-void jvmtiDeallocate(void *ptr);
-
-/* System malloc/free */
-void * hprof_malloc(int size);
-void hprof_free(void *ptr);
-
-#include "debug_malloc.h"
-
-#ifdef DEBUG
- void * hprof_debug_malloc(int size, char *file, int line);
- void hprof_debug_free(void *ptr, char *file, int line);
- #define HPROF_MALLOC(size) hprof_debug_malloc(size, THIS_FILE, __LINE__)
- #define HPROF_FREE(ptr) hprof_debug_free(ptr, THIS_FILE, __LINE__)
-#else
- #define HPROF_MALLOC(size) hprof_malloc(size)
- #define HPROF_FREE(ptr) hprof_free(ptr)
-#endif
-
-#endif
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/jvm.hprof.txt Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +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.
-
-
-Header for -agentlib:hprof (or -Xrunhprof) ASCII Output (JDK 5.0 JVMTI based)
-
-WARNING! This file format is under development, and is subject to
-change without notice.
-
-This file contains the following types of records:
-
-THREAD START
-THREAD END mark the lifetime of Java threads
-
-TRACE represents a Java stack trace. Each trace consists
- of a series of stack frames. Other records refer to
- TRACEs to identify (1) where object allocations have
- taken place, (2) the frames in which GC roots were
- found, and (3) frequently executed methods.
-
-HEAP DUMP is a complete snapshot of all live objects in the Java
- heap. Following distinctions are made:
-
- ROOT root set as determined by GC
- CLS classes
- OBJ instances
- ARR arrays
-
-SITES is a sorted list of allocation sites. This identifies
- the most heavily allocated object types, and the TRACE
- at which those allocations occurred.
-
-CPU SAMPLES is a statistical profile of program execution. The VM
- periodically samples all running threads, and assigns
- a quantum to active TRACEs in those threads. Entries
- in this record are TRACEs ranked by the percentage of
- total quanta they consumed; top-ranked TRACEs are
- typically hot spots in the program.
-
-CPU TIME is a profile of program execution obtained by measuring
- the time spent in individual methods (excluding the time
- spent in callees), as well as by counting the number of
- times each method is called. Entries in this record are
- TRACEs ranked by the percentage of total CPU time. The
- "count" field indicates the number of times each TRACE
- is invoked.
-
-MONITOR TIME is a profile of monitor contention obtained by measuring
- the time spent by a thread waiting to enter a monitor.
- Entries in this record are TRACEs ranked by the percentage
- of total monitor contention time and a brief description
- of the monitor. The "count" field indicates the number of
- times the monitor was contended at that TRACE.
-
-MONITOR DUMP is a complete snapshot of all the monitors and threads in
- the System.
-
-HEAP DUMP, SITES, CPU SAMPLES|TIME and MONITOR DUMP|TIME records are generated
-at program exit. They can also be obtained during program execution by typing
-Ctrl-\ (on Solaris) or by typing Ctrl-Break (on Win32).
--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/manual.html Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1737 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <meta content="deepa viswanathan" name="Author">
- <meta content="Mozilla/4.04 [en] (WinNT; U) [Netscape]"
- name="GENERATOR">
- <title>HPROF Agent</title>
- <meta name="author" content="Kelly O'Hair">
-</head>
-<body alink="#ff0000" bgcolor="#ffffff" link="#0000ee" text="#000000"
- vlink="#551a8b">
-<h1 style="text-align: center;"><a name="mozTocId137594"
- class="mozTocH1"></a><span style="font-weight: bold;"></span>HPROF
-Agent<br>
-</h1>
-<h2><a name="mozTocId558923" class="mozTocH2"></a>Contents</h2>
-<span style="text-decoration: underline;"></span>
-<ol id="mozToc">
-<!--mozToc h1 1 h2 2 h3 3 h4 4 h5 5 h6 6--><li><a href="#mozTocId137594">HPROF
-Agent</a>
- <ol>
- <li><a href="#mozTocId558923">Contents</a></li>
- <li><a href="#mozTocId550204">Overview</a></li>
- <li><a href="#mozTocId634758">Start-up</a></li>
- <li><a href="#mozTocId708821">Heap Allocation
-Profiles (heap=sites) </a></li>
- <li><a href="#mozTocId634725">Heap Dump (heap=dump)</a></li>
- <li><a href="#mozTocId546448">CPU Usage Sampling
-Profiles (cpu=samples) </a></li>
- <li><a href="#mozTocId116568">CPU Usage Times Profile (cpu=times)
- </a></li>
- <li><a href="#mozTocId848088">Binary Dump Format
-(format=b)</a>
- <ol>
- <li><a href="#mozTocId348369">Socket Connection and
-Communication</a></li>
- </ol>
- <ol>
- <li><a href="#mozTocId348360">Handling of Arrays</a></li>
- </ol>
- </li>
- <li><a href="#mozTocId589424">Source Code </a></li>
- </ol>
- </li>
-</ol>
-<span style="text-decoration: underline;"></span>
-<h2><a name="mozTocId550204" class="mozTocH2"></a>Overview</h2>
-<p>This document describes the JVM TI Agent HPROF delivered in
-the Java Development Kit (JDK). It is intended as demonstration code
-for JVM TI, and as a functional
-replacement for the older HPROF JVMPI Agent delivered in past releases.<br>
-</p>
-Previous 1.4 and earlier releases of the JDK contained an HPROF
-agent built on the experimental JVMPI.
-The newer JVM TI replaces both JVMDI and JVMPI.
-<p><span style="font-weight: bold;">Note</span>: Differences between
-this HPROF implementation and the older JVMPI based HPROF are marked in
-<span style="font-style: italic; color: rgb(255, 0, 0);">RED ITALICS</span>
-throughout this document.<br>
-</p>
-<br>
-<h2><a name="mozTocId634758" class="mozTocH3"></a>Start-up</h2>
-<p>HPROF is a simple profiler agent shipped with the JDK. It is
-a dynamically-linked
-library that interacts with the JVM TI and
-writes out profiling
-information either to a file or to a socket in ascii or binary format.
-This information can
-be further processed by a profiler front-end tool.</p>
-<p>It is capable of presenting CPU usage, heap allocation statistics
-and monitor contention
-profiles. In addition it can also report complete heap dumps and states
-of all the monitors and threads in the Java virtual machine.
-</p>
-<p>HPROF can be invoked by:
-</p>
-<pre>java -<span style="font-weight: bold;">agentlib:</span><b>hprof</b> ToBeProfiledClass</pre>
-Depending on the type of profiling requested, HPROF instructs the
-virtual machine to send it the relevant JVM TI events and processes
-the event data into profiling information. For example, the following
-command obtains the heap allocation profile:
-<pre>java -agentlib:hprof=heap=sites ToBeProfiledClass</pre>
-Following is the complete list of options that can passed to hprof :
-<blockquote>
- <pre>java -agentlib:hprof=help<br><br> HPROF: Heap and CPU Profiling Agent (JVMTI Demonstration Code)<br><br>hprof usage: java -agentlib:hprof=[help]|[<option>=<value>, ...]<br><br>Option Name and Value Description Default<br>--------------------- ----------- -------<br>heap=dump|sites|all heap profiling all<br>cpu=samples|times|old CPU usage off<br>monitor=y|n monitor contention n<br>format=a|b text(txt) or binary output a<br>file=<file> write data to file java.hprof[{.txt}]<br>net=<host>:<port> send data over a socket off<br>depth=<size> stack trace depth 4<br>interval=<ms> sample interval in ms 10<br>cutoff=<value> output cutoff point 0.0001<br>lineno=y|n line number in traces? y<br>thread=y|n thread in traces? n<br>doe=y|n dump on exit? y<br>msa=y|n Solaris micro state accounting n<br>force=y|n force output to <file> y<br>verbose=y|n print messages about dumps y<br><br>Obsolete Options<br>----------------<br>gc_okay=y|n<br><br>Examples<br>--------<br> - Get sample cpu information every 20 millisec, with a stack depth of 3:<br> java -agentlib:hprof=cpu=samples,interval=20,depth=3 classname<br> - Get heap usage information based on the allocation sites:<br> java -agentlib:hprof=heap=sites classname<br><br>Notes<br>-----<br> - The option format=b cannot be used with monitor=y.<br> - The option format=b cannot be used with cpu=old|times.<br> - Use of the -Xrunhprof interface can still be used, e.g.<br> java -Xrunhprof:[help]|[<option>=<value>, ...]<br> will behave exactly the same as:<br> java -agentlib:hprof=[help]|[<option>=<value>, ...]<br><br>Warnings<br>--------<br> - This is demonstration code for the JVMTI interface and use of BCI,<br> it is not an official product or formal part of the JDK.<br> - The -Xrunhprof interface will be removed in a future release.<br> - The option format=b is considered experimental, this format may change<br> in a future release.<br></pre>
-</blockquote>
-<p>By default, heap profiling information (sites and dump) is written
-out
-to java.hprof.txt (ascii).
-The monitor=y|n option has proven to be problematic and may be replaced
-with something more useful.<br>
-</p>
-<p>The output in most cases will contain ID's for traces, threads,
-objects, etc. Each type of ID will typically start with a
-different number than the other ID's, e.g. traces might start with
-300000.<br>
-</p>
-<p><span style="font-weight: bold;">Note</span>: <span
- style="font-style: italic; color: rgb(255, 0, 0);">The gc_okay option
-is no longer supported.</span><br>
-</p>
-<h2><a name="mozTocId708821" class="mozTocH4"></a>Heap Allocation
-Profiles (heap=sites)<br>
-</h2>
-Following is the heap allocation profile generated by running the Java
-compiler
-(<code>javac</code>) on a set of input files. Only parts of the
-profiler output are shown here.
-<p></p>
-<pre>Command used: javac -J-agentlib:hprof=heap=sites Hello.java<br><br>SITES BEGIN (ordered by live bytes) Fri Feb 6 13:13:42 2004<br> percent live alloc'ed stack class<br> rank self accum bytes objs bytes objs trace name<br> 1 44.13% 44.13% 1117360 13967 1117360 13967 301926 java.util.zip.ZipEntry<br> 2 8.83% 52.95% 223472 13967 223472 13967 301927 com.sun.tools.javac.util.List<br> 3 5.18% 58.13% 131088 1 131088 1 300996 byte[]<br> 4 5.18% 63.31% 131088 1 131088 1 300995 com.sun.tools.javac.util.Name[]<br> <br></pre>
-A crucial piece of information in heap profile is the amount of
-allocation that occurs
-in various parts of the program. The <code>SITES</code> record above
-tells us that 44.13% of the total space was allocated for
-java.util.zip.ZipEntry objects. Note that the amount of live data is
-only a fraction
-of the total allocation that has occurred at a given site; the rest has
-been garbage collected.
-<p>A good way to relate allocation sites to the source code is to
-record
-the dynamic stack traces that led to the heap allocation. Following is
-another part of the profiler output that illustrates the stack traces
-referred to by the four allocation sites in output shown above.
-<span style="font-family: monospace;"><br>
-</span></p>
-<pre><span style="font-family: monospace;"></span>TRACE 301926:<br> java.util.zip.ZipEntry.<init>(ZipEntry.java:101)<br> java.util.zip.ZipFile+3.nextElement(ZipFile.java:417)<br> com.sun.tools.javac.jvm.ClassReader.openArchive(ClassReader.java:1374)<br> com.sun.tools.javac.jvm.ClassReader.list(ClassReader.java:1631)<br><br>TRACE 301927:<br> com.sun.tools.javac.util.List.<init>(List.java:42)<br> com.sun.tools.javac.util.List.<init>(List.java:50)<br> com.sun.tools.javac.util.ListBuffer.append(ListBuffer.java:94)<br> com.sun.tools.javac.jvm.ClassReader.openArchive(ClassReader.java:1374)<br><br>TRACE 300996:<br> com.sun.tools.javac.util.Name$Table.<init>(Name.java:379)<br> com.sun.tools.javac.util.Name$Table.<init>(Name.java:481)<br> com.sun.tools.javac.util.Name$Table.make(Name.java:332)<br> com.sun.tools.javac.util.Name$Table.instance(Name.java:349)<br><br>TRACE 300995:<br> com.sun.tools.javac.util.Name$Table.<init>(Name.java:378)<br> com.sun.tools.javac.util.Name$Table.<init>(Name.java:481)<br> com.sun.tools.javac.util.Name$Table.make(Name.java:332)<br> com.sun.tools.javac.util.Name$Table.instance(Name.java:349)<init><init><init><br></init></init></init></pre>
-<blockquote></blockquote>
-<p>
-Each frame in the stack trace contains class name, method name, source
-file name, and the line number. The user can set the maximum number
-of frames collected by the HPROF agent. The default limit is 4. Stack
-traces reveal not only which methods performed heap allocation, but
-also which methods were ultimately responsible for making calls that
-resulted in memory allocation. <br>
-</p>
-<h2><a name="mozTocId634725" class="mozTocH2"></a>Heap Dump (heap=dump)</h2>
-A complete dump of the current live objects in the heap can be obtained
-with:<br>
-<pre>Command used: javac -J-agentlib:hprof=heap=dump Hello.java<br></pre>
-This is a very large output file, but can be viewed and searched in any
-editor.<br>
-<br>
-<h2><a name="mozTocId546448" class="mozTocH4"></a>CPU Usage Sampling
-Profiles (cpu=samples)<br>
-</h2>
-HPROF can collect CPU usage information by sampling threads. Following
-is part of the output collected from a run
-of the <code>javac</code> compiler.
-<p></p>
-<pre>Command used: javac -J-agentlib:hprof=cpu=samples Hello.java<br><br>CPU SAMPLES BEGIN (total = 462) Fri Feb 6 13:33:07 2004<br>rank self accum count trace method<br> 1 49.57% 49.57% 229 300187 java.util.zip.ZipFile.getNextEntry<br> 2 6.93% 56.49% 32 300190 java.util.zip.ZipEntry.initFields<br> 3 4.76% 61.26% 22 300122 java.lang.ClassLoader.defineClass2<br> 4 2.81% 64.07% 13 300188 java.util.zip.ZipFile.freeEntry<br> 5 1.95% 66.02% 9 300129 java.util.Vector.addElement<br> 6 1.73% 67.75% 8 300124 java.util.zip.ZipFile.getEntry<br> 7 1.52% 69.26% 7 300125 java.lang.ClassLoader.findBootstrapClass<br> 8 0.87% 70.13% 4 300172 com.sun.tools.javac.main.JavaCompiler.<init><br> 9 0.65% 70.78% 3 300030 java.util.zip.ZipFile.open<br> 10 0.65% 71.43% 3 300175 com.sun.tools.javac.main.JavaCompiler.<init><br><init>
-...
-CPU SAMPLES END
-</init></pre>
-<blockquote>
-</blockquote>
-<p>
-The HPROF agent periodically samples the stack of all running threads
-to record the most frequently active stack traces. The <code>count</code>
-field above indicates how many times a particular stack trace was found
-to be active. These stack traces correspond to the CPU usage hot spots
-in the application.<br>
-</p>
-<h2><a name="mozTocId116568" class="mozTocH2"></a>CPU Usage Times
-Profile (cpu=times)<br>
-</h2>
-HPROF can collect CPU usage information by injecting code into every
-method entry and exit, keeping track of exact method call counts and
-the time spent in each method. This uses Byte Code Injection (BCI) and
-runs considerably slower than cpu=samples. Following is part of the
-output collected from a run
-of the <code>javac</code> compiler.
-<p></p>
-<pre>Command used: javac -J-agentlib:hprof=cpu=times Hello.java<br><br>CPU TIME (ms) BEGIN (total = 2082665289) Fri Feb 6 13:43:42 2004<br>rank self accum count trace method<br> 1 3.70% 3.70% 1 311243 com.sun.tools.javac.Main.compile<br> 2 3.64% 7.34% 1 311242 com.sun.tools.javac.main.Main.compile<br> 3 3.64% 10.97% 1 311241 com.sun.tools.javac.main.Main.compile<br> 4 3.11% 14.08% 1 311173 com.sun.tools.javac.main.JavaCompiler.compile<br> 5 2.54% 16.62% 8 306183 com.sun.tools.javac.jvm.ClassReader.listAll<br> 6 2.53% 19.15% 36 306182 com.sun.tools.javac.jvm.ClassReader.list<br> 7 2.03% 21.18% 1 307195 com.sun.tools.javac.comp.Enter.main<br> 8 2.03% 23.21% 1 307194 com.sun.tools.javac.comp.Enter.complete<br> 9 1.68% 24.90% 1 306392 com.sun.tools.javac.comp.Enter.classEnter<br> 10 1.68% 26.58% 1 306388 com.sun.tools.javac.comp.Enter.classEnter<br><br>...<br>CPU TIME (ms) END</pre>
-Here the count represents the true count of the times this method was
-entered, and the percentages represent a measure of thread CPU time
-spent in those methods.<br>
-<br>
-<h2><a class="mozTocH3" name="mozTocId848088"></a>Binary Dump Format
-(format=b)</h2>
-The basic fields in the binary output are u1 (1 byte), u2 (2 byte), u4
-(4 byte), and u8 (8 byte). An ID in this implementation is a u4,
-however the size of an ID is really determined by the "size of
-identifiers" field in the header.<br>
-<br>
-<span style="font-weight: bold;">WARNING</span>: This format is still
-considered highly experimental, however, all attempts were made to
-match the format of past HPROF implementations.<br>
-<br>
-The binary output begins with the information:<br>
-<br>
-<table style="text-align: left; width: 100%; height: 124px;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">[u1]*<br>
- </td>
- <td style="vertical-align: top;">An initial NULL terminated
-series of bytes representing the format name and version, in this
-implementation and historically, the string "JAVA PROFILE 1.0.1" (18
-u1 bytes) followed by a NULL byte. If the TAG "HEAP DUMP SEGMENT" is
-used this string will be "JAVA PROFILE 1.0.2". </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">size of identifiers. Identifiers
-are used to represent UTF8 strings, objects, stack traces, etc. They
-can have the same size as host pointers or sizeof(void*), but are not
-required to be.<span style="color: rgb(0, 0, 0);"></span></td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">high word of number of
-milliseconds since 0:00 GMT, 1/1/70</td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">low word of number of
-milliseconds since 0:00 GMT, 1/1/70</td>
- </tr>
- </tbody>
-</table>
-<br>
-Followed by a se<span style="font-family: monospace;"></span>quence of
-records that look like:<br>
-<br>
-<table style="text-align: left; width: 100%;" border="1" cellpadding="2"
- cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u1<br>
- </td>
- <td style="vertical-align: top;">TAG: denoting the type of the
-record</td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">TIME: number of microseconds
-since the
-time stamp in the header<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">LENGTH: number of bytes that
-follow this
-u4 field and belong to this record<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">[u1]*<br>
- </td>
- <td style="vertical-align: top;">BODY: as many bytes as specified
-in
-the above u4 field<br>
- </td>
- </tr>
- </tbody>
-</table>
-<br>
-<br>
-The following TAGs are supported:<br>
-<br>
-<table style="text-align: left; width: 100%;" border="1" cellpadding="2"
- cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">STRING IN UTF8<br>
- </td>
- <td style="vertical-align: top;">0x01<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">ID for this string<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">[u1]*<br>
- </td>
- <td style="vertical-align: top;">UTF8 characters for string
-(NOT NULL terminated)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">LOAD CLASS<br>
- </td>
- <td style="vertical-align: top;">0x02<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">class serial number
-(always > 0)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">class object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">class name string ID<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">UNLOAD CLASS<br>
- </td>
- <td style="vertical-align: top;">0x03<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">class serial number<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">STACK FRAME<br>
- </td>
- <td style="vertical-align: top;">0x04<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">stack frame ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">method name string ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">method signature string ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">source file name string ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">class serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">> 0<br>
- </td>
- <td style="vertical-align: top;">line number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0<br>
- </td>
- <td style="vertical-align: top;">no line information
-available<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">-1<br>
- </td>
- <td style="vertical-align: top;">unknown location<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">-2<br>
- </td>
- <td style="vertical-align: top;">compiled method (<span
- style="font-style: italic; color: rgb(255, 0, 0);">Not implemented</span>)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">-3<br>
- </td>
- <td style="vertical-align: top;">native method (<span
- style="color: rgb(255, 0, 0); font-style: italic;">Not implemented</span>)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">STACK TRACE<br>
- </td>
- <td style="vertical-align: top;">0x05<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of frames<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">[ID]*<br>
- </td>
- <td style="vertical-align: top;">series of stack frame ID's<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ALLOC SITES<br>
- </td>
- <td style="vertical-align: top;">0x06<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">Bit mask flags:<br>
- <table style="text-align: left; width: 441px; height: 74px;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">0x1<br>
- </td>
- <td style="vertical-align: top;">incremental vs.
-complete<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x2<br>
- </td>
- <td style="vertical-align: top; text-align: left;">sorted
-by allocation vs. line<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x4<br>
- </td>
- <td style="vertical-align: top;">whether to force GC
-(<span style="font-style: italic; color: rgb(255, 0, 0);">Not
-Implemented</span>)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">cutoff ratio (floating
-point)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">total live bytes<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">total live instances<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u8<br>
- </td>
- <td style="vertical-align: top;">total bytes allocated<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u8<br>
- </td>
- <td style="vertical-align: top;">total instances allocated<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of sites that
-follow:<br>
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u1<br>
- </td>
- <td style="vertical-align: top;">array indicator: 0
-means not an array, non-zero means an array of this type (See <a
- href="#Basic_Type">Basic Type</a>)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">class serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial
-number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of live bytes<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of live
-instances<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of bytes
-allocated<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of instances
-allocated<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">HEAP SUMMARY<br>
- </td>
- <td style="vertical-align: top;">0x07<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">total live bytes<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">total live instances<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u8<br>
- </td>
- <td style="vertical-align: top;">total bytes allocated<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u8<br>
- </td>
- <td style="vertical-align: top;">total instances allocated<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">START THREAD<br>
- </td>
- <td style="vertical-align: top;">0x0A<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">thread object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">thread name string ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">thread group name ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">thread parent group name ID<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">END THREAD<br>
- </td>
- <td style="vertical-align: top;">0x0B<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">HEAP DUMP<br>
- <span style="font-style: italic;">or</span><br>
-HEAP DUMP SEGMENT<br>
- </td>
- <td style="vertical-align: top;">0x0C<br>
- <span style="font-style: italic;">or</span><br>
-0x1C<br>
- </td>
- <td style="vertical-align: top;">Contains any number of sub-tags,
-each begins a u1 field (no order implied here):<br>
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ROOT UNKNOWN<br>
- </td>
- <td style="vertical-align: top;">0xFF<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT JNI GLOBAL<br>
- </td>
- <td style="vertical-align: top;">0x01<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">JNI global ref ID<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT JNI LOCAL<br>
- </td>
- <td style="vertical-align: top;">0x02<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">frame number in
-stack trace (-1 for empty)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT JAVA FRAME<br>
- </td>
- <td style="vertical-align: top;">0x03<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">frame number in
-stack trace (-1 for empty)</td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT NATIVE STACK<br>
- </td>
- <td style="vertical-align: top;">0x04<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT STICKY CLASS<br>
- </td>
- <td style="vertical-align: top;">0x05<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT THREAD BLOCK<br>
- </td>
- <td style="vertical-align: top;">0x06<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT MONITOR USED<br>
- </td>
- <td style="vertical-align: top;">0x07<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ROOT THREAD OBJECT<br>
- </td>
- <td style="vertical-align: top;">0x08<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">thread object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">thread serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial
-number<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">CLASS DUMP<br>
- </td>
- <td style="vertical-align: top;">0x20<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">class object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial
-number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">super class object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">class loader object
-ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">signers object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">protection domain
-object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">reserved<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">reserved<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">instance size (in
-bytes)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">size of constant
-pool and number of records that follow:<br>
- <table style="text-align: left; width: 100%;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">constant pool
-index<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u1<br>
- </td>
- <td style="vertical-align: top;">type of entry:
-(See <a href="#Basic_Type">Basic Type</a>)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">value<br>
- </td>
- <td style="vertical-align: top;">value of entry
-(u1, u2, u4, or u8 based on type of entry)<span
- style="font-style: italic; color: rgb(255, 0, 0);"></span><br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">Number of static
-fields:<br>
- <table style="text-align: left; width: 100%;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">static field
-name string ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u1<br>
- </td>
- <td style="vertical-align: top;">type of field:
-(See <a href="#Basic_Type">Basic Type</a>)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">value<br>
- </td>
- <td style="vertical-align: top;">value of entry
-(u1, u2, u4, or u8 based on type of field) <span
- style="font-style: italic; color: rgb(255, 0, 0);"></span><br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">Number of instance
-fields (not including super class's)<br>
- <table style="text-align: left; width: 100%;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">field name
-string ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u1<br>
- </td>
- <td style="vertical-align: top;">type of field:
-(See <a href="#Basic_Type">Basic Type</a>)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">INSTANCE DUMP<br>
- </td>
- <td style="vertical-align: top;">0x21<br>
- </td>
- <td style="vertical-align: top;"><br>
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial
-number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">class object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of bytes that
-follow<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">[value]*<br>
- </td>
- <td style="vertical-align: top;">instance field
-values (this class, followed by super class, etc)<span
- style="font-style: italic; color: rgb(255, 0, 0);"></span><br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">OBJECT ARRAY DUMP<br>
- </td>
- <td style="vertical-align: top;">0x22<br>
- </td>
- <td style="vertical-align: top;"><br>
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">array object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial
-number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of elements<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">array class object
-ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">[ID]*<br>
- </td>
- <td style="vertical-align: top;">elements<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">PRIMITIVE ARRAY DUMP<br>
- </td>
- <td style="vertical-align: top;">0x23<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">array object ID<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial
-number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of elements<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u1<br>
- </td>
- <td style="vertical-align: top;">element type (See <a
- href="#Basic_Type">Basic Type</a>)<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">[u1]*<br>
- </td>
- <td style="vertical-align: top;">elements (packed
-array) </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">HEAP DUMP END<br>
- </td>
- <td style="vertical-align: top;">0x2C<br>
- </td>
- <td style="vertical-align: top;">Terminates a series of HEAP DUMP
-SEGMENTS. Concatenation of HEAP DUMP SEGMENTS equals a HEAP DUMP.<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">CPU SAMPLES<br>
- </td>
- <td style="vertical-align: top;">0x0D<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">total number of samples<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of traces that
-follow:<br>
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of samples<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">stack trace serial
-number<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">CONTROL SETTINGS<br>
- </td>
- <td style="vertical-align: top;">0x0E<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">Bit mask flags:<br>
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">0x1<br>
- </td>
- <td style="vertical-align: top;">alloc traces on/off<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x2<br>
- </td>
- <td style="vertical-align: top;">cpu sampling on/off<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">stack trace depth<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
-</table>
-<span style="font-weight: bold;"><br>
-</span><a name="Basic_Type"></a>Basic Type
-<table style="text-align: left; width: 296px; height: 221px;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">2<br>
- </td>
- <td style="vertical-align: top;">object<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">4<br>
- </td>
- <td style="vertical-align: top;">boolean<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">5<br>
- </td>
- <td style="vertical-align: top;">char<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">6<br>
- </td>
- <td style="vertical-align: top;">float<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">7<br>
- </td>
- <td style="vertical-align: top;">double<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">8<br>
- </td>
- <td style="vertical-align: top;">byte<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">9<br>
- </td>
- <td style="vertical-align: top;">short<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">10<br>
- </td>
- <td style="vertical-align: top;">int<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">11<br>
- </td>
- <td style="vertical-align: top;">long<br>
- </td>
- </tr>
- </tbody>
-</table>
-<h3><a name="mozTocId348360" class="mozTocH3"></a>Handling of Arrays</h3>
-<br>
-There will be a "LOAD CLASS" tag for type type of each array
-in the dump. In the LOAD CLASS record, the class name string ID
-will refer to a string with a human-readable name of the array
-type that is formatted as the type name would be in Java source
-code. Thus, the LOAD CLASS record for the type char[] will
-be "char[]", for short[][][] will be "short[][][]" and for
-MyType[] will be "MyType[]".
-<br>
-<h3><a name="mozTocId348369" class="mozTocH3"></a>Socket Connection and
-Communication</h3>
-<br>
-<span style="font-weight: bold;">WARNING</span>: This command format is
-still
-considered highly experimental, however, all attempts were made to
-match the format of past HPROF implementations.<br>
-<br>
-<br>
-Commands can be sent to HPROF via the socket connection, the accepted
-COMMAND TAGS are:<br>
-<br>
-<table style="text-align: left; width: 100%;" border="1" cellpadding="2"
- cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">FORCE GC (<span
- style="font-style: italic; color: rgb(255, 0, 0);">Not implemented</span>)<br>
- </td>
- <td style="vertical-align: top;">0x01<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">DUMP HEAP<br>
- </td>
- <td style="vertical-align: top;">0x02<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">ALLOC SITES<br>
- </td>
- <td style="vertical-align: top;">0x03<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">HEAP SUMMARY<br>
- </td>
- <td style="vertical-align: top;">0x04<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">EXIT THE VM<br>
- </td>
- <td style="vertical-align: top;">0x05<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">DUMP TRACES<br>
- </td>
- <td style="vertical-align: top;">0x06<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">CPU SAMPLES<br>
- </td>
- <td style="vertical-align: top;">0x07<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">CONTROL<br>
- </td>
- <td style="vertical-align: top;">0x08<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">EOF (used to terminate socket
-connection)<br>
- </td>
- <td style="vertical-align: top;">0xFF<br>
- </td>
- </tr>
- </tbody>
-</table>
-<br>
-The commands take the form:<br>
-<br>
-<table style="text-align: left; width: 100%;" border="1" cellpadding="2"
- cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u1<br>
- </td>
- <td style="vertical-align: top;">COMMAND TAG<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">serial number<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">number of bytes that follow<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">[u1]*<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ALLOC SITES<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">Flags:<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">cutoff ratio
-(floating point between 0.0 and 1.0)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">CPU SAMPLES<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">ignored<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">u4<br>
- </td>
- <td style="vertical-align: top;">cutoff ratio
-(floating point between 0.0 and 1.0)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">CONTROL<br>
- </td>
- <td style="vertical-align: top;">
- <table style="text-align: left; width: 100%;" border="1"
- cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">Sub option:<br>
- <table style="text-align: left; width: 100%;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">0x1<br>
- </td>
- <td style="vertical-align: top;">Turn alloc
-traces on<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x2<br>
- </td>
- <td style="vertical-align: top;">Turn alloc
-traces off<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x3<br>
- </td>
- <td style="vertical-align: top;">Turn CPU
-sampling on:<br>
- <table style="text-align: left; width: 100%;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">thread
-object ID (0 for all threads)<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x4<br>
- </td>
- <td style="vertical-align: top;">Turn CPU
-sampling off:<br>
- <table style="text-align: left; width: 100%;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">ID<br>
- </td>
- <td style="vertical-align: top;">thread
-object ID (0 for all threads)</td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x5<br>
- </td>
- <td style="vertical-align: top;">Clear CPU
-sampling<br>
- </td>
- </tr>
- <tr>
- <td style="vertical-align: top;">0x6<br>
- </td>
- <td style="vertical-align: top;">Set max stack
-depth:<br>
- <table style="text-align: left; width: 100%;"
- border="1" cellpadding="2" cellspacing="2">
- <tbody>
- <tr>
- <td style="vertical-align: top;">u2<br>
- </td>
- <td style="vertical-align: top;">New max
-stack depth<br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- </td>
- </tr>
- </tbody>
-</table>
-<br>
-<p></p>
-<hr><!-- hhmts start -->
-Last modified: 2005<!-- hhmts end -->
-</body>
-</html>
--- a/jdk/src/jdk.hprof.agent/unix/native/libhprof/hprof_md.c Wed Aug 05 03:43:31 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,453 +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.
- */
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#if !defined(LINUX) && !defined(_ALLBSD_SOURCE) && !defined(AIX)
-#include <procfs.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dlfcn.h>
-#include <sys/time.h>
-
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/param.h>
-#include <time.h>
-
-#include "jni.h"
-#include "jvm_md.h"
-#include "hprof.h"
-
-#ifdef AIX
-#include "porting_aix.h" /* For the 'dladdr' function. */
-#endif
-
-int
-md_getpid(void)
-{
- static int pid = -1;
-
- if ( pid >= 0 ) {
- return pid;
- }
- pid = getpid();
- return pid;
-}
-
-void
-md_sleep(unsigned seconds)
-{
- sleep(seconds);
-}
-
-void
-md_init(void)
-{
-#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
- /* No Hi-Res timer option? */
-#else
- if ( gdata->micro_state_accounting ) {
- char proc_ctl_fn[48];
- int procfd;
-
- /* Turn on micro state accounting, once per process */
- (void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn),
- "/proc/%d/ctl", md_getpid());
-
- procfd = open(proc_ctl_fn, O_WRONLY);
- if (procfd >= 0) {
- long ctl_op[2];
-
- ctl_op[0] = PCSET;
- ctl_op[1] = PR_MSACCT;
- (void)write(procfd, ctl_op, sizeof(ctl_op));
- (void)close(procfd);
- }
- }
-#endif
-}
-
-int
-md_connect(char *hostname, unsigned short port)
-{
- struct hostent *hentry;
- struct sockaddr_in s;
- int fd;
-
- /* create a socket */
- fd = socket(AF_INET, SOCK_STREAM, 0);
- if ( fd < 0 ) {
- return -1;
- }
-
- /* find remote host's addr from name */
- if ((hentry = gethostbyname(hostname)) == NULL) {
- (void)close(fd);
- return -1;
- }
- (void)memset((char *)&s, 0, sizeof(s));
- /* set remote host's addr; its already in network byte order */
- (void)memcpy(&s.sin_addr.s_addr, *(hentry->h_addr_list),
- (int)sizeof(s.sin_addr.s_addr));
- /* set remote host's port */
- s.sin_port = htons(port);
- s.sin_family = AF_INET;
-
- /* now try connecting */
- if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) {
- (void)close(fd);
- return 0;
- }
- return fd;
-}
-
-int
-md_recv(int f, char *buf, int len, int option)
-{
- return recv(f, buf, len, option);
-}
-
-int
-md_shutdown(int filedes, int option)
-{
- return shutdown(filedes, option);
-}
-
-int
-md_open(const char *filename)
-{
- return open(filename, O_RDONLY);
-}
-
-int
-md_open_binary(const char *filename)
-{
- return md_open(filename);
-}
-
-int
-md_creat(const char *filename)
-{
- return open(filename, O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-}
-
-int
-md_creat_binary(const char *filename)
-{
- return md_creat(filename);
-}
-
-jlong
-md_seek(int filedes, jlong cur)
-{
- jlong new_pos;
-
- if ( cur == (jlong)-1 ) {
- new_pos = lseek(filedes, 0, SEEK_END);
- } else {
- new_pos = lseek(filedes, cur, SEEK_SET);
- }
- return new_pos;
-}
-
-void
-md_close(int filedes)
-{
- (void)close(filedes);
-}
-
-int
-md_send(int s, const char *msg, int len, int flags)
-{
- int res;
-
- do {
- res = send(s, msg, len, flags);
- } while ((res < 0) && (errno == EINTR));
-
- return res;
-}
-
-int
-md_write(int filedes, const void *buf, int nbyte)
-{
- int res;
-
- do {
- res = write(filedes, buf, nbyte);
- } while ((res < 0) && (errno == EINTR));
-
- return res;
-}
-
-int
-md_read(int filedes, void *buf, int nbyte)
-{
- int res;
-
- do {
- res = read(filedes, buf, nbyte);
- } while ((res < 0) && (errno == EINTR));
-
- return res;
-}
-
-/* Time of day in milli-seconds */
-static jlong
-md_timeofday(void)
-{
- struct timeval tv;
-
- if ( gettimeofday(&tv, (void *)0) != 0 ) {
- return (jlong)0; /* EOVERFLOW ? */
- }
- /*LINTED*/
- return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000);
-}
-
-/* Hi-res timer in micro-seconds */
-jlong
-md_get_microsecs(void)
-{
-#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
- return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */
-#else
- return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */
-#endif
-}
-
-/* Time of day in milli-seconds */
-jlong
-md_get_timemillis(void)
-{
- return md_timeofday();
-}
-
-/* Current CPU hi-res CPU time used */
-jlong
-md_get_thread_cpu_timemillis(void)
-{
-#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
- return md_timeofday();
-#else
- return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */
-#endif
-}
-
-void
-md_get_prelude_path(char *path, int path_len, char *filename)
-{
- void *addr;
- char libdir[FILENAME_MAX+1];
- Dl_info dlinfo;
-
- libdir[0] = 0;
- addr = (void*)&md_get_prelude_path;
-
- /* Use dladdr() to get the full path to libhprof.so, which we use to find
- * the prelude file.
- */
- dlinfo.dli_fname = NULL;
- (void)dladdr(addr, &dlinfo);
- if ( dlinfo.dli_fname != NULL ) {
- char * lastSlash;
-
- /* Full path to library name, need to move up one directory to 'lib' */
- (void)strcpy(libdir, (char *)dlinfo.dli_fname);
- lastSlash = strrchr(libdir, '/');
- if ( lastSlash != NULL ) {
- *lastSlash = '\0';
- }
-#ifndef __APPLE__
- // not sure why other platforms have to go up two levels, but on macos we only need up one
- lastSlash = strrchr(libdir, '/');
- if ( lastSlash != NULL ) {
- *lastSlash = '\0';
- }
-#endif /* __APPLE__ */
- }
- (void)snprintf(path, path_len, "%s/%s", libdir, filename);
-}
-
-
-int
-md_vsnprintf(char *s, int n, const char *format, va_list ap)
-{
- return vsnprintf(s, n, format, ap);
-}
-
-int
-md_snprintf(char *s, int n, const char *format, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, format);
- ret = md_vsnprintf(s, n, format, ap);
- va_end(ap);
- return ret;
-}
-
-void
-md_system_error(char *buf, int len)
-{
- char *p;
-
- buf[0] = 0;
- p = strerror(errno);
- if ( p != NULL ) {
- (void)strcpy(buf, p);
- }
-}
-
-unsigned
-md_htons(unsigned short s)
-{
- return htons(s);
-}
-
-unsigned
-md_htonl(unsigned l)
-{
- return htonl(l);
-}
-
-unsigned
-md_ntohs(unsigned short s)
-{
- return ntohs(s);
-}
-
-unsigned
-md_ntohl(unsigned l)
-{
- return ntohl(l);
-}
-
-static void dll_build_name(char* buffer, size_t buflen,
- const char* paths, const char* fname) {
- char *path, *paths_copy, *next_token;
-
- paths_copy = strdup(paths);
- if (paths_copy == NULL) {
- return;
- }
-
- next_token = NULL;
- path = strtok_r(paths_copy, ":", &next_token);
-
- while (path != NULL) {
- snprintf(buffer, buflen, "%s/lib%s" JNI_LIB_SUFFIX, path, fname);
- if (access(buffer, F_OK) == 0) {
- break;
- }
- *buffer = '\0';
- path = strtok_r(NULL, ":", &next_token);
- }
-
- free(paths_copy);
-}
-
-/* Create the actual fill filename for a dynamic library. */
-void
-md_build_library_name(char *holder, int holderlen, const char *pname, const char *fname)
-{
- int pnamelen;
-
- /* Length of options directory location. */
- pnamelen = pname ? strlen(pname) : 0;
-
- *holder = '\0';
- /* Quietly truncate on buffer overflow. Should be an error. */
- if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
- return;
- }
-
- /* Construct path to library */
- if (pnamelen == 0) {
- (void)snprintf(holder, holderlen, "lib%s" JNI_LIB_SUFFIX, fname);
- } else {
- dll_build_name(holder, holderlen, pname, fname);
- }
-}
-
-/* Load this library (return NULL on error, and error message in err_buf) */
-void *
-md_load_library(const char *name, char *err_buf, int err_buflen)
-{
- void * result;
-
- result = dlopen(name, RTLD_LAZY);
- if (result == NULL) {
- (void)strncpy(err_buf, dlerror(), err_buflen-2);
- err_buf[err_buflen-1] = '\0';
- }
- return result;
-}
-
-/* Unload this library */
-void
-md_unload_library(void *handle)
-{
- (void)dlclose(handle);
-}
-
-/* Find an entry point inside this library (return NULL if not found) */
-void *
-md_find_library_entry(void *handle, const char *name)
-{
- void * sym;
-
- sym = dlsym(handle, name);
- return sym;
-}
-
-
--- a/jdk/src/jdk.hprof.agent/windows/native/libhprof/hprof_md.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.
- */
-
-
-// To ensure winsock2.h is used, it has to be included ahead of
-// windows.h, which includes winsock.h by default.
-#include <winsock2.h>
-#include <windows.h>
-#include <io.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <mmsystem.h>
-#include <fcntl.h>
-#include <process.h>
-
-#include "jni.h"
-#include "hprof.h"
-
-int
-md_getpid(void)
-{
- static int pid = -1;
-
- if ( pid >= 0 ) {
- return pid;
- }
- pid = getpid();
- return pid;
-}
-
-void
-md_sleep(unsigned seconds)
-{
- Sleep((DWORD)seconds*1000);
-}
-
-void
-md_init(void)
-{
-}
-
-int
-md_connect(char *hostname, unsigned short port)
-{
- struct hostent *hentry;
- struct sockaddr_in s;
- int fd;
-
- /* find remote host's addr from name */
- if ((hentry = gethostbyname(hostname)) == NULL) {
- return -1;
- }
- (void)memset((char *)&s, 0, sizeof(s));
- /* set remote host's addr; its already in network byte order */
- (void)memcpy(&s.sin_addr.s_addr, *(hentry->h_addr_list),
- (int)sizeof(s.sin_addr.s_addr));
- /* set remote host's port */
- s.sin_port = htons(port);
- s.sin_family = AF_INET;
-
- /* create a socket */
- fd = (int)socket(AF_INET, SOCK_STREAM, 0);
- if (INVALID_SOCKET == fd) {
- return 0;
- }
-
- /* now try connecting */
- if (SOCKET_ERROR == connect(fd, (struct sockaddr*)&s, sizeof(s))) {
- closesocket(fd);
- return 0;
- }
- return fd;
-}
-
-int
-md_recv(int f, char *buf, int len, int option)
-{
- return recv(f, buf, len, option);
-}
-
-int
-md_shutdown(int filedes, int option)
-{
- return shutdown(filedes, option);
-}
-
-int
-md_open(const char *filename)
-{
- return open(filename, O_RDONLY);
-}
-
-int
-md_open_binary(const char *filename)
-{
- return open(filename, O_RDONLY|O_BINARY);
-}
-
-int
-md_creat(const char *filename)
-{
- return open(filename, O_CREAT | O_WRONLY | O_TRUNC,
- _S_IREAD | _S_IWRITE);
-}
-
-int
-md_creat_binary(const char *filename)
-{
- return open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY,
- _S_IREAD | _S_IWRITE);
-}
-
-jlong
-md_seek(int filedes, jlong pos)
-{
- jlong new_pos;
-
- if ( pos == (jlong)-1 ) {
- new_pos = _lseeki64(filedes, 0L, SEEK_END);
- } else {
- new_pos = _lseeki64(filedes, pos, SEEK_SET);
- }
- return new_pos;
-}
-
-void
-md_close(int filedes)
-{
- (void)closesocket(filedes);
-}
-
-int
-md_send(int s, const char *msg, int len, int flags)
-{
- return send(s, msg, len, flags);
-}
-
-int
-md_read(int filedes, void *buf, int nbyte)
-{
- return read(filedes, buf, nbyte);
-}
-
-int
-md_write(int filedes, const void *buf, int nbyte)
-{
- return write(filedes, buf, nbyte);
-}
-
-jlong
-md_get_microsecs(void)
-{
- return (jlong)(timeGetTime())*(jlong)1000;
-}
-
-#define FT2JLONG(ft) \
- ((jlong)(ft).dwHighDateTime << 32 | (jlong)(ft).dwLowDateTime)
-
-jlong
-md_get_timemillis(void)
-{
- static jlong fileTime_1_1_70 = 0;
- SYSTEMTIME st0;
- FILETIME ft0;
-
- if (fileTime_1_1_70 == 0) {
- /* Initialize fileTime_1_1_70 -- the Win32 file time of midnight
- * 1/1/70.
- */
-
- memset(&st0, 0, sizeof(st0));
- st0.wYear = 1970;
- st0.wMonth = 1;
- st0.wDay = 1;
- SystemTimeToFileTime(&st0, &ft0);
- fileTime_1_1_70 = FT2JLONG(ft0);
- }
-
- GetSystemTime(&st0);
- SystemTimeToFileTime(&st0, &ft0);
-
- return (FT2JLONG(ft0) - fileTime_1_1_70) / 10000;
-}
-
-jlong
-md_get_thread_cpu_timemillis(void)
-{
- return md_get_timemillis();
-}
-
-HINSTANCE hJavaInst;
-static int nError = 0;
-
-BOOL WINAPI
-DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
-{
- WSADATA wsaData;
- switch (reason) {
- case DLL_PROCESS_ATTACH:
- hJavaInst = hinst;
- nError = WSAStartup(MAKEWORD(2,0), &wsaData);
- break;
- case DLL_PROCESS_DETACH:
- WSACleanup();
- hJavaInst = NULL;
- default:
- break;
- }
- return TRUE;
-}
-
-void
-md_get_prelude_path(char *path, int path_len, char *filename)
-{
- char libdir[FILENAME_MAX+1];
- char *lastSlash;
-
- GetModuleFileName(hJavaInst, libdir, FILENAME_MAX);
-
- /* This is actually in the bin directory, so move above bin for lib */
- lastSlash = strrchr(libdir, '\\');
- if ( lastSlash != NULL ) {
- *lastSlash = '\0';
- }
- lastSlash = strrchr(libdir, '\\');
- if ( lastSlash != NULL ) {
- *lastSlash = '\0';
- }
- (void)md_snprintf(path, path_len, "%s\\lib\\%s", libdir, filename);
-}
-
-int
-md_vsnprintf(char *s, int n, const char *format, va_list ap)
-{
- return _vsnprintf(s, n, format, ap);
-}
-
-int
-md_snprintf(char *s, int n, const char *format, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, format);
- ret = md_vsnprintf(s, n, format, ap);
- va_end(ap);
- return ret;
-}
-
-void
-md_system_error(char *buf, int len)
-{
- long errval;
-
- errval = GetLastError();
- buf[0] = '\0';
- if (errval != 0) {
- int n;
-
- n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, errval,
- 0, buf, len, NULL);
- if (n > 3) {
- /* Drop final '.', CR, LF */
- if (buf[n - 1] == '\n') n--;
- if (buf[n - 1] == '\r') n--;
- if (buf[n - 1] == '.') n--;
- buf[n] = '\0';
- }
- }
-}
-
-unsigned
-md_htons(unsigned short s)
-{
- return htons(s);
-}
-
-unsigned
-md_htonl(unsigned l)
-{
- return htonl(l);
-}
-
-unsigned
-md_ntohs(unsigned short s)
-{
- return ntohs(s);
-}
-
-unsigned
-md_ntohl(unsigned l)
-{
- return ntohl(l);
-}
-
-static int
-get_last_error_string(char *buf, int len)
-{
- long errval;
-
- errval = GetLastError();
- if (errval != 0) {
- /* DOS error */
- int n;
-
- n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, errval,
- 0, buf, len, NULL);
- if (n > 3) {
- /* Drop final '.', CR, LF */
- if (buf[n - 1] == '\n') n--;
- if (buf[n - 1] == '\r') n--;
- if (buf[n - 1] == '.') n--;
- buf[n] = '\0';
- }
- return n;
- }
-
- if (errno != 0) {
- /* C runtime error that has no corresponding DOS error code */
- const char *s;
- int n;
-
- s = strerror(errno);
- n = (int)strlen(s);
- if (n >= len) {
- n = len - 1;
- }
- (void)strncpy(buf, s, n);
- buf[n] = '\0';
- return n;
- }
-
- return 0;
-}
-
-static void dll_build_name(char* buffer, size_t buflen,
- const char* paths, const char* fname) {
- char *path, *paths_copy, *next_token;
-
- paths_copy = strdup(paths);
- if (paths_copy == NULL) {
- return;
- }
-
- next_token = NULL;
- path = strtok_s(paths_copy, ";", &next_token);
-
- while (path != NULL) {
- _snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
- if (_access(buffer, 0) == 0) {
- break;
- }
- *buffer = '\0';
- path = strtok_s(NULL, ";", &next_token);
- }
-
- free(paths_copy);
-}
-
-/* Build a machine dependent library name out of a path and file name. */
-void
-md_build_library_name(char *holder, int holderlen, const char *pname, const char *fname)
-{
- int pnamelen;
-
- pnamelen = pname ? (int)strlen(pname) : 0;
-
- *holder = '\0';
- /* Quietly truncates on buffer overflow. Should be an error. */
- if (pnamelen + strlen(fname) + 10 > (unsigned int)holderlen) {
- return;
- }
-
- if (pnamelen == 0) {
- sprintf(holder, "%s.dll", fname);
- } else {
- dll_build_name(holder, holderlen, pname, fname);
- }
-}
-
-void *
-md_load_library(const char * name, char *err_buf, int err_buflen)
-{
- void *result;
-
- result = LoadLibrary(name);
- if (result == NULL) {
- /* Error message is pretty lame, try to make a better guess. */
- long errcode;
-
- errcode = GetLastError();
- if (errcode == ERROR_MOD_NOT_FOUND) {
- strncpy(err_buf, "Can't find dependent libraries", err_buflen-2);
- err_buf[err_buflen-1] = '\0';
- } else {
- get_last_error_string(err_buf, err_buflen);
- }
- }
- return result;
-}
-
-void
-md_unload_library(void *handle)
-{
- FreeLibrary(handle);
-}
-
-void *
-md_find_library_entry(void *handle, const char *name)
-{
- return GetProcAddress(handle, name);
-}
--- a/jdk/test/tools/pack200/CommandLineTests.java Wed Aug 05 03:43:31 2015 +0200
+++ b/jdk/test/tools/pack200/CommandLineTests.java Mon Aug 10 13:08:55 2015 +0200
@@ -110,7 +110,6 @@
ps.println("pack.pass.file.2=java/lang/Object.class");
ps.println("pack.pass.file.3=java/lang/Throwable.class");
ps.println("pack.pass.file.4=java/lang/VerifyError.class");
- ps.println("pack.pass.file.5=com/sun/demo/jvmti/hprof/Tracker.class");
} finally {
Utils.close(ps);
Utils.close(fos);