--- a/hotspot/agent/make/Makefile Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/make/Makefile Thu Sep 15 12:44:09 2011 -0700
@@ -48,6 +48,7 @@
sun.jvm.hotspot.bugspot \
sun.jvm.hotspot.bugspot.tree \
sun.jvm.hotspot.c1 \
+sun.jvm.hotspot.ci \
sun.jvm.hotspot.code \
sun.jvm.hotspot.compiler \
sun.jvm.hotspot.debugger \
@@ -56,9 +57,6 @@
sun.jvm.hotspot.debugger.cdbg.basic \
sun.jvm.hotspot.debugger.cdbg.basic.amd64 \
sun.jvm.hotspot.debugger.cdbg.basic.x86 \
-sun.jvm.hotspot.debugger.dbx \
-sun.jvm.hotspot.debugger.dbx.sparc \
-sun.jvm.hotspot.debugger.dbx.x86 \
sun.jvm.hotspot.debugger.dummy \
sun.jvm.hotspot.debugger.ia64 \
sun.jvm.hotspot.debugger.linux \
@@ -76,7 +74,6 @@
sun.jvm.hotspot.debugger.remote.sparc \
sun.jvm.hotspot.debugger.remote.x86 \
sun.jvm.hotspot.debugger.sparc \
-sun.jvm.hotspot.debugger.win32 \
sun.jvm.hotspot.debugger.win32.coff \
sun.jvm.hotspot.debugger.windbg \
sun.jvm.hotspot.debugger.windbg.amd64 \
@@ -91,7 +88,9 @@
sun.jvm.hotspot.jdi \
sun.jvm.hotspot.livejvm \
sun.jvm.hotspot.memory \
+sun.jvm.hotspot.opto \
sun.jvm.hotspot.oops \
+sun.jvm.hotspot.prims \
sun.jvm.hotspot.runtime \
sun.jvm.hotspot.runtime.amd64 \
sun.jvm.hotspot.runtime.ia64 \
@@ -139,6 +138,7 @@
sun/jvm/hotspot/bugspot/*.java \
sun/jvm/hotspot/bugspot/tree/*.java \
sun/jvm/hotspot/c1/*.java \
+sun/jvm/hotspot/ci/*.java \
sun/jvm/hotspot/code/*.java \
sun/jvm/hotspot/compiler/*.java \
sun/jvm/hotspot/debugger/*.java \
@@ -147,9 +147,6 @@
sun/jvm/hotspot/debugger/cdbg/basic/*.java \
sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
-sun/jvm/hotspot/debugger/dbx/*.java \
-sun/jvm/hotspot/debugger/dbx/sparc/*.java \
-sun/jvm/hotspot/debugger/dbx/x86/*.java \
sun/jvm/hotspot/debugger/dummy/*.java \
sun/jvm/hotspot/debugger/ia64/*.java \
sun/jvm/hotspot/debugger/linux/*.java \
@@ -165,7 +162,6 @@
sun/jvm/hotspot/debugger/remote/sparc/*.java \
sun/jvm/hotspot/debugger/remote/x86/*.java \
sun/jvm/hotspot/debugger/sparc/*.java \
-sun/jvm/hotspot/debugger/win32/*.java \
sun/jvm/hotspot/debugger/win32/coff/*.java \
sun/jvm/hotspot/debugger/windbg/*.java \
sun/jvm/hotspot/debugger/windbg/ia64/*.java \
@@ -176,6 +172,8 @@
sun/jvm/hotspot/livejvm/*.java \
sun/jvm/hotspot/memory/*.java \
sun/jvm/hotspot/oops/*.java \
+sun/jvm/hotspot/opto/*.java \
+sun/jvm/hotspot/prims/*.java \
sun/jvm/hotspot/runtime/*.java \
sun/jvm/hotspot/runtime/amd64/*.java \
sun/jvm/hotspot/runtime/ia64/*.java \
--- a/hotspot/agent/make/saenv.sh Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/make/saenv.sh Thu Sep 15 12:44:09 2011 -0700
@@ -70,6 +70,14 @@
SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar
+if [ ! -z "$SA_TYPEDB" ]; then
+ if [ ! -f $SA_TYPEDB ]; then
+ echo "$SA_TYPEDB is unreadable"
+ exit 1
+ fi
+ OPTIONS="-Dsun.jvm.hotspot.typedb=$SA_TYPEDB ${OPTIONS}"
+fi
+
OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
SA_JAVA_CMD="$SA_PREFIX_CMD $SA_JAVA -showversion ${OPTIONS} -cp $SA_CLASSPATH $SA_OPTIONS"
--- a/hotspot/agent/make/saenv64.sh Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/make/saenv64.sh Thu Sep 15 12:44:09 2011 -0700
@@ -67,6 +67,14 @@
SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar::$STARTDIR/lib/js.jar
+if [ ! -z "$SA_TYPEDB" ]; then
+ if [ ! -f $SA_TYPEDB ]; then
+ echo "$SA_TYPEDB is unreadable"
+ exit 1
+ fi
+ OPTIONS="-Dsun.jvm.hotspot.typedb=$SA_TYPEDB ${OPTIONS}"
+fi
+
OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
SA_JAVA_CMD="$SA_PREFIX_CMD $SA_JAVA -d64 -showversion ${OPTIONS} -cp $SA_CLASSPATH $SA_OPTIONS"
--- a/hotspot/agent/src/os/solaris/Makefile Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/os/solaris/Makefile Thu Sep 15 12:44:09 2011 -0700
@@ -24,9 +24,7 @@
all:
- cd dbx; $(MAKE) all
cd proc; $(MAKE) all
clean:
- cd dbx; $(MAKE) clean
cd proc; $(MAKE) clean
--- a/hotspot/agent/src/os/solaris/dbx/Makefile Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#
-# Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-
-# Targets are:
-# 32bit: Build the 32 bit version in ./32bit
-# 64bit: Build the 64 bit version in ./64bit
-# helloWorld: Build the helloWorld test program
-# all: Build all of the above. This is the default.
-#
-# NOTE: This makefile uses IOBuf.cpp, IOBuf.hpp, Buffer.cpp, and
-# Buffer.hpp from the src/os/win32/agent directory.
-
-.PHONY: 32bit 64bit
-
-ARCH_ORIG = $(shell uname -p)
-
-# C++ := /java/devtools/$(ARCH_ORIG)/SUNWspro/SC6.1/bin/CC
-
-C++ := CC
-RM := /usr/bin/rm
-MKDIRS := /usr/bin/mkdir -p
-
-
-WIN32_DIR := ../../win32
-ARCH := $(subst i386,i486,$(ARCH_ORIG))
-# INCLUDES := -I/net/sparcworks.eng/export/set/sparcworks5/dbx_62_intg/dev/src/dbx -I$(WIN32_DIR)
-INCLUDES := -I. -I$(WIN32_DIR)
-CFLAGS_32bit := -xarch=v8
-CFLAGS_64bit := -xarch=v9
-CFLAGS := -PIC -xO3 $(INCLUDES)
-LIBS := -lsocket -lnsl -lrtld_db
-LDFLAGS := -G
-
-ifneq "$(ARCH)" "i486"
- CFLAGS += $(CFLAGS_$(VERSION))
- LDFLAGS += $(CFLAGS_$(VERSION))
-endif
-
-# We use IOBuf.hpp, IOBuf.cpp, Buffer.hpp, and Buffer.cpp from the win32 dir.
-vpath %.cpp .:$(WIN32_DIR)
-vpath %.hpp .:$(WIN32_DIR)
-
-OBJS = $(VERSION)/svc_agent_dbx.o $(VERSION)/IOBuf.o $(VERSION)/Buffer.o
-
-
-
-# The default is to make both 32 bit and 64 bit versions.
-all:: 32bit 64bit
-
-32bit 64bit::
- $(MKDIRS) $@
- $(MAKE) $@/libsvc_agent_dbx.so helloWorld VERSION=$@
-
-$(VERSION)/IOBuf.o: IOBuf.hpp
-$(VERSION)/Buffer.o: Buffer.hpp
-$(VERSION)/svc_agent_dbx.o: svc_agent_dbx.hpp
-
-$(VERSION)/%.o: %.cpp
- $(C++) $(CFLAGS) -c $< -o $@
-
-$(VERSION)/libsvc_agent_dbx.so:: $(OBJS)
- $(C++) $(LDFLAGS) -o $(VERSION)/libsvc_agent_dbx.so $(OBJS) $(LIBS)
-
-# Would be nice to move this into a shared directory
-helloWorld:: helloWorld.cpp
- $(C++) -g $< -o $@
-
-clean::
- $(RM) -rf 32bit 64bit *.o helloWorld
--- a/hotspot/agent/src/os/solaris/dbx/README Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-shell_impl.h
-proc_service_2.h
-
-The above files are captured from the dbx build environment.
-Rather then use a -I that points to stuff in .eng domain that
-may not be accessible in other domains these files are just
-copied here so local builds in other domains will work.
-These files rarely change so the fact that we might have to
-strobe in new ones on rare occasions is no big deal.
--- a/hotspot/agent/src/os/solaris/dbx/README-commands.txt Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-This import module uses a largely text-based protocol, except for
-certain bulk data transfer operations. All text is in single-byte
-US-ASCII.
-
-Commands understood:
-
-address_size ::= <int result>
-
- Returns 32 if attached to 32-bit process, 64 if 64-bit.
-
-peek_fail_fast <bool arg> ::=
-
- Indicates whether "peek" requests should "fail fast"; that is, if
- any of the addresses in the requested range are unmapped, report
- the entire range as unmapped. This is substantially faster than
- the alternative, which is to read the entire range byte-by-byte.
- However, it should only be used when it is guaranteed by the
- client application that peeks come from at most one page. The
- default is that peek_fast_fail is not enabled.
-
-peek <address addr> <unsigned int numBytes> ::=
- B<binary char success>
- [<binary unsigned int len> <binary char isMapped> [<binary char data>]...]...
-
- NOTE that the binary portion of this message is prefixed by the
- uppercase US-ASCII letter 'B', allowing easier synchronization by
- clients. There is no data between the 'B' and the rest of the
- message.
-
- May only be called once attached. Reads the address space of the
- target process starting at the given address (see below for format
- specifications) and extending the given number of bytes. Whether
- the read succeeded is indicated by a single byte containing a 1 or
- 0 (success or failure). If successful, the return result is given
- in a sequence of ranges. _len_, the length of each range, is
- indicated by a 32-bit unsigned integer transmitted with big-endian
- byte ordering (i.e., most significant byte first). _isMapped_
- indicates whether the range is mapped or unmapped in the target
- process's address space, and will contain the value 1 or 0 for
- mapped or unmapped, respectively. If the range is mapped,
- _isMapped_ is followed by _data_, containing the raw binary data
- for the range. The sum of all ranges' lengths is guaranteed to be
- equivalent to the number of bytes requested.
-
-poke <address addr> <int numBytes> B[<binary char data>]... ::= <bool result>
-
- NOTE that the binary portion of this message is prefixed by the
- uppercase US-ASCII letter 'B', allowing easier synchronization by
- clients. There is no data between the 'B' and the rest of the
- message.
-
- Writes the given data to the target process starting at the given
- address. Returns 1 on success, 0 on failure (i.e., one or more of
- target addresses were unmapped).
-
-mapped <address addr> <int numBytes> ::= <bool result>
-
- Returns 1 if entire address range [address...address + int arg) is
- mapped in target process's address space, 0 if not
-
-lookup <symbol objName> <symbol sym> ::= <address addr>
-
- First symbol is object name; second is symbol to be looked up.
- Looks up symbol in target process's symbol table and returns
- address. Returns NULL (0x0) if symbol is not found.
-
-thr_gregs <int tid> ::= <int numAddresses> <address...>
-
- Fetch the "general" (integer) register set for the given thread.
- Returned as a series of hexidecimal values. NOTE: the meaning of
- the return value is architecture-dependent. In general it is the
- contents of the prgregset_t.
-
-exit ::=
-
- Exits the serviceability agent dbx module, returning control to
- the dbx prompt.
-
-// Data formats and example values:
-<address> ::= 0x12345678[9ABCDEF0] /* up to 64-bit hex value */
-<unsigned int> ::= 5 /* up to 32-bit integer number; no leading sign */
-<bool> ::= 1 /* ASCII '0' or '1' */
--- a/hotspot/agent/src/os/solaris/dbx/helloWorld.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-#include <inttypes.h>
-
-extern "C" {
- const char* helloWorldString = "Hello, world!";
- // Do not change these values without changing TestDebugger.java as well
- // FIXME: should make these jbyte, jshort, etc...
- volatile int8_t testByte = 132;
- volatile int16_t testShort = 27890;
- volatile int32_t testInt = 1020304050;
- volatile int64_t testLong = 102030405060708090LL;
- volatile float testFloat = 35.4F;
- volatile double testDouble = 1.23456789;
-
- volatile int helloWorldTrigger = 0;
-}
-
-int
-main(int, char**) {
- while (1) {
- while (helloWorldTrigger == 0) {
- }
-
- fprintf(stderr, "%s\n", helloWorldString);
- fprintf(stderr, "testByte=%d\n", testByte);
- fprintf(stderr, "testShort=%d\n", testShort);
- fprintf(stderr, "testInt=%d\n", testInt);
- fprintf(stderr, "testLong=%d\n", testLong);
- fprintf(stderr, "testFloat=%d\n", testFloat);
- fprintf(stderr, "testDouble=%d\n", testDouble);
-
- while (helloWorldTrigger != 0) {
- }
- }
-}
--- a/hotspot/agent/src/os/solaris/dbx/proc_service_2.h Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _PROC_SERVICE_2_H
-#define _PROC_SERVICE_2_H
-
-/*
- * Types, function definitions for the provider of services beyond
- * proc_service. This interface will be used by import modules like
- * BAT/prex, NEO debugger etc.
- */
-
-/*
- CCR info
-
- Version history:
-
- 1.0 - Initial CCR release
-
- 1.1 - Changes for GLUE/neo.
- New entry points ps_svnt_generic() and ps_svc_generic()
- - New entry point ps_getpid()
-
- Release information for automatic CCR updates:
- BEGIN RELEASE NOTES: (signifies what gets put into CCR release notes)
- 1.2 - Changes to support Solaris 2.7
-
- END RELEASE NOTES: (signifies what gets put into CCR release notes)
-
- Following is used for CCR version number:
-
-#define CCR_PROC_SERVICE_2_VERSION 1.2
-
-*/
-
-
-#include <proc_service.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ps_loadobj {
- int objfd; /* fd of the load object or executable
- * -1 implies its not available.
- * This file decriptor is live only during the
- * particular call to ps_iter_f(). If you
- * need it beyond that you need to dup() it.
- */
- psaddr_t
- text_base; /* address where text of loadobj was mapped */
- psaddr_t
- data_base; /* address where data of loadobj was mapped */
- const char *objname; /* loadobj name */
-};
-
-typedef int ps_iter_f(const struct ps_prochandle *, const struct ps_loadobj *,
- void *cd);
-
-/*
- * Returns the ps_prochandle for the current process under focus. Returns
- * NULL if there is none.
- */
-
-const struct ps_prochandle *
-ps_get_prochandle(void);
-
-/*
- * Returns the ps_prochandle for the current process(allows core files to
- * be specified) under focus. Returns NULL if there is none.
- */
-const struct ps_prochandle *
-ps_get_prochandle2(int cores_too);
-
-/*
- * Returns the pid of the process referred to by the ps_prochandle.
- *
- * 0 is returned in case the ps_prochandle is not valid or refers to dead
- * process.
- *
- */
-pid_t
-ps_getpid(const struct ps_prochandle *);
-
-/*
- * Iteration function that iterates over all load objects *and the
- * executable*
- *
- * If the callback routine returns:
- * 0 - continue processing link objects
- * non zero - stop calling the callback function
- *
- */
-
-ps_err_e
-ps_loadobj_iter(const struct ps_prochandle *, ps_iter_f *, void *clnt_data);
-
-/*
- * Address => function name mapping
- *
- * Given an address, returns a pointer to the function's
- * linker name (null terminated).
- */
-
-ps_err_e
-ps_find_fun_name(const struct ps_prochandle *, psaddr_t addr,
- const char **name);
-
-/*
- * Interface to LD_PRELOAD. LD_PRELOAD given library across the
- * program 'exec'.
- *
- */
-
-/*
- * Append/Prepend the 'lib' (has to be library name as understood by LD_PRELOAD)
- * to the LD_PRELOAD variable setting to be used by the debugee
- * Returns a cookie (in id).
- */
-ps_err_e
-ps_ld_preload_append(const char *lib, int *id);
-ps_err_e
-ps_ld_preload_prepend(const char *lib, int *id);
-
-/*
- * Remove the library associated with 'id' from the LD_PRELOAD setting.
- *
- */
-ps_err_e
-ps_ld_preload_remove(int id);
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * The following are C++ only interfaces
- */
-#ifdef __cplusplus
-
-/*
- * classes ServiceDbx and ServantDbx and defined in "gp_dbx_svc.h" which is
- * accessed via CCR
- */
-extern class ServantDbx *ps_svnt_generic();
-extern class ServiceDbx *ps_svc_generic();
-
-#endif
-
-#endif /* _PROC_SERVICE_2_H */
--- a/hotspot/agent/src/os/solaris/dbx/shell_imp.h Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHELL_IMP_H
-#define SHELL_IMP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-
-/*
- CCR info
-
- Vesrion history:
-
- 1.0 - Initial CCR release
-
- Release information for automatic CCR updates:
-
- BEGIN RELEASE NOTES: (signifies what gets put into CCR release notes)
- 1.1
- - Entry points for va_list style msgs; new shell_imp_vmsg()
- and shell_imp_verrmsg()
- - shell_imp_env_checker() is now shell_imp_var_checker().
- Also the var_checker callback gets passed interp.
- 1.2 - interposition framework (used by jdbx)
- - access to input FILE pointer.
-
- END RELEASE NOTES: (signifies what gets put into CCR release notes)
-
-Following is used as a CCR version number:
-#define CCR_SHELL_IMP_VERSION 1.1
-*/
-
-#include <stdarg.h>
-
-#define SHELL_IMP_MAJOR 1
-#define SHELL_IMP_MINOR 2
-#define SHELL_IMP_FLAG_GLOB 0x1
-#define SHELL_IMP_FLAG_ARGQ 0x2
-
-typedef void *shell_imp_interp_t;
-typedef void *shell_imp_command_t;
-typedef int shell_imp_fun_t(shell_imp_interp_t, int, char **, void *);
-
-int
-shell_imp_init(
- int, /* major version number */
- int, /* minor version number */
- shell_imp_interp_t, /* interpreter */
- int, /* argc */
- char *[] /* argv */
-);
-
-int
-shell_imp_fini(shell_imp_interp_t);
-
-shell_imp_command_t
-shell_imp_define_command(char *, /* command name e.g. "tnf" */
- shell_imp_fun_t *, /* callback function */
- int, /* SHELL_IMP_FLAG_* bit vector */
- void *, /* client_data Passed as last arg to
- /* callback function */
- char * /* help message, e.g. */
- /* "enable the specified tnf probes" */
- );
-
-int
-shell_imp_undefine_command(shell_imp_command_t);
-
-int
-shell_imp_var_checker(shell_imp_interp_t,
- const char *, /* var name */
- int (*)(shell_imp_interp_t, const char*) /* env checker */
- );
-
-int
-shell_imp_execute(shell_imp_interp_t, const char *);
-
-const char *
-shell_imp_get_var(shell_imp_interp_t, const char *);
-
-void
-shell_imp_msg(shell_imp_interp_t, const char *, ...);
-
-void
-shell_imp_errmsg(shell_imp_interp_t, const char *, ...);
-
-void
-shell_imp_vmsg(shell_imp_interp_t, const char *, va_list);
-
-void
-shell_imp_verrmsg(shell_imp_interp_t, const char *, va_list);
-
-
-
-/*
- * Stuff added for 1.2
- */
-
-struct shell_imp_interposition_info_t {
- shell_imp_fun_t *
- new_func;
- void * new_client_data;
- shell_imp_fun_t *
- original_func;
- void * original_client_data;
- int original_flags;
-};
-
-typedef int shell_imp_dispatcher_t(shell_imp_interp_t, int, char **,
- shell_imp_interposition_info_t *);
-
-shell_imp_command_t
-shell_imp_interpose(char *name,
- shell_imp_fun_t *new_func,
- int flags,
- void *client_data,
- char * description,
- shell_imp_dispatcher_t *);
-
-int shell_imp_uninterpose(shell_imp_command_t);
-
-int
-shell_imp_dispatch_interposition(shell_imp_interp_t,
- shell_imp_interposition_info_t *,
- int argc, char *argv[]);
-
-int
-shell_imp_dispatch_original(shell_imp_interp_t,
- shell_imp_interposition_info_t *,
- int argc, char *argv[]);
-
-FILE *
-shell_imp_cur_input(shell_imp_interp_t);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1068 +0,0 @@
-/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-// This is the implementation of a very simple dbx import module which
-// handles requests from the VM which come in over a socket. The
-// higher-level Java wrapper for dbx starts the debugger, attaches to
-// the process, imports this command, and runs it. After that, the SA
-// writes commands to this agent via its own private communications
-// channel. The intent is to move away from the text-based front-end
-// completely in the near future (no more calling "debug" by printing
-// text to dbx's stdin).
-
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <string.h>
-#include <stropts.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <proc_service.h>
-#include <sys/procfs_isa.h>
-#include <rtld_db.h>
-#include "proc_service_2.h"
-#include "svc_agent_dbx.hpp"
-
-static ServiceabilityAgentDbxModule* module = NULL;
-#define NEEDS_CLEANUP
-
-// Useful for debugging
-#define VERBOSE_DEBUGGING
-
-#ifdef VERBOSE_DEBUGGING
-# define debug_only(x) x
-#else
-# define debug_only(x)
-#endif
-
-// For profiling
-//#define PROFILING
-
-#ifdef PROFILING
-#define PROFILE_COUNT 200
-static Timer scanTimer;
-static Timer workTimer;
-static Timer writeTimer;
-static int numRequests = 0;
-#endif /* PROFILING */
-
-const char* ServiceabilityAgentDbxModule::CMD_ADDRESS_SIZE = "address_size";
-const char* ServiceabilityAgentDbxModule::CMD_PEEK_FAIL_FAST = "peek_fail_fast";
-const char* ServiceabilityAgentDbxModule::CMD_PEEK = "peek";
-const char* ServiceabilityAgentDbxModule::CMD_POKE = "poke";
-const char* ServiceabilityAgentDbxModule::CMD_MAPPED = "mapped";
-const char* ServiceabilityAgentDbxModule::CMD_LOOKUP = "lookup";
-const char* ServiceabilityAgentDbxModule::CMD_THR_GREGS = "thr_gregs";
-const char* ServiceabilityAgentDbxModule::CMD_EXIT = "exit";
-
-// The initialization routines must not have C++ name mangling
-extern "C" {
-
-/** This is the initialization routine called by dbx upon importing of
- this module. Returns 0 upon successful initialization, -1 upon
- failure. */
-int shell_imp_init(int major, int minor,
- shell_imp_interp_t interp, int argc, char *argv[])
-{
- // Ensure shell interpreter data structure is laid out the way we
- // expect
- if (major != SHELL_IMP_MAJOR) {
- debug_only(fprintf(stderr, "Serviceability agent: unexpected value for SHELL_IMP_MAJOR (got %d, expected %d)\n", major, SHELL_IMP_MAJOR);)
- return -1;
- }
- if (minor < SHELL_IMP_MINOR) {
- debug_only(fprintf(stderr, "Serviceability agent: unexpected value for SHELL_IMP_MINOR (got %d, expected >= %d)\n", minor, SHELL_IMP_MINOR);)
- return -1;
- }
-
- if (module != NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: module appears to already be initialized (should not happen)\n");)
- // Already initialized. Should not happen.
- return -1;
- }
-
- module = new ServiceabilityAgentDbxModule(major, minor, interp, argc, argv);
- if (!module->install()) {
- debug_only(fprintf(stderr, "Serviceability agent: error installing import module\n");)
- delete module;
- module = NULL;
- return -1;
- }
-
- // Installation was successful. Next step will be for the user to
- // enter the appropriate command on the command line, which will
- // make the SA's dbx module wait for commands to come in over the
- // socket.
- return 0;
-}
-
-/** This is the routine called by dbx upon unloading of this module.
- Returns 0 upon success, -1 upon failure. */
-int
-shell_imp_fini(shell_imp_interp_t)
-{
- if (module == NULL) {
- return -1;
- }
-
- bool res = module->uninstall();
- delete module;
- module = NULL;
- if (!res) {
- return -1;
- }
- return 0;
-}
-
-} // extern "C"
-
-/** This is the routine which is called by the dbx shell when the user
- requests the serviceability agent module to run. This delegates to
- ServiceabilityAgentDbxModule::run. This routine's signature must
- match that of shell_imp_fun_t. */
-extern "C" {
-static int
-svc_agent_run(shell_imp_interp_t, int, char **, void *) {
- if (module == NULL) {
- return -1;
- }
-
- module->run();
- return 0;
-}
-}
-
-/*
- * Implementation of ServiceabilityAgentDbxModule class
- */
-
-// NOTE: we need to forward declare the special "ps_get_prochandle2"
-// function which allows examination of core files as well. It isn't
-// currently in proc_service_2.h. Note also that it has name mangling
-// because it isn't declared extern "C".
-//const struct ps_prochandle *ps_get_prochandle2(int cores_too);
-
-ServiceabilityAgentDbxModule::ServiceabilityAgentDbxModule(int, int, shell_imp_interp_t interp,
- int argc, char *argv[])
- :myComm(32768, 131072)
-{
- _interp = interp;
- _argc = argc;
- _argv = argv;
- _tdb_agent = NULL;
- peek_fail_fast = false;
- libThreadName = NULL;
-}
-
-ServiceabilityAgentDbxModule::~ServiceabilityAgentDbxModule() {
- if (_command != NULL) {
- uninstall();
- }
-}
-
-char*
-readCStringFromProcess(psaddr_t addr) {
- char c;
- int num = 0;
- ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
-
- // Search for null terminator
- do {
- if (ps_pread(cur_proc, addr + num, &c, 1) != PS_OK) {
- return NULL;
- }
- ++num;
- } while (c != 0);
-
- // Allocate string
- char* res = new char[num];
- if (ps_pread(cur_proc, addr, res, num) != PS_OK) {
- delete[] res;
- return NULL;
- }
- return res;
-}
-
-int
-findLibThreadCB(const rd_loadobj_t* lo, void* data) {
- ServiceabilityAgentDbxModule* module = (ServiceabilityAgentDbxModule*) data;
- char* name = readCStringFromProcess(lo->rl_nameaddr);
- if (strstr(name, "libthread.so") != NULL) {
- module->libThreadName = name;
- return 0;
- } else {
- delete[] name;
- return 1;
- }
-}
-
-bool
-ServiceabilityAgentDbxModule::install() {
- // NOTE interdependency between here and Java side wrapper
- // FIXME: casts of string literal to char * to match prototype
- _command = shell_imp_define_command((char *) "svc_agent_run",
- &svc_agent_run,
- 0,
- NULL,
- (char *) "Run the serviceability agent's dbx module.\n"
- "This routine causes the module to listen on a socket for requests.\n"
- "It does not return until the Java-side code tells it to exit, at\n"
- "which point control is returned to the dbx shell.");
- if (_command == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: Failed to install svc_agent_run command\n"));
- return false;
- }
-
- // This is fairly painful. Since dbx doesn't currently load
- // libthread_db with RTLD_GLOBAL, we can't just use RTLD_DEFAULT for
- // the argument to dlsym. Instead, we have to use rtld_db to search
- // through the loaded objects in the target process for libthread.so and
-
- // Try rtld_db
- if (rd_init(RD_VERSION) != RD_OK) {
- debug_only(fprintf(stderr, "Serviceability agent: Unable to init rtld_db\n"));
- return false;
- }
-
- rd_agent_t* rda = rd_new((struct ps_prochandle*) ps_get_prochandle2(1));
- if (rda == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: Unable to allocate rtld_db agent\n"));
- return false;
- }
-
- if (rd_loadobj_iter(rda, (rl_iter_f*) findLibThreadCB, this) != RD_OK) {
- debug_only(fprintf(stderr, "Serviceability agent: Loadobject iteration failed\n"));
- return false;
- }
-
- if (libThreadName == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: Failed to find pathname to libthread.so in target process\n"));
- return false;
- }
-
- // Find and open libthread_db.so
- char* slash = strrchr(libThreadName, '/');
- if (slash == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: can't parse path to libthread.so \"%s\"\n"));
- return false;
- }
-
- int slashPos = slash - libThreadName;
- char* buf = new char[slashPos + strlen("libthread_db.so") + 20]; // slop
- if (buf == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: error allocating libthread_db.so pathname\n"));
- return false;
- }
- strncpy(buf, libThreadName, slashPos + 1);
-
- // Check dbx's data model; use sparcv9/ subdirectory if 64-bit and
- // if target process is 32-bit
- if ((sizeof(void*) == 8) &&
- (strstr(libThreadName, "sparcv9") == NULL)) {
- strcpy(buf + slashPos + 1, "sparcv9/");
- slashPos += strlen("sparcv9/");
- }
-
- strcpy(buf + slashPos + 1, "libthread_db.so");
-
- libThreadDB = dlopen(buf, RTLD_LAZY);
- void* tmpDB = libThreadDB;
- if (libThreadDB == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: Warning: unable to find libthread_db.so at \"%s\"\n", buf));
- // Would like to handle this case as well. Maybe dbx has a better
- // idea of where libthread_db.so lies. If the problem with dbx
- // loading libthread_db without RTLD_GLOBAL specified ever gets
- // fixed, we could run this code all the time.
- tmpDB = RTLD_DEFAULT;
- }
-
- delete[] buf;
-
- // Initialize access to libthread_db
- td_init_fn = (td_init_fn_t*) dlsym(tmpDB, "td_init");
- td_ta_new_fn = (td_ta_new_fn_t*) dlsym(tmpDB, "td_ta_new");
- td_ta_delete_fn = (td_ta_delete_fn_t*) dlsym(tmpDB, "td_ta_delete");
- td_ta_map_id2thr_fn = (td_ta_map_id2thr_fn_t*) dlsym(tmpDB, "td_ta_map_id2thr");
- td_thr_getgregs_fn = (td_thr_getgregs_fn_t*) dlsym(tmpDB, "td_thr_getgregs");
-
- if (td_init_fn == NULL ||
- td_ta_new_fn == NULL ||
- td_ta_delete_fn == NULL ||
- td_ta_map_id2thr_fn == NULL ||
- td_thr_getgregs_fn == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: Failed to find one or more libthread_db symbols:\n"));
- debug_only(if (td_init_fn == NULL) fprintf(stderr, " td_init\n"));
- debug_only(if (td_ta_new_fn == NULL) fprintf(stderr, " td_ta_new\n"));
- debug_only(if (td_ta_delete_fn == NULL) fprintf(stderr, " td_ta_delete\n"));
- debug_only(if (td_ta_map_id2thr_fn == NULL) fprintf(stderr, " td_ta_map_id2thr\n"));
- debug_only(if (td_thr_getgregs_fn == NULL) fprintf(stderr, " td_thr_getgregs\n"));
- return false;
- }
-
- if ((*td_init_fn)() != TD_OK) {
- debug_only(fprintf(stderr, "Serviceability agent: Failed to initialize libthread_db\n"));
- return false;
- }
-
- return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::uninstall() {
- if (_command == NULL) {
- return false;
- }
-
- if (libThreadDB != NULL) {
- dlclose(libThreadDB);
- libThreadDB = NULL;
- }
-
- int res = shell_imp_undefine_command(_command);
-
- if (res != 0) {
- return false;
- }
-
- return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::run() {
- // This is where most of the work gets done.
- // The command processor loop looks like the following:
- // - create listening socket
- // - accept a connection (only one for now)
- // - while that connection is open and the "exit" command has not
- // been received:
- // - read command
- // - if it's the exit command, cleanup and return
- // - otherwise, process command and write result
-
- int listening_socket = socket(AF_INET, SOCK_STREAM, 0);
- if (listening_socket < 0) {
- return false;
- }
-
- // Set the SO_REUSEADDR property on the listening socket. This
- // prevents problems with calls to bind() to the same port failing
- // after this process exits. This seems to work on all platforms.
- int reuse_address = 1;
- if (setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
- (char *)&reuse_address, sizeof(reuse_address)) < 0) {
- close(listening_socket);
- return false;
- }
-
- sockaddr_in server_address;
- // Build the server address. We can bind the listening socket to the
- // INADDR_ANY internet address.
- memset((char*)&server_address, 0, sizeof(server_address));
- server_address.sin_family = AF_INET;
- server_address.sin_addr.s_addr = (unsigned long)htonl(INADDR_ANY);
- server_address.sin_port = htons((short)PORT);
-
- // Bind socket to port
- if (bind(listening_socket, (sockaddr*) &server_address,
- sizeof(server_address)) < 0) {
- close(listening_socket);
- return false;
- }
-
- // Arbitrarily chosen backlog of 5 (shouldn't matter since we expect
- // at most one connection)
- if (listen(listening_socket, 5) < 0) {
- close(listening_socket);
- return false;
- }
-
- // OK, now ready to wait for a data connection. This call to
- // accept() will block.
- struct sockaddr_in client_address;
- int address_len = sizeof(client_address);
- int client_socket = accept(listening_socket, (sockaddr*) &client_address,
- &address_len);
- // Close listening socket regardless of whether accept() succeeded.
- // (FIXME: this may be annoying, especially during debugging, but I
- // really feel that robustness and multiple connections should be
- // handled higher up, e.g., at the Java level -- multiple clients
- // could conceivably connect to the SA via RMI, and that would be a
- // more robust solution than implementing multiple connections at
- // this level)
- NEEDS_CLEANUP;
-
- // NOTE: the call to shutdown() usually fails, so don't panic if this happens
- shutdown(listening_socket, 2);
-
- if (close(listening_socket) < 0) {
- debug_only(fprintf(stderr, "Serviceability agent: Error closing listening socket\n"));
- return false;
- }
-
- if (client_socket < 0) {
- debug_only(fprintf(stderr, "Serviceability agent: Failed to open client socket\n"));
- // No more cleanup necessary
- return false;
- }
-
- // Attempt to disable TCP buffering on this socket. We send small
- // amounts of data back and forth and don't want buffering.
- int buffer_val = 1;
- if (setsockopt(client_socket, IPPROTO_IP, TCP_NODELAY, (char *) &buffer_val, sizeof(buffer_val)) < 0) {
- debug_only(fprintf(stderr, "Serviceability agent: Failed to set TCP_NODELAY option on client socket\n"));
- cleanup(client_socket);
- return false;
- }
-
- // OK, we have the data socket through which we will communicate
- // with the Java side. Wait for commands or until reading or writing
- // caused an error.
-
- bool should_continue = true;
-
- myComm.setSocket(client_socket);
-
-#ifdef PROFILING
- scanTimer.reset();
- workTimer.reset();
- writeTimer.reset();
-#endif
-
- // Allocate a new thread agent for libthread_db
- if ((*td_ta_new_fn)((ps_prochandle*) ps_get_prochandle2(1), &_tdb_agent) !=
- TD_OK) {
- debug_only(fprintf(stderr, "Serviceability agent: Failed to allocate thread agent\n"));
- cleanup(client_socket);
- return false;
- }
-
- do {
- // Decided to use text to communicate between these processes.
- // Probably will make debugging easier -- could telnet in if
- // necessary. Will make scanning harder, but probably doesn't
- // matter.
-
- // Why not just do what workshop does and parse dbx's console?
- // Probably could do that, but at least this way we are in control
- // of the text format on both ends.
-
- // FIXME: should have some way of synchronizing these commands
- // between the C and Java sources.
-
- NEEDS_CLEANUP;
-
- // Do a blocking read of a line from the socket.
- char *input_buffer = myComm.readLine();
- if (input_buffer == NULL) {
- debug_only(fprintf(stderr, "Serviceability agent: error during read: errno = %d\n", errno));
- debug_only(perror("Serviceability agent"));
- // Error occurred during read.
- // FIXME: should guard against SIGPIPE
- cleanup(client_socket);
- return false;
- }
-
- // OK, now ready to scan. See README-commands.txt for syntax
- // descriptions.
-
- bool res = false;
- if (!strncmp(input_buffer, CMD_ADDRESS_SIZE, strlen(CMD_ADDRESS_SIZE))) {
- res = handleAddressSize(input_buffer + strlen(CMD_ADDRESS_SIZE));
- } else if (!strncmp(input_buffer, CMD_PEEK_FAIL_FAST, strlen(CMD_PEEK_FAIL_FAST))) {
- res = handlePeekFailFast(input_buffer + strlen(CMD_PEEK_FAIL_FAST));
- } else if (!strncmp(input_buffer, CMD_PEEK, strlen(CMD_PEEK))) {
- res = handlePeek(input_buffer + strlen(CMD_PEEK));
- } else if (!strncmp(input_buffer, CMD_POKE, strlen(CMD_POKE))) {
- res = handlePoke(input_buffer + strlen(CMD_POKE));
- } else if (!strncmp(input_buffer, CMD_MAPPED, strlen(CMD_MAPPED))) {
- res = handleMapped(input_buffer + strlen(CMD_MAPPED));
- } else if (!strncmp(input_buffer, CMD_LOOKUP, strlen(CMD_LOOKUP))) {
- res = handleLookup(input_buffer + strlen(CMD_LOOKUP));
- } else if (!strncmp(input_buffer, CMD_THR_GREGS, strlen(CMD_THR_GREGS))) {
- res = handleThrGRegs(input_buffer + strlen(CMD_THR_GREGS));
- } else if (!strncmp(input_buffer, CMD_EXIT, strlen(CMD_EXIT))) {
- should_continue = false;
- }
-
- if (should_continue) {
- if (!res) {
- cleanup(client_socket);
- return false;
- }
- }
-
-#ifdef PROFILING
- if (++numRequests == PROFILE_COUNT) {
- fprintf(stderr, "%d requests: %d ms scanning, %d ms work, %d ms writing\n",
- PROFILE_COUNT, scanTimer.total(), workTimer.total(), writeTimer.total());
- fflush(stderr);
- scanTimer.reset();
- workTimer.reset();
- writeTimer.reset();
- numRequests = 0;
- }
-#endif
-
- } while (should_continue);
-
- // Successful exit
- cleanup(client_socket);
- return true;
-}
-
-void
-ServiceabilityAgentDbxModule::cleanup(int client_socket) {
- shutdown(client_socket, 2);
- close(client_socket);
- if (_tdb_agent != NULL) {
- (*td_ta_delete_fn)(_tdb_agent);
- }
-}
-
-bool
-ServiceabilityAgentDbxModule::handleAddressSize(char* data) {
- int data_model;
- ps_err_e result = ps_pdmodel((ps_prochandle*) ps_get_prochandle2(1),
- &data_model);
- if (result != PS_OK) {
- myComm.writeString("0");
- myComm.flush();
- return false;
- }
-
- int val;
- switch (data_model) {
- case PR_MODEL_ILP32:
- val = 32;
- break;
- case PR_MODEL_LP64:
- val = 64;
- break;
- default:
- val = 0;
- break;
- }
-
- if (!myComm.writeInt(val)) {
- return false;
- }
- if (!myComm.writeEOL()) {
- return false;
- }
- return myComm.flush();
-}
-
-bool
-ServiceabilityAgentDbxModule::handlePeekFailFast(char* data) {
- unsigned int val;
- if (!scanUnsignedInt(&data, &val)) {
- return false;
- }
- peek_fail_fast = (val ? true : false);
- return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::handlePeek(char* data) {
- // Scan hex address, return false if failed
- psaddr_t addr;
-#ifdef PROFILING
- scanTimer.start();
-#endif /* PROFILING */
- if (!scanAddress(&data, &addr)) {
- return false;
- }
- unsigned int num;
- if (!scanUnsignedInt(&data, &num)) {
- return false;
- }
- if (num == 0) {
-#ifdef PROFILING
- writeTimer.start();
-#endif /* PROFILING */
- myComm.writeBinChar('B');
- myComm.writeBinChar(1);
- myComm.writeBinUnsignedInt(0);
- myComm.writeBinChar(0);
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
- return true;
- }
-#ifdef PROFILING
- scanTimer.stop();
- workTimer.start();
-#endif /* PROFILING */
- char* buf = new char[num];
- ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
- ps_err_e result = ps_pread(cur_proc, addr, buf, num);
- if (result == PS_OK) {
- // Fast case; entire read succeeded.
-#ifdef PROFILING
- workTimer.stop();
- writeTimer.start();
-#endif /* PROFILING */
- myComm.writeBinChar('B');
- myComm.writeBinChar(1);
- myComm.writeBinUnsignedInt(num);
- myComm.writeBinChar(1);
- myComm.writeBinBuf(buf, num);
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
- } else {
-#ifdef PROFILING
- workTimer.stop();
-#endif /* PROFILING */
-
- if (peek_fail_fast) {
-#ifdef PROFILING
- writeTimer.start();
-#endif /* PROFILING */
- // Fail fast
- myComm.writeBinChar('B');
- myComm.writeBinChar(1);
- myComm.writeBinUnsignedInt(num);
- myComm.writeBinChar(0);
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
- } else {
- // Slow case: try to read one byte at a time
- // FIXME: need better way of handling this, a la VirtualQuery
-
- unsigned int strideLen = 0;
- int bufIdx = 0;
- bool lastByteMapped = (ps_pread(cur_proc, addr, buf, 1) == PS_OK ? true : false);
-
-#ifdef PROFILING
- writeTimer.start();
-#endif /* PROFILING */
- myComm.writeBinChar('B');
- myComm.writeBinChar(1);
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
-
- for (int i = 0; i < num; ++i, ++addr) {
-#ifdef PROFILING
- workTimer.start();
-#endif /* PROFILING */
- result = ps_pread(cur_proc, addr, &buf[bufIdx], 1);
-#ifdef PROFILING
- workTimer.stop();
-#endif /* PROFILING */
- bool tmpMapped = (result == PS_OK ? true : false);
-#ifdef PROFILING
- writeTimer.start();
-#endif /* PROFILING */
- if (tmpMapped != lastByteMapped) {
- // State change. Write the length of the last stride.
- myComm.writeBinUnsignedInt(strideLen);
- if (lastByteMapped) {
- // Stop gathering data. Write the data of the last stride.
- myComm.writeBinChar(1);
- myComm.writeBinBuf(buf, strideLen);
- bufIdx = 0;
- } else {
- // Start gathering data to write.
- myComm.writeBinChar(0);
- }
- strideLen = 0;
- lastByteMapped = tmpMapped;
- }
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
- if (lastByteMapped) {
- ++bufIdx;
- }
- ++strideLen;
- }
-
- // Write last stride (must be at least one byte long by definition)
-#ifdef PROFILING
- writeTimer.start();
-#endif /* PROFILING */
- myComm.writeBinUnsignedInt(strideLen);
- if (lastByteMapped) {
- myComm.writeBinChar(1);
- myComm.writeBinBuf(buf, strideLen);
- } else {
- myComm.writeBinChar(0);
- }
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
- }
- }
- delete[] buf;
- myComm.flush();
- return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::handlePoke(char* data) {
- // FIXME: not yet implemented
- NEEDS_CLEANUP;
- bool res = myComm.writeBoolAsInt(false);
- myComm.flush();
- return res;
-}
-
-bool
-ServiceabilityAgentDbxModule::handleMapped(char* data) {
- // Scan address
- psaddr_t addr;
- if (!scanAddress(&data, &addr)) {
- return false;
- }
- unsigned int num;
- if (!scanUnsignedInt(&data, &num)) {
- return false;
- }
- unsigned char val;
- ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
- char* buf = new char[num];
- if (ps_pread(cur_proc, addr, buf, num) == PS_OK) {
- myComm.writeBoolAsInt(true);
- } else {
- myComm.writeBoolAsInt(false);
- }
- delete[] buf;
- myComm.writeEOL();
- myComm.flush();
- return true;
-}
-
-extern "C"
-int loadobj_iterator(const rd_loadobj_t* loadobj, void *) {
- if (loadobj != NULL) {
- fprintf(stderr, "loadobj_iterator: visited loadobj \"%p\"\n", (void*) loadobj->rl_nameaddr);
- return 1;
- }
-
- fprintf(stderr, "loadobj_iterator: NULL loadobj\n");
- return 0;
-}
-
-bool
-ServiceabilityAgentDbxModule::handleLookup(char* data) {
- // Debugging: iterate over loadobjs
- /*
- rd_agent_t* rld_agent = rd_new((ps_prochandle*) ps_get_prochandle2(1));
- rd_loadobj_iter(rld_agent, &loadobj_iterator, NULL);
- rd_delete(rld_agent);
- */
-
-#ifdef PROFILING
- scanTimer.start();
-#endif /* PROFILING */
-
- char* object_name = scanSymbol(&data);
- if (object_name == NULL) {
- return false;
- }
- char* symbol_name = scanSymbol(&data);
- if (symbol_name == NULL) {
- delete[] object_name;
- return false;
- }
-
-#ifdef PROFILING
- scanTimer.stop();
- workTimer.start();
-#endif /* PROFILING */
-
- ps_sym_t sym;
- // FIXME: check return values from write routines
- ps_prochandle* process = (ps_prochandle*) ps_get_prochandle2(1);
- ps_err_e lookup_res = ps_pglobal_sym(process,
- object_name, symbol_name, &sym);
-#ifdef PROFILING
- workTimer.stop();
- writeTimer.start();
-#endif /* PROFILING */
-
- delete[] object_name;
- delete[] symbol_name;
- if (lookup_res != PS_OK) {
- // This is too noisy
- // debug_only(fprintf(stderr, "ServiceabilityAgentDbxModule::handleLookup: error %d\n", lookup_res));
- myComm.writeString("0x0");
- } else {
- myComm.writeAddress((void *)sym.st_value);
- }
- myComm.writeEOL();
- myComm.flush();
-
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
-
- return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::handleThrGRegs(char* data) {
-#ifdef PROFILING
- scanTimer.start();
-#endif /* PROFILING */
-
- unsigned int num;
- // Get the thread ID
- if (!scanUnsignedInt(&data, &num)) {
- return false;
- }
-
-#ifdef PROFILING
- scanTimer.stop();
- workTimer.start();
-#endif /* PROFILING */
-
- // Map tid to thread handle
- td_thrhandle_t thread_handle;
- if ((*td_ta_map_id2thr_fn)(_tdb_agent, num, &thread_handle) != TD_OK) {
- // fprintf(stderr, "Error mapping thread ID %d to thread handle\n", num);
- return false;
- }
-
- // Fetch register set
- prgregset_t reg_set;
- memset(reg_set, 0, sizeof(reg_set));
- td_err_e result = (*td_thr_getgregs_fn)(&thread_handle, reg_set);
- if ((result != TD_OK) && (result != TD_PARTIALREG)) {
- // fprintf(stderr, "Error fetching registers for thread handle %d: error = %d\n", num, result);
- return false;
- }
-
-#ifdef PROFILING
- workTimer.stop();
- writeTimer.start();
-#endif /* PROFILING */
-
-#if (defined(__sparc) || defined(__i386))
- myComm.writeInt(NPRGREG);
- myComm.writeSpace();
- for (int i = 0; i < NPRGREG; i++) {
- myComm.writeAddress((void *)reg_set[i]);
- if (i == NPRGREG - 1) {
- myComm.writeEOL();
- } else {
- myComm.writeSpace();
- }
- }
-#else
-#error Please port ServiceabilityAgentDbxModule::handleThrGRegs to your current platform
-#endif
-
- myComm.flush();
-
-#ifdef PROFILING
- writeTimer.stop();
-#endif /* PROFILING */
-
- return true;
-}
-
-//
-// Input routines
-//
-
-bool
-ServiceabilityAgentDbxModule::scanAddress(char** data, psaddr_t* addr) {
- *addr = 0;
-
- // Skip whitespace
- while ((**data != 0) && (isspace(**data))) {
- ++*data;
- }
-
- if (**data == 0) {
- return false;
- }
-
- if (strncmp(*data, "0x", 2) != 0) {
- return false;
- }
-
- *data += 2;
-
- while ((**data != 0) && (!isspace(**data))) {
- int val;
- bool res = charToNibble(**data, &val);
- if (!res) {
- return false;
- }
- *addr <<= 4;
- *addr |= val;
- ++*data;
- }
-
- return true;
-}
-
-bool
-ServiceabilityAgentDbxModule::scanUnsignedInt(char** data, unsigned int* num) {
- *num = 0;
-
- // Skip whitespace
- while ((**data != 0) && (isspace(**data))) {
- ++*data;
- }
-
- if (**data == 0) {
- return false;
- }
-
- while ((**data != 0) && (!isspace(**data))) {
- char cur = **data;
- if ((cur < '0') || (cur > '9')) {
- return false;
- }
- *num *= 10;
- *num += cur - '0';
- ++*data;
- }
-
- return true;
-}
-
-char*
-ServiceabilityAgentDbxModule::scanSymbol(char** data) {
- // Skip whitespace
- while ((**data != 0) && (isspace(**data))) {
- ++*data;
- }
-
- if (**data == 0) {
- return NULL;
- }
-
- // First count length
- int len = 1; // Null terminator
- char* tmpData = *data;
- while ((*tmpData != 0) && (!isspace(*tmpData))) {
- ++tmpData;
- ++len;
- }
- char* buf = new char[len];
- strncpy(buf, *data, len - 1);
- buf[len - 1] = 0;
- *data += len - 1;
- return buf;
-}
-
-bool
-ServiceabilityAgentDbxModule::charToNibble(char ascii, int* value) {
- if (ascii >= '0' && ascii <= '9') {
- *value = ascii - '0';
- return true;
- } else if (ascii >= 'A' && ascii <= 'F') {
- *value = 10 + ascii - 'A';
- return true;
- } else if (ascii >= 'a' && ascii <= 'f') {
- *value = 10 + ascii - 'a';
- return true;
- }
-
- return false;
-}
-
-
-char*
-ServiceabilityAgentDbxModule::readCStringFromProcess(psaddr_t addr) {
- char c;
- int num = 0;
- ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
-
- // Search for null terminator
- do {
- if (ps_pread(cur_proc, addr + num, &c, 1) != PS_OK) {
- return NULL;
- }
- ++num;
- } while (c != 0);
-
- // Allocate string
- char* res = new char[num];
- if (ps_pread(cur_proc, addr, res, num) != PS_OK) {
- delete[] res;
- return NULL;
- }
- return res;
-}
-
-
-//--------------------------------------------------------------------------------
-// Class Timer
-//
-
-Timer::Timer() {
- reset();
-}
-
-Timer::~Timer() {
-}
-
-void
-Timer::start() {
- gettimeofday(&startTime, NULL);
-}
-
-void
-Timer::stop() {
- struct timeval endTime;
- gettimeofday(&endTime, NULL);
- totalMicroseconds += timevalDiff(&startTime, &endTime);
- ++counter;
-}
-
-long
-Timer::total() {
- return (totalMicroseconds / 1000);
-}
-
-long
-Timer::average() {
- return (long) ((double) total() / (double) counter);
-}
-
-void
-Timer::reset() {
- totalMicroseconds = 0;
- counter = 0;
-}
-
-long long
-Timer::timevalDiff(struct timeval* start, struct timeval* end) {
- long long secs = end->tv_sec - start->tv_sec;
- secs *= 1000000;
- long long usecs = end->tv_usec - start->tv_usec;
- return (secs + usecs);
-}
--- a/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "shell_imp.h"
-#include "IOBuf.hpp"
-#include <sys/time.h>
-#include <thread_db.h>
-
-typedef td_err_e td_init_fn_t();
-typedef td_err_e td_ta_new_fn_t(struct ps_prochandle *, td_thragent_t **);
-typedef td_err_e td_ta_delete_fn_t(td_thragent_t *);
-typedef td_err_e td_ta_map_id2thr_fn_t(const td_thragent_t *, thread_t, td_thrhandle_t *);
-typedef td_err_e td_thr_getgregs_fn_t(const td_thrhandle_t *, prgregset_t);
-
-class ServiceabilityAgentDbxModule {
-public:
- ServiceabilityAgentDbxModule(int major, int minor,
- shell_imp_interp_t interp, int argc, char *argv[]);
- ~ServiceabilityAgentDbxModule();
-
- bool install();
- bool uninstall();
-
- /* This is invoked through the dbx command interpreter. It listens
- on a socket for commands and does not return until it receives an
- "exit" command. At that point control is returned to dbx's main
- loop, at which point if the user sends an exit command to dbx's
- shell the dbx process will exit. Returns true if completed
- successfully, false if an error occurred while running (for
- example, unable to bind listening socket). */
- bool run();
-
-private:
-
- // This must be shared between the Java and C layers
- static const int PORT = 21928;
-
- // Command handlers
- bool handleAddressSize(char* data);
- bool handlePeekFailFast(char* data);
- bool handlePeek(char* data);
- bool handlePoke(char* data);
- bool handleMapped(char* data);
- bool handleLookup(char* data);
- bool handleThrGRegs(char* data);
-
- // Input routines
-
- // May mutate addr argument even if result is false
- bool scanAddress(char** data, psaddr_t* addr);
- // May mutate num argument even if result is false
- bool scanUnsignedInt(char** data, unsigned int* num);
- // Returns NULL if error occurred while scanning. Otherwise, returns
- // newly-allocated character array which must be freed with delete[].
- char* scanSymbol(char** data);
- // Helper routine: converts ASCII to 4-bit integer. Returns true if
- // character is in range, false otherwise.
- bool charToNibble(char ascii, int* value);
-
- // Output routines
-
- // Writes an int with no leading or trailing spaces
- bool writeInt(int val, int fd);
- // Writes an address in hex format with no leading or trailing
- // spaces
- bool writeAddress(psaddr_t addr, int fd);
- // Writes a register in hex format with no leading or trailing
- // spaces (addresses and registers might be of different size)
- bool writeRegister(prgreg_t reg, int fd);
- // Writes a space to given file descriptor
- bool writeSpace(int fd);
- // Writes carriage return to given file descriptor
- bool writeCR(int fd);
- // Writes a bool as [0|1]
- bool writeBoolAsInt(bool val, int fd);
- // Helper routine: converts low 4 bits to ASCII [0..9][A..F]
- char nibbleToChar(unsigned char nibble);
-
- // Base routine called by most of the above
- bool writeString(const char* str, int fd);
-
- // Writes a binary character
- bool writeBinChar(char val, int fd);
- // Writes a binary unsigned int in network (big-endian) byte order
- bool writeBinUnsignedInt(unsigned int val, int fd);
- // Writes a binary buffer
- bool writeBinBuf(char* buf, int size, int fd);
-
- // Routine to flush the socket
- bool flush(int client_socket);
-
- void cleanup(int client_socket);
-
- // The shell interpreter on which we can invoke commands (?)
- shell_imp_interp_t _interp;
-
- // The "command line" arguments passed to us by dbx (?)
- int _argc;
- char **_argv;
-
- // The installed command in the dbx shell
- shell_imp_command_t _command;
-
- // Access to libthread_db (dlsym'ed to be able to pick up the
- // version loaded by dbx)
- td_init_fn_t* td_init_fn;
- td_ta_new_fn_t* td_ta_new_fn;
- td_ta_delete_fn_t* td_ta_delete_fn;
- td_ta_map_id2thr_fn_t* td_ta_map_id2thr_fn;
- td_thr_getgregs_fn_t* td_thr_getgregs_fn;
-
- // Our "thread agent" -- access to libthread_db
- td_thragent_t* _tdb_agent;
-
- // Path to libthread.so in target process; free with delete[]
- char* libThreadName;
-
- // Handle to dlopen'ed libthread_db.so
- void* libThreadDB;
-
- // Helper callback for finding libthread_db.so
- friend int findLibThreadCB(const rd_loadobj_t* lo, void* data);
-
- // Support for reading C strings out of the target process (so we
- // can find the correct libthread_db). Returns newly-allocated char*
- // which must be freed with delete[], or null if the read failed.
- char* readCStringFromProcess(psaddr_t addr);
-
- IOBuf myComm;
-
- // Output buffer support (used by writeString, writeChar, flush)
- char* output_buffer;
- int output_buffer_size;
- int output_buffer_pos;
-
- // "Fail fast" flag
- bool peek_fail_fast;
-
- // Commands
- static const char* CMD_ADDRESS_SIZE;
- static const char* CMD_PEEK_FAIL_FAST;
- static const char* CMD_PEEK;
- static const char* CMD_POKE;
- static const char* CMD_MAPPED;
- static const char* CMD_LOOKUP;
- static const char* CMD_THR_GREGS;
- static const char* CMD_EXIT;
-};
-
-// For profiling. Times reported are in milliseconds.
-class Timer {
-public:
- Timer();
- ~Timer();
-
- void start();
- void stop();
- long total();
- long average();
- void reset();
-
-private:
- struct timeval startTime;
- long long totalMicroseconds; // stored internally in microseconds
- int counter;
- long long timevalDiff(struct timeval* startTime, struct timeval* endTime);
-};
--- a/hotspot/agent/src/os/win32/BasicList.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _BASIC_LIST_
-#define _BASIC_LIST_
-
-#include <vector>
-
-template<class T>
-class BasicList {
-protected:
- typedef std::vector<T> InternalListType;
- InternalListType internalList;
-
-public:
- BasicList() {
- }
- virtual ~BasicList() {
- }
-
- void add(T arg) {
- internalList.push_back(arg);
- }
-
- bool remove(T arg) {
- for (InternalListType::iterator iter = internalList.begin();
- iter != internalList.end(); iter++) {
- if (*iter == arg) {
- internalList.erase(iter);
- return true;
- }
- }
- return false;
- }
-
- int size() {
- return internalList.size();
- }
-
- T get(int index) {
- return internalList[index];
- }
-};
-
-#endif // #defined _BASIC_LIST_
--- a/hotspot/agent/src/os/win32/Buffer.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "Buffer.hpp"
-
-#include <string.h>
-
-Buffer::Buffer(int bufSize) {
- buf = new char[bufSize];
- sz = bufSize;
- fill = 0;
- drain = 0;
-}
-
-Buffer::~Buffer() {
- delete[] buf;
-}
-
-char*
-Buffer::fillPos() {
- return buf + fill;
-}
-
-int
-Buffer::remaining() {
- return sz - fill;
-}
-
-int
-Buffer::size() {
- return sz;
-}
-
-bool
-Buffer::incrFillPos(int amt) {
- if (fill + amt >= sz) {
- return false;
- }
- fill += amt;
- return true;
-}
-
-int
-Buffer::readByte() {
- if (drain < fill) {
- return buf[drain++] & 0xFF;
- } else {
- return -1;
- }
-}
-
-int
-Buffer::readBytes(char* data, int len) {
- int numRead = 0;
- while (numRead < len) {
- int c = readByte();
- if (c < 0) break;
- data[numRead++] = (char) c;
- }
- return numRead;
-}
-
-char*
-Buffer::drainPos() {
- return buf + drain;
-}
-
-int
-Buffer::drainRemaining() {
- return fill - drain;
-}
-
-bool
-Buffer::incrDrainPos(int amt) {
- if (drainRemaining() < amt) {
- return false;
- }
- drain += amt;
- return true;
-}
-
-void
-Buffer::compact() {
- // Copy down data
- memmove(buf, buf + drain, fill - drain);
- // Adjust positions
- fill -= drain;
- drain = 0;
-}
--- a/hotspot/agent/src/os/win32/Buffer.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _BUFFER_
-#define _BUFFER_
-
-// A Buffer is the backing store for the IOBuf abstraction and
-// supports producer-consumer filling and draining.
-
-class Buffer {
-public:
- Buffer(int bufSize);
- ~Buffer();
-
- char* fillPos(); // Position of the place where buffer should be filled
- int remaining(); // Number of bytes that can be placed starting at fillPos
- int size(); // Size of the buffer
- // Move up fill position by amount (decreases remaining()); returns
- // false if not enough space
- bool incrFillPos(int amt);
-
- // Read single byte (0..255); returns -1 if no data available.
- int readByte();
- // Read multiple bytes, non-blocking (this buffer does not define a
- // fill mechanism), into provided buffer. Returns number of bytes read.
- int readBytes(char* buf, int len);
-
- // Access to drain position. Be very careful using this.
- char* drainPos();
- int drainRemaining();
- bool incrDrainPos(int amt);
-
- // Compact buffer, removing already-consumed input. This must be
- // called periodically to yield the illusion of an infinite buffer.
- void compact();
-
-private:
- Buffer(const Buffer&);
- Buffer& operator=(const Buffer&);
-
- char* buf;
- int sz;
- int fill;
- int drain;
-};
-
-#endif // #defined _BUFFER_
--- a/hotspot/agent/src/os/win32/Dispatcher.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "dispatcher.hpp"
-
-const char* CMD_ASCII = "ascii";
-const char* CMD_UNICODE = "unicode";
-const char* CMD_PROCLIST = "proclist";
-const char* CMD_ATTACH = "attach";
-const char* CMD_DETACH = "detach";
-const char* CMD_LIBINFO = "libinfo";
-const char* CMD_PEEK = "peek";
-const char* CMD_POKE = "poke";
-const char* CMD_THREADLIST = "threadlist";
-const char* CMD_DUPHANDLE = "duphandle";
-const char* CMD_CLOSEHANDLE = "closehandle";
-const char* CMD_GETCONTEXT = "getcontext";
-const char* CMD_SETCONTEXT = "setcontext";
-const char* CMD_SELECTORENTRY = "selectorentry";
-const char* CMD_SUSPEND = "suspend";
-const char* CMD_RESUME = "resume";
-const char* CMD_POLLEVENT = "pollevent";
-const char* CMD_CONTINUEEVENT = "continueevent";
-const char* CMD_EXIT = "exit";
-
-// Uncomment the #define below to get messages on stderr
-// #define DEBUGGING
-
-void
-Dispatcher::dispatch(char* cmd, Handler* handler) {
- if (!strncmp(cmd, CMD_ASCII, strlen(CMD_ASCII))) {
- handler->ascii(cmd + strlen(CMD_ASCII));
-
- } else if (!strncmp(cmd, CMD_UNICODE, strlen(CMD_UNICODE))) {
- handler->unicode(cmd + strlen(CMD_UNICODE));
-
- } else if (!strncmp(cmd, CMD_PROCLIST, strlen(CMD_PROCLIST))) {
- handler->procList(cmd + strlen(CMD_PROCLIST));
-
- } else if (!strncmp(cmd, CMD_ATTACH, strlen(CMD_ATTACH))) {
- handler->attach(cmd + strlen(CMD_ATTACH));
-
- } else if (!strncmp(cmd, CMD_DETACH, strlen(CMD_DETACH))) {
- handler->detach(cmd + strlen(CMD_DETACH));
-
- } else if (!strncmp(cmd, CMD_LIBINFO, strlen(CMD_LIBINFO))) {
- handler->libInfo(cmd + strlen(CMD_LIBINFO));
-
- } else if (!strncmp(cmd, CMD_PEEK, strlen(CMD_PEEK))) {
- handler->peek(cmd + strlen(CMD_PEEK));
-
- } else if (!strncmp(cmd, CMD_POKE, strlen(CMD_POKE))) {
- handler->poke(cmd + strlen(CMD_POKE));
-
- } else if (!strncmp(cmd, CMD_THREADLIST, strlen(CMD_THREADLIST))) {
- handler->threadList(cmd + strlen(CMD_THREADLIST));
-
- } else if (!strncmp(cmd, CMD_DUPHANDLE, strlen(CMD_DUPHANDLE))) {
- handler->dupHandle(cmd + strlen(CMD_DUPHANDLE));
-
- } else if (!strncmp(cmd, CMD_CLOSEHANDLE, strlen(CMD_CLOSEHANDLE))) {
- handler->closeHandle(cmd + strlen(CMD_CLOSEHANDLE));
-
- } else if (!strncmp(cmd, CMD_GETCONTEXT, strlen(CMD_GETCONTEXT))) {
- handler->getContext(cmd + strlen(CMD_GETCONTEXT));
-
- } else if (!strncmp(cmd, CMD_SETCONTEXT, strlen(CMD_SETCONTEXT))) {
- handler->setContext(cmd + strlen(CMD_SETCONTEXT));
-
- } else if (!strncmp(cmd, CMD_SELECTORENTRY, strlen(CMD_SELECTORENTRY))) {
- handler->selectorEntry(cmd + strlen(CMD_SELECTORENTRY));
-
- } else if (!strncmp(cmd, CMD_SUSPEND, strlen(CMD_SUSPEND))) {
- handler->suspend(cmd + strlen(CMD_SUSPEND));
-
- } else if (!strncmp(cmd, CMD_RESUME, strlen(CMD_RESUME))) {
- handler->resume(cmd + strlen(CMD_RESUME));
-
- } else if (!strncmp(cmd, CMD_POLLEVENT, strlen(CMD_POLLEVENT))) {
- handler->pollEvent(cmd + strlen(CMD_POLLEVENT));
-
- } else if (!strncmp(cmd, CMD_CONTINUEEVENT, strlen(CMD_CONTINUEEVENT))) {
- handler->continueEvent(cmd + strlen(CMD_CONTINUEEVENT));
-
- } else if (!strcmp(cmd, CMD_EXIT)) {
- handler->exit(cmd + strlen(CMD_EXIT));
- }
-
-#ifdef DEBUGGING
- else fprintf(stderr, "Ignoring illegal command \"%s\"\n", cmd);
-#endif
-}
--- a/hotspot/agent/src/os/win32/Dispatcher.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _DISPATCHER_
-#define _DISPATCHER_
-
-#include "Handler.hpp"
-
-/** This class understands the commands supported by the system and
- calls the appropriate handler routines. */
-
-class Dispatcher {
-public:
- static void dispatch(char* cmd, Handler* handler);
-};
-
-#endif // #defined _DISPATCHER_
--- a/hotspot/agent/src/os/win32/Handler.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _HANDLER_
-#define _HANDLER_
-
-/** An abstract base class encapsulating the handlers for all commands
- understood by the system. */
-class Handler {
-public:
- virtual void ascii(char* arg) = 0;
- virtual void unicode(char* arg) = 0;
- virtual void procList(char* arg) = 0;
- virtual void attach(char* arg) = 0;
- virtual void detach(char* arg) = 0;
- virtual void libInfo(char* arg) = 0;
- virtual void peek(char* arg) = 0;
- virtual void poke(char* arg) = 0;
- virtual void threadList(char* arg) = 0;
- virtual void dupHandle(char* arg) = 0;
- virtual void closeHandle(char* arg) = 0;
- virtual void getContext(char* arg) = 0;
- virtual void setContext(char* arg) = 0;
- virtual void selectorEntry(char* arg) = 0;
- virtual void suspend(char* arg) = 0;
- virtual void resume(char* arg) = 0;
- virtual void pollEvent(char* arg) = 0;
- virtual void continueEvent(char* arg) = 0;
- virtual void exit(char* arg) = 0;
-};
-
-#endif // #defined _HANDLER_
--- a/hotspot/agent/src/os/win32/IOBuf.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,490 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-
-// This file is currently used for os/solaris/agent too. At some point in time
-// the source will be reorganized to avoid these ifdefs.
-
-#ifdef __sun
- #include <string.h>
- #include <inttypes.h>
- #include <sys/byteorder.h>
-#endif
-
-#include "IOBuf.hpp"
-
-// Formats for printing pointers
-#ifdef _LP64
-# define INTPTR_FORMAT "0x%016lx"
-#else /* ! _LP64 */
-# define INTPTR_FORMAT "0x%08lx"
-#endif /* _LP64 */
-
-// Uncomment the #define below to get messages on stderr
-// #define DEBUGGING
-
-IOBuf::IOBuf(int inLen, int outLen) {
- inBuf = new Buffer(inLen);
- outBuf = new Buffer(outLen);
- fd = INVALID_SOCKET;
- outHandle = NULL;
- usingSocket = true;
- reset();
-}
-
-IOBuf::~IOBuf() {
- delete inBuf;
- delete outBuf;
-}
-
-void
-IOBuf::setSocket(SOCKET sock) {
- fd = sock;
- usingSocket = true;
-}
-
-// Reading/writing files is only needed and used on windows.
-#ifdef WIN32
-void
-IOBuf::setOutputFileHandle(HANDLE handle) {
- outHandle = handle;
- usingSocket = false;
-}
-#endif
-
-void
-IOBuf::reset() {
- gotDataLastTime = false;
- state = TEXT_STATE;
- binPos = 0;
- binLength = 0;
-}
-
-IOBuf::ReadLineResult
-IOBuf::tryReadLine() {
- return doReadLine(false);
-}
-
-char*
-IOBuf::readLine() {
- ReadLineResult rr = doReadLine(true);
- if (rr != RL_GOT_DATA) {
- return NULL;
- }
- return getLine();
-}
-
-IOBuf::ReadLineResult
-IOBuf::doReadLine(bool shouldWait) {
-
- if (!usingSocket) {
- return IOBuf::RL_ERROR;
- }
-
- if (gotDataLastTime) {
- curLine.clear();
- }
-
- int c;
- do {
- c = readChar(shouldWait);
- if (c >= 0) {
- Action act = processChar((char) c);
- if (act == GOT_LINE) {
- curLine.push_back('\0');
- gotDataLastTime = true;
- return IOBuf::RL_GOT_DATA;
- } else if (act == SKIP_EOL_CHAR) {
- // Do nothing
- } else {
- curLine.push_back((char) c);
- }
- }
- } while (shouldWait || c >= 0);
-
- gotDataLastTime = false;
- return IOBuf::RL_NO_DATA;
-}
-
-bool
-IOBuf::flushImpl(bool moreDataToCome) {
- int numWritten = 0;
-
-#ifdef WIN32
- // When running on Windows and using IOBufs for inter-process
- // communication, we need to write metadata into the stream
- // indicating how many bytes are coming down. Five bytes are written
- // per flush() call, four containing the integer number of bytes
- // coming (not including the five-byte header) and one (a 0 or 1)
- // indicating whether there is more data coming.
- if (!usingSocket) {
- int numToWrite = outBuf->drainRemaining();
- char moreToCome = (moreDataToCome ? 1 : 0);
- DWORD numBytesWritten;
- if (!WriteFile(outHandle, &numToWrite, sizeof(int), &numBytesWritten, NULL)) {
- return false;
- }
- if (numBytesWritten != sizeof(int)) {
- return false;
- }
- if (!WriteFile(outHandle, &moreToCome, 1, &numBytesWritten, NULL)) {
- return false;
- }
- if (numBytesWritten != 1) {
- return false;
- }
- }
-#endif
-
- while (outBuf->drainRemaining() != 0) {
-#ifdef DEBUGGING
- fprintf(stderr, "Flushing %d bytes\n", outBuf->drainRemaining());
-#endif
- if (usingSocket) {
- numWritten = send(fd, outBuf->drainPos(), outBuf->drainRemaining(), 0);
- } else {
-#ifdef WIN32
- DWORD numBytesWritten;
- if (!WriteFile(outHandle, outBuf->drainPos(), outBuf->drainRemaining(), &numBytesWritten, NULL)) {
- numWritten = -1;
- } else {
- numWritten = numBytesWritten;
- }
-#endif
- }
- if (numWritten != -1) {
-#ifdef DEBUGGING
- fprintf(stderr, "Flushed %d bytes\n", numWritten);
-#endif
- outBuf->incrDrainPos(numWritten);
- } else {
- return false;
- }
- }
-
- outBuf->compact();
-
- return true;
-}
-
-int
-IOBuf::readChar(bool block) {
- do {
- int c = inBuf->readByte();
- if (c >= 0) {
- return c;
- }
- // See whether we need to compact the input buffer
- if (inBuf->remaining() < inBuf->size() / 2) {
- inBuf->compact();
- }
- // See whether socket is ready
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- if (block || select(1 + fd, &fds, NULL, NULL, &timeout) > 0) {
- if (block || FD_ISSET(fd, &fds)) {
-#ifdef DEBUGGING
- int b = (block ? 1 : 0);
- fprintf(stderr, "calling recv: block = %d\n", b);
-#endif
- // Read data from socket
- int numRead = recv(fd, inBuf->fillPos(), inBuf->remaining(), 0);
- if (numRead < 0) {
-#ifdef DEBUGGING
- fprintf(stderr, "recv failed\n");
-#endif
- return -1;
- }
- inBuf->incrFillPos(numRead);
- }
- }
- } while (block);
-
- return inBuf->readByte();
-}
-
-char*
-IOBuf::getLine() {
-#ifdef DEBUGGING
- fprintf(stderr, "Returning (first 10 chars) \"%.10s\"\n", curLine.begin());
-#endif
- return curLine.begin();
-}
-
-bool
-IOBuf::flush() {
- return flushImpl(false);
-}
-
-bool
-IOBuf::writeString(const char* str) {
- int len = strlen(str);
-
- if (len > outBuf->size()) {
- return false;
- }
-
- if (len > outBuf->remaining()) {
- if (!flushImpl(true)) {
- return false;
- }
- }
-
- // NOTE we do not copy the null terminator of the string.
-
- strncpy(outBuf->fillPos(), str, len);
- outBuf->incrFillPos(len);
- return true;
-}
-
-bool
-IOBuf::writeInt(int val) {
- char buf[128];
- sprintf(buf, "%d", val);
- return writeString(buf);
-}
-
-bool
-IOBuf::writeUnsignedInt(unsigned int val) {
- char buf[128];
- sprintf(buf, "%u", val);
- return writeString(buf);
-}
-
-bool
-IOBuf::writeBoolAsInt(bool val) {
- if (val) {
- return writeString("1");
- } else {
- return writeString("0");
- }
-}
-
-bool
-IOBuf::writeAddress(void* val) {
- char buf[128];
- sprintf(buf, INTPTR_FORMAT, val);
- return writeString(buf);
-}
-
-bool
-IOBuf::writeSpace() {
- return writeString(" ");
-}
-
-bool
-IOBuf::writeEOL() {
- return writeString("\n\r");
-}
-
-bool
-IOBuf::writeBinChar(char c) {
- return writeBinBuf((char*) &c, sizeof(c));
-}
-
-bool
-IOBuf::writeBinUnsignedShort(unsigned short i) {
- i = htons(i);
- return writeBinBuf((char*) &i, sizeof(i));
-}
-
-bool
-IOBuf::writeBinUnsignedInt(unsigned int i) {
- i = htonl(i);
- return writeBinBuf((char*) &i, sizeof(i));
-}
-
-bool
-IOBuf::writeBinBuf(char* buf, int size) {
- while (size > 0) {
- int spaceRemaining = outBuf->remaining();
- if (spaceRemaining == 0) {
- if (!flushImpl(true)) {
- return false;
- }
- spaceRemaining = outBuf->remaining();
- }
- int toCopy = (size > spaceRemaining) ? spaceRemaining : size;
- memcpy(outBuf->fillPos(), buf, toCopy);
- outBuf->incrFillPos(toCopy);
- buf += toCopy;
- size -= toCopy;
- if (size > 0) {
- if (!flushImpl(true)) {
- return false;
- }
- }
- }
- return true;
-}
-
-#ifdef WIN32
-IOBuf::FillState
-IOBuf::fillFromFileHandle(HANDLE fh, DWORD* numBytesRead) {
- int totalToRead;
- char moreToCome;
-
- outBuf->compact();
-
- DWORD numRead;
- if (!ReadFile(fh, &totalToRead, sizeof(int), &numRead, NULL)) {
- return FAILED;
- }
- if (numRead != sizeof(int)) {
- return FAILED;
- }
- if (!ReadFile(fh, &moreToCome, 1, &numRead, NULL)) {
- return FAILED;
- }
- if (numRead != 1) {
- return FAILED;
- }
- if (outBuf->remaining() < totalToRead) {
- return FAILED;
- }
-
- int tmp = totalToRead;
-
- while (totalToRead > 0) {
- if (!ReadFile(fh, outBuf->fillPos(), totalToRead, &numRead, NULL)) {
- return FAILED;
- }
- outBuf->incrFillPos((int) numRead);
- totalToRead -= numRead;
- }
-
- *numBytesRead = tmp;
- return ((moreToCome == 0) ? DONE : MORE_DATA_PENDING);
-}
-#endif
-
-bool
-IOBuf::isBinEscapeChar(char c) {
- return (c == '|');
-}
-
-IOBuf::Action
-IOBuf::processChar(char c) {
- Action action = NO_ACTION;
- switch (state) {
- case TEXT_STATE: {
- // Looking for text char, bin escape char, or EOL
- if (isBinEscapeChar(c)) {
-#ifdef DEBUGGING
- fprintf(stderr, "[a: '%c'] ", inBuf[0]);
-#endif
- binPos = 0;
-#ifdef DEBUGGING
- fprintf(stderr, "[b: '%c'] ", inBuf[0]);
-#endif
- binLength = 0;
-#ifdef DEBUGGING
- fprintf(stderr, "[c: '%c'] ", inBuf[0]);
-#endif
- state = BIN_STATE;
-#ifdef DEBUGGING
- fprintf(stderr, "[d: '%c'] ", inBuf[0]);
-#endif
-#ifdef DEBUGGING
- fprintf(stderr, "\nSwitching to BIN_STATE\n");
-#endif
- } else if (isEOL(c)) {
- state = EOL_STATE;
- action = GOT_LINE;
-#ifdef DEBUGGING
- fprintf(stderr, "\nSwitching to EOL_STATE (GOT_LINE)\n");
-#endif
- }
-#ifdef DEBUGGING
- else {
- fprintf(stderr, "'%c' ", c);
- fflush(stderr);
- }
-#endif
- break;
- }
-
- case BIN_STATE: {
- // Seeking to finish read of input
- if (binPos < 4) {
- int cur = c & 0xFF;
- binLength <<= 8;
- binLength |= cur;
- ++binPos;
- } else {
-#ifdef DEBUGGING
- fprintf(stderr, "Reading binary byte %d of %d\n",
- binPos - 4, binLength);
-#endif
- ++binPos;
- if (binPos == 4 + binLength) {
- state = TEXT_STATE;
-#ifdef DEBUGGING
- fprintf(stderr, "Switching to TEXT_STATE\n");
-#endif
- }
- }
- break;
- }
-
- case EOL_STATE: {
- // More EOL characters just cause us to re-enter this state
- if (isEOL(c)) {
- action = SKIP_EOL_CHAR;
- } else if (isBinEscapeChar(c)) {
- binPos = 0;
- binLength = 0;
- state = BIN_STATE;
- } else {
- state = TEXT_STATE;
-#ifdef DEBUGGING
- fprintf(stderr, "'%c' ", c);
- fflush(stderr);
-#endif
- }
- break;
- }
-
- } // switch
-
- return action;
-}
-
-
-bool
-IOBuf::isEOL(char c) {
-#ifdef WIN32
- return ((c == '\n') || (c == '\r'));
-#elif defined(__sun)
- return c == '\n';
-#else
- #error Please port isEOL() to your platform
- return false;
-#endif
-}
--- a/hotspot/agent/src/os/win32/IOBuf.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _IO_BUF_
-#define _IO_BUF_
-
-// This file is currently used for os/solaris/agent/ too. At some point in time
-// the source will be reorganized to avoid these ifdefs.
-// Note that this class can read/write from a file as well as a socket. This
-// file capability is only implemented on win32.
-
-#ifdef WIN32
- #include <winsock2.h>
-#else
- #include <sys/types.h>
- #include <sys/socket.h>
- // These are from win32 winsock2.h
- typedef unsigned int SOCKET;
- typedef void * HANDLE;
- typedef unsigned long DWORD;
- #define INVALID_SOCKET (SOCKET)(~0)
-#endif
-
-#include <vector>
-#include "Buffer.hpp"
-
-/** Manages an input/output buffer pair for a socket or file handle. */
-class IOBuf {
-public:
- IOBuf(int inBufLen, int outBufLen);
- ~IOBuf();
-
- enum ReadLineResult {
- RL_GOT_DATA,
- RL_NO_DATA,
- RL_ERROR
- };
-
- /** Change the socket with which this buffer is associated */
- void setSocket(SOCKET sock);
-
- // Reading/writing files is only supported on windows.
-#ifdef WIN32
- /** Change the output file handle with which this buffer is
- associated. Currently IOBufs can not be used to read from a file
- handle. */
- void setOutputFileHandle(HANDLE handle);
-#endif
-
- /** Reset the input and output buffers, without flushing the output
- data to the socket */
- void reset();
-
- /** Try to read a line of data from the given socket without
- blocking. If was able to read a complete line of data, returns a
- character pointer to the beginning of the (null-terminated)
- string. If not, returns NULL, but maintains enough state that
- subsequent calls to tryReadLine() will not ignore the data
- already read. NOTE: this skips end-of-line characters (typically
- CR/LF) as defined by "isEOL()". When switching back and forth
- between binary and text modes, to be sure no data is lost, pad
- the beginning and end of the binary transmission with bytes
- which can not be confused with these characters. */
- ReadLineResult tryReadLine();
-
- /** Read a line of data from the given socket, blocking until a
- line, including EOL, appears. Return the line, or NULL if
- something goes wrong. */
- char *readLine();
-
- /** Get the pointer to the beginning of the (null-terminated) line.
- This should only be called if tryReadLine() has returned
- RL_GOT_DATA. This sets the "parsing cursor" to the beginning of
- the line. */
- char* getLine();
-
- // NOTE: any further data-acquisition routines must ALWAYS call
- // fixupData() at the beginning!
-
- //----------------------------------------------------------------------
- // Output routines
- //
-
- /** Flush the output buffer to the socket. Returns true if
- succeeded, false if write error occurred. */
- bool flush();
-
- /** Write the given string to the output buffer. May flush if output
- buffer becomes too full to store the data. Not guaranteed to
- work if string is longer than the size of the output buffer.
- Does not include the null terminator of the string. Returns true
- if succeeded, false if write error occurred. */
- bool writeString(const char* str);
-
- /** Write the given int to the output buffer. May flush if output
- buffer becomes too full to store the data. Returns true if
- succeeded, false if write error occurred. */
- bool writeInt(int val);
-
- /** Write the given unsigned int to the output buffer. May flush if
- output buffer becomes too full to store the data. Returns true
- if succeeded, false if write error occurred. */
- bool writeUnsignedInt(unsigned int val);
-
- /** Write the given boolean to the output buffer. May flush if
- output buffer becomes too full to store the data. Returns true
- if succeeded, false if write error occurred. */
- bool writeBoolAsInt(bool val);
-
- /** Write the given address to the output buffer. May flush if
- output buffer becomes too full to store the data. Returns true
- if succeeded, false if write error occurred. */
- bool writeAddress(void* val);
-
- /** Writes a space to the output buffer. May flush if output buffer
- becomes too full to store the data. Returns true if succeeded,
- false if write error occurred. */
- bool writeSpace();
-
- /** Writes an end-of-line sequence to the output buffer. May flush
- if output buffer becomes too full to store the data. Returns
- true if succeeded, false if write error occurred. */
- bool writeEOL();
-
- /** Writes a binary character to the output buffer. */
- bool writeBinChar(char c);
-
- /** Writes a binary unsigned short in network (big-endian) byte
- order to the output buffer. */
- bool writeBinUnsignedShort(unsigned short i);
-
- /** Writes a binary unsigned int in network (big-endian) byte order
- to the output buffer. */
- bool writeBinUnsignedInt(unsigned int i);
-
- /** Writes a binary buffer to the output buffer. */
- bool writeBinBuf(char* buf, int size);
-
-#ifdef WIN32
- enum FillState {
- DONE = 1,
- MORE_DATA_PENDING = 2,
- FAILED = 3
- };
-
- /** Very specialized routine; fill the output buffer from the given
- file handle. Caller is responsible for ensuring that there is
- data to be read on the file handle. */
- FillState fillFromFileHandle(HANDLE fh, DWORD* numRead);
-#endif
-
- /** Binary utility routine (for poke) */
- static bool isBinEscapeChar(char c);
-
-private:
- IOBuf(const IOBuf&);
- IOBuf& operator=(const IOBuf&);
-
- // Returns -1 if non-blocking and no data available
- int readChar(bool block);
- // Line-oriented reading
- std::vector<char> curLine;
- bool gotDataLastTime;
-
- ReadLineResult doReadLine(bool);
-
- bool flushImpl(bool moreDataToCome);
-
- SOCKET fd;
- HANDLE outHandle;
- bool usingSocket;
-
- // Buffers
- Buffer* inBuf;
- Buffer* outBuf;
-
- // Simple finite-state machine to handle binary data
- enum State {
- TEXT_STATE,
- BIN_STATE,
- EOL_STATE
- };
- enum Action {
- NO_ACTION,
- GOT_LINE, // TEXT_STATE -> EOL_STATE transition
- SKIP_EOL_CHAR // EOL_STATE -> EOL_STATE transition
- };
-
- State state;
- Action processChar(char c);
-
- // Handling incoming binary buffers (poke command)
- int binPos; // Number of binary characters read so far;
- // total number to read is binLength + 4
- int binLength; // Number of binary characters in message;
- // not valid until binPos >= 4
-
- bool isEOL(char c);
-};
-
-#endif // #defined _IO_BUF_
--- a/hotspot/agent/src/os/win32/LockableList.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _LOCKABLE_LIST_
-#define _LOCKABLE_LIST_
-
-#include <windows.h>
-#include "BasicList.hpp"
-
-template<class T>
-class LockableList : public BasicList<T> {
-private:
- CRITICAL_SECTION crit;
-
-public:
- LockableList() {
- InitializeCriticalSection(&crit);
- }
-
- ~LockableList() {
- DeleteCriticalSection(&crit);
- }
-
- void lock() {
- EnterCriticalSection(&crit);
- }
-
- void unlock() {
- LeaveCriticalSection(&crit);
- }
-};
-
-#endif // #defined _LOCKABLE_LIST_
--- a/hotspot/agent/src/os/win32/Makefile Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-#
-# Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-SERVER=SwDbgSrv.exe
-SUBPROCESS=SwDbgSub.exe
-
-SERVER_SOURCES = \
- Buffer.cpp \
- Dispatcher.cpp \
- initWinsock.cpp \
- IOBuf.cpp \
- ioUtils.cpp \
- isNT4.cpp \
- nt4internals.cpp \
- procList.cpp \
- Reaper.cpp \
- SwDbgSrv.cpp \
- serverLists.cpp \
- toolHelp.cpp
-
-SUBPROCESS_SOURCES = \
- SwDbgSub.cpp \
- Buffer.cpp \
- IOBuf.cpp \
- isNT4.cpp \
- libInfo.cpp \
- Monitor.cpp \
- nt4internals.cpp \
- toolHelp.cpp
-
-SERVER_OBJS = $(SERVER_SOURCES:.cpp=.obj)
-SUBPROCESS_OBJS = $(SUBPROCESS_SOURCES:.cpp=.obj)
-
-CPP=cl.exe
-LINK32=link.exe
-
-# These do not need to be optimized (don't run a lot of code) and it
-# will be useful to have the assertion checks in place
-
-CFLAGS=/nologo /MD /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-
-LIBS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \
- ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib \
- winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib \
- odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386
-
-default: $(SERVER) $(SUBPROCESS)
-
-$(SERVER): $(SERVER_OBJS)
- $(LINK32) /out:$@ $(SERVER_OBJS) $(LIBS)
-
-$(SUBPROCESS): $(SUBPROCESS_OBJS)
- $(LINK32) /out:$@ $(SUBPROCESS_OBJS) $(LIBS)
-
-clean:
- rm -f *.obj *.idb *.pch *.pdb *.ncb *.opt *.plg *.exe *.ilk
-
-.cpp.obj:
- @ $(CPP) $(CFLAGS) /o $@ $<
--- a/hotspot/agent/src/os/win32/Message.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _MESSAGE_
-#define _MESSAGE_
-
-// These are the commands sent from the server to the child processes
-// over the child processes' stdin pipes. A subset of the commands
-// understood by the overall system, these require responses from the
-// child process. Having a data structure rather than sending text
-// simplifies parsing on the child side. The child replies by sending
-// back fully-formatted replies which are copied by the server process
-// to the clients' sockets.
-
-struct PeekArg {
- DWORD address;
- DWORD numBytes;
-};
-
-// NOTE: when sending a PokeArg to the child process, we handle the
-// buffer specially
-struct PokeArg {
- DWORD address;
- DWORD numBytes;
- void* data;
-};
-
-// Used for continueevent
-struct BoolArg {
- bool val;
-};
-
-// Used for duphandle, closehandle, and getcontext
-struct HandleArg {
- HANDLE handle;
-};
-
-// Used for setcontext
-const int NUM_REGS_IN_CONTEXT = 22;
-struct SetContextArg {
- HANDLE handle;
- DWORD Eax;
- DWORD Ebx;
- DWORD Ecx;
- DWORD Edx;
- DWORD Esi;
- DWORD Edi;
- DWORD Ebp;
- DWORD Esp;
- DWORD Eip;
- DWORD Ds;
- DWORD Es;
- DWORD Fs;
- DWORD Gs;
- DWORD Cs;
- DWORD Ss;
- DWORD EFlags;
- DWORD Dr0;
- DWORD Dr1;
- DWORD Dr2;
- DWORD Dr3;
- DWORD Dr6;
- DWORD Dr7;
-};
-
-// Used for selectorentry
-struct SelectorEntryArg {
- HANDLE handle;
- DWORD selector;
-};
-
-struct Message {
- typedef enum {
- ATTACH,
- DETACH,
- LIBINFO,
- PEEK,
- POKE,
- THREADLIST,
- DUPHANDLE,
- CLOSEHANDLE,
- GETCONTEXT,
- SETCONTEXT,
- SELECTORENTRY,
- SUSPEND,
- RESUME,
- POLLEVENT,
- CONTINUEEVENT
- } Type;
-
- Type type;
- union {
- PeekArg peekArg;
- PokeArg pokeArg;
- BoolArg boolArg;
- HandleArg handleArg;
- SetContextArg setContextArg;
- SelectorEntryArg selectorArg;
- };
-};
-
-#endif // #defined _MESSAGE_
--- a/hotspot/agent/src/os/win32/Monitor.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <stdio.h>
-#include <assert.h>
-#include "Monitor.hpp"
-
-Monitor::Monitor() {
- _lock_count = -1; // No threads have entered the critical section
- _owner = NULL;
- _lock_event = CreateEvent(NULL, false, false, NULL);
- _wait_event = CreateEvent(NULL, true, false, NULL);
- _counter = 0;
- _tickets = 0;
- _waiters = 0;
-}
-
-Monitor::~Monitor() {
- assert(_owner == NULL); // Otherwise, owned monitor being deleted
- assert(_lock_count == -1); // Otherwise, monitor being deleted with non -1 lock count
- CloseHandle(_lock_event);
- CloseHandle(_wait_event);
-}
-
-void
-Monitor::lock() {
- if (InterlockedIncrement(&_lock_count) == 0) {
- // Success, we now own the lock
- } else {
- DWORD dwRet = WaitForSingleObject((HANDLE)_lock_event, INFINITE);
- assert(dwRet == WAIT_OBJECT_0); // Unexpected return value from WaitForSingleObject
- }
- assert(owner() == NULL); // Otherwise, lock count and owner are inconsistent
- setOwner(GetCurrentThread());
-}
-
-void
-Monitor::unlock() {
- setOwner(NULL);
- if (InterlockedDecrement(&_lock_count) >= 0) {
- // Wake a waiting thread up
- DWORD dwRet = SetEvent(_lock_event);
- assert(dwRet != 0); // Unexpected return value from SetEvent
- }
-}
-
-bool
-Monitor::wait(long timeout) {
- assert(owner() != NULL);
- assert(owner() == GetCurrentThread());
-
- // 0 means forever. Convert to Windows specific code.
- DWORD timeout_value = (timeout == 0) ? INFINITE : timeout;
- DWORD which;
-
- long c = _counter;
- bool retry = false;
-
- _waiters++;
- // Loop until condition variable is signaled. The event object is
- // set whenever the condition variable is signaled, and tickets will
- // reflect the number of threads which have been notified. The counter
- // field is used to make sure we don't respond to notifications that
- // have occurred *before* we started waiting, and is incremented each
- // time the condition variable is signaled.
-
- while (true) {
-
- // Leave critical region
- unlock();
-
- // If this is a retry, let other low-priority threads have a chance
- // to run. Make sure that we sleep outside of the critical section.
- if (retry) {
- Sleep(1);
- } else {
- retry = true;
- }
-
- which = WaitForSingleObject(_wait_event, timeout_value);
- // Enter critical section
- lock();
-
- if (_tickets != 0 && _counter != c) break;
-
- if (which == WAIT_TIMEOUT) {
- --_waiters;
- return true;
- }
- }
- _waiters--;
-
- // If this was the last thread to be notified, then we need to reset
- // the event object.
- if (--_tickets == 0) {
- ResetEvent(_wait_event);
- }
-
- return false;
-}
-
-// Notify a single thread waiting on this monitor
-bool
-Monitor::notify() {
- assert(ownedBySelf()); // Otherwise, notify on unknown thread
-
- if (_waiters > _tickets) {
- if (!SetEvent(_wait_event)) {
- return false;
- }
- _tickets++;
- _counter++;
- }
-
- return true;
-}
-
-// Notify all threads waiting on this monitor
-bool
-Monitor::notifyAll() {
- assert(ownedBySelf()); // Otherwise, notifyAll on unknown thread
-
- if (_waiters > 0) {
- if (!SetEvent(_wait_event)) {
- return false;
- }
- _tickets = _waiters;
- _counter++;
- }
-
- return true;
-}
-
-HANDLE
-Monitor::owner() {
- return _owner;
-}
-
-void
-Monitor::setOwner(HANDLE owner) {
- if (owner != NULL) {
- assert(_owner == NULL); // Setting owner thread of already owned monitor
- assert(owner == GetCurrentThread()); // Else should not be doing this
- } else {
- HANDLE oldOwner = _owner;
- assert(oldOwner != NULL); // Removing the owner thread of an unowned mutex
- assert(oldOwner == GetCurrentThread());
- }
- _owner = owner;
-}
-
-bool
-Monitor::ownedBySelf() {
- return (_owner == GetCurrentThread());
-}
--- a/hotspot/agent/src/os/win32/Monitor.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _MONITOR_
-#define _MONITOR_
-
-#include <windows.h>
-
-class Monitor {
-public:
- Monitor();
- ~Monitor();
-
- void lock();
- void unlock();
- // Default time is forever (i.e, zero). Returns true if it times-out, otherwise
- // false.
- bool wait(long timeout = 0);
- bool notify();
- bool notifyAll();
-
-private:
- HANDLE owner();
- void setOwner(HANDLE owner);
- bool ownedBySelf();
-
- HANDLE _owner;
- long _lock_count;
- HANDLE _lock_event; // Auto-reset event for blocking in lock()
- HANDLE _wait_event; // Manual-reset event for notifications
- long _counter; // Current number of notifications
- long _waiters; // Number of threads waiting for notification
- long _tickets; // Number of waiters to be notified
-};
-
-
-#endif // #defined _MONITOR_
--- a/hotspot/agent/src/os/win32/README-commands.txt Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-This debug server uses a largely text-based protocol, except for
-certain bulk data transfer operations. All text is in single-byte
-US-ASCII except for the strings returned in "proclist".
-
-NOTE that the character '|' (vertical bar) is used as an escape
-character to switch the incoming data stream to the debug server into
-binary mode, so no text command may contain that character.
-
-Commands understood:
-
-ascii <EOL> ::=
-
- Changes to ASCII mode. This affects all outgoing strings. At
- startup the system is in unicode mode.
-
-unicode <EOL> ::=
-
- Changes to UNICODE mode. This affects all outgoing strings. This
- is the default mode upon startup.
-
-proclist <EOL> ::=
- <int num> [<unsigned int pid> <int charSize> <int numChars> [<binary char_t name>]...]... <EOL>
-
- Returns integer indicating number of processes to follow, followed
- by (pid, name) pairs. Names are given by (charSize, numChars,
- [char_t]...) tuples; charSize indicates the size of each character
- in bytes, numChars the number of characters in the string, and
- name the raw data for the string. Each individual character of the
- string, if multi-byte, is transmitted in network byte order.
- numChars and name are guaranteed to be separated by precisely one
- US-ASCII space. If process list is not available because of
- limitations of the underlying operating system, number of
- processes returned is 0.
-
-attach <int pid> <EOL> ::= <bool result> <EOL>
-
- Attempts to attach to the specified process. Returns 1 if
- successful, 0 if not. Will fail if already attached or if the
- process ID does not exist. Attaching to a process causes the
- process to be suspended.
-
-detach <EOL> ::= <bool result> <EOL>
-
- Detaches from the given process. Attaching and detaching multiple
- times during a debugging session is allowed. Detaching causes the
- process to resume execution.
-
-libinfo <EOL> ::=
- <int numLibs> [<int charSize> <int numChars> [<binary char_t name>]... <address baseAddr>]... <EOL>
-
- May only be called once attached and the target process must be
- suspended; otherwise, returns 0. Returns list of the full path
- names of all of the loaded modules (including the executable
- image) in the target process, as well as the base address at which
- each module was relocated. See proclist for format of strings, but
- NOTE that charSize is ALWAYS 1 for this particular routine,
- regardless of the setting of ASCII/UNICODE.
-
-peek <address addr> <unsigned int numBytes> <EOL> ::=
- B<binary char success>
- [<binary unsigned int len> <binary char isMapped> [<binary char data>]...]...
-
- NOTE that the binary portion of this message is prefixed by the
- uppercase US-ASCII letter 'B', allowing easier synchronization by
- clients. There is no data between the 'B' and the rest of the
- message.
-
- May only be called once attached. Reads the address space of the
- target process starting at the given address (see below for format
- specifications) and extending the given number of bytes. Whether
- the read succeeded is indicated by a single byte containing a 1 or
- 0 (success or failure). If successful, the return result is given
- in a sequence of ranges. _len_, the length of each range, is
- indicated by a 32-bit unsigned integer transmitted with big-endian
- byte ordering (i.e., most significant byte first). _isMapped_
- indicates whether the range is mapped or unmapped in the target
- process's address space, and will contain the value 1 or 0 for
- mapped or unmapped, respectively. If the range is mapped,
- _isMapped_ is followed by _data_, containing the raw binary data
- for the range. The sum of all ranges' lengths is guaranteed to be
- equivalent to the number of bytes requested.
-
-poke <address addr> |[<binary unsigned int len> [<binary char data>]] <EOL> ::=
- <bool result> <EOL>
-
- NOTE that the binary portion of this message is prefixed by the
- uppercase US-ASCII character '|' (vertical bar), allowing easier
- synchronization by the server. There is no data between the '|'
- and the rest of the message. ('B' is not used here because
- addresses can contain that letter; no alphanumeric characters are
- used because some of the parsing routines are used by the Solaris
- SA port, and in that port any alphanumeric character can show up
- as a part of a symbol being looked up.)
-
- May only be called once attached. Writes the address space of the
- target process starting at the given address (see below for format
- specifications), extending the given number of bytes, and
- containing the given data. The number of bytes is a 32-bit
- unsigned integer transmitted with big-endian byte ordering (i.e.,
- most significant byte first). This is followed by the raw binary
- data to be placed at that address. The number of bytes of data
- must match the number of bytes specified in the message.
-
- Returns true if the write succeeded; false if it failed, for
- example because a portion of the region was not mapped in the
- target address space.
-
-threadlist <EOL> ::= <int numThreads> [<address threadHandle>...] <EOL>
-
- May only be called once attached and the target process must be
- suspended; otherwise, returns 0. If available, returns handles for
- all of the threads in the target process. These handles may be
- used as arguments to the getcontext and selectorentry
- commands. They do not need to be (and should not be) duplicated
- via the duphandle command and must not be closed via the
- closehandle command.
-
-duphandle <address handle> <EOL> ::=
- <bool success> [<address duplicate>] <EOL>
-
- Duplicates a HANDLE read from the target process's address space.
- HANDLE is a Windows construct (typically typedef'd to void *).
- The returned handle should ultimately be closed via the
- closehandle command; failing to do so can cause resource leaks.
-
- The purpose of this command is to allow the debugger to read the
- value of a thread handle from the target process and query its
- register set and thread selector entries via the getcontext and
- selectorentry commands, below; such use implies that the target
- program has its own notion of the thread list, and further, that
- the debugger has a way of locating that thread list.
-
-closehandle <address handle> <EOL> ::=
-
- Closes a handle retrieved via the duphandle command, above.
-
-getcontext <address threadHandle> <EOL> ::= <bool success> [<context>] <EOL>
-
- Returns the context for the given thread. The handle must either
- be one of the handles returned from the threadlist command or the
- result of duplicating a thread handle out of the target process
- via the duphandle command. The target process must be suspended.
-
- The context is returned as a series of hex values which represent
- the following x86 registers in the following order:
- EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, DS, ES, FS, GS,
- CS, SS, EFLAGS, DR0, DR1, DR2, DR3, DR6, DR7
-
- FIXME: needs to be generalized and/or specified for other
- architectures.
-
-setcontext <address threadHandle> <context> ::= <bool success> <EOL>
-
- Sets the context of the given thread. The target process must be
- suspended. See the getcontext command for the ordering of the
- registers in the context.
-
- Even if the setcontext command succeeds, some of the bits in some
- of the registers (like the global enable bits in the debug
- registers) may be overridden by the operating system. To ensure
- the debugger's notion of the register set is up to date, it is
- recommended to follow up a setcontext with a getcontext.
-
-selectorentry <address threadHandle> <int selector> <EOL> ::=
- <bool success>
- [<address limitLow> <address baseLow>
- <address baseMid> <address flags1>
- <address flags2> <address baseHi>] <EOL>
-
- Retrieves a descriptor table entry for the given thread and
- selector. This data structure allows conversion of a
- segment-relative address to a linear virtual address. It is most
- useful for locating the Thread Information Block for a given
- thread handle to be able to find that thread's ID, to be able to
- understand whether two different thread handles in fact refer to
- the same underlying thread.
-
- This command will only work on the X86 architecture and will
- return false for the success flag (with no additional information
- sent) on other architectures.
-
-suspend ::=
-
- Suspends the target process. Must be attached to a target process.
- A process is suspended when attached to via the attach command. If
- the target process is already suspended then this command has no
- effect.
-
-resume ::=
-
- Resumes the target process without detaching from it. Must be
- attached to a target process. After resuming a target process, the
- debugger client must be prepared to poll for events from the
- target process fairly frequently in order for execution in the
- target process to proceed normally. If the target process is
- already resumed then this command has no effect.
-
-pollevent ::=
- <bool eventPresent> [<address threadHandle> <unsigned int eventCode>]
-
- Additional entries in result for given eventCode:
-
- LOAD/UNLOAD_DLL_DEBUG_EVENT: <address baseOfDLL>
- EXCEPTION_DEBUG_EVENT: <unsigned int exceptionCode> <address faultingPC>
-
- Additional entries for given exceptionCode:
-
- EXCEPTION_ACCESS_VIOLATION: <bool wasWrite> <address faultingAddress>
-
- <EOL>
-
- Polls once to see whether a debug event has been generated by the
- target process. If none is present, returns 0 immediately.
- Otherwise, returns 1 along with a series of textual information
- about the event. The event is not cleared, and the thread resumed,
- until the continueevent command is sent, or the debugger client
- detaches from the target process.
-
- Typically a debugger client will suspend the target process upon
- reception of a debug event. Otherwise, it is not guaranteed that
- all threads will be suspended upon reception of a debug event, and
- any operations requiring that threads be suspended (including
- fetching the context for the thread which generated the event)
- will fail.
-
-continueevent <bool passEventToClient> ::= <bool success> <EOL>
-
- Indicates that the current debug event has been used by the
- debugger client and that the target process should be resumed. The
- passEventToClient flag indicates whether the event should be
- propagated to the target process. Breakpoint and single-step
- events should not be propagated to the target. Returns false if
- there was no pending event, true otherwise.
-
-exit <EOL>
-
- Exits this debugger session.
-
-Format specifications:
-
-// Data formats and example values:
-<EOL> ::= end of line (typically \n on Unix platforms, or \n\r on Windows)
-<address> ::= 0x12345678[9ABCDEF0] /* up to 64-bit hex value */
-<unsigned int> ::= 5 /* up to 32-bit integer number; no leading sign */
-<bool> ::= 1 /* ASCII '0' or '1' */
-<context> ::= <address> ...
--- a/hotspot/agent/src/os/win32/README.txt Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-This is a "Simple Windows Debug Server" written for the purpose of
-enabling the Serviceability Agent on Win32. It has backends both for
-Windows NT 4.0 (using internal Windows APIs for a few routines) as
-well as for 95/98/ME/2000 via the Tool Help APIs.
-
-The reason this debug server is necessary is that the Win32 debug APIs
-by design tear down the target process when the debugger exits (see
-knowledge base article Q164205 on msdn.microsoft.com). On Solaris, one
-can attach to and detach from a process with no effect; this is key to
-allowing dbx and gcore to work.
-
-The Simple Windows Debug Server effectively implements attach/detach
-functionality for arbitrary debug clients. This allows the SA to
-attach non-destructively to a process, and will enable gcore for Win32
-to be written shortly. While the debugger (the "client" in all of the
-source code) is attached, the target process is suspended. (Note that
-the debug server could be extended to support resumption of the target
-process and transmission of debug events over to the debugger, but
-this has been left for the future.)
-
-The makefile (type "nmake") builds two executables: SwDbgSrv.exe,
-which is the server process, and SwDbgSub.exe, which is forked by the
-server and should not be directly invoked by the user.
-
-The intent is that these two executables can be installed into
-C:\WINNT\SYSTEM32 and SwDbgSrv installed to run as a service (on NT),
-for example using ServiceInstaller (http://www.kcmultimedia.com/smaster/).
-However, SwDbgSrv can also be run from the command line. It generates
-no text output unless the source code is changed to enable debugging
-printouts. As long as any processes which have been attached to by the
-SA are alive, the SwDbgSrv and any forked SwDbgSub processes must be
-left running. Terminating them will cause termination of the target
-processes.
-
-The debug server opens port 27000 and accepts incoming connections
-from localhost only. The security model assumes that if one can run a
-process on the given machine then one basically has access to most or
-all of the machine's facilities; this seems to be in line with the
-standard Windows security model. The protocol used is text-based, so
-one can debug the debug server using telnet. See README-commands.txt
-for documentation on the supported commands.
-
-Testing indicates that the performance impact of attaching to a
-process (and therefore permanently attaching a debugger) is minimal.
-Some serious performance problems had been seen which ultimately
-appeared to be a lack of physical memory on the machine running the
-system.
-
-Bugs:
-
-This debug server is fundamentally incompatible with the Visual C++
-debugger. Once the debug server is used to attach to a process, the
-Visual C++ IDE will not be able to attach to the same process (even if
-the debug server is "detached" from that process). Note that this
-system is designed to work with the same primitives that C and C++
-debuggers use (like "symbol lookup" and "read from process memory")
-and exposes these primitives to Java, so in the long term we could
-solve this problem by implementing platform-specific debug symbol
-parsing and a platform-independent C++ debugger in Java.
-
-Note:
-
-The files IOBuf.cpp and IOBuf.hpp are also used in
-building src/os/solaris/agent.
--- a/hotspot/agent/src/os/win32/Reaper.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <iostream>
-#include "Reaper.hpp"
-
-using namespace std;
-
-Reaper::Reaper(ReaperCB* cb) {
- InitializeCriticalSection(&crit);
- event = CreateEvent(NULL, TRUE, FALSE, NULL);
- this->cb = cb;
-
- active = false;
- shouldShutDown = false;
-}
-
-bool
-Reaper::start() {
- bool result = false;
-
- EnterCriticalSection(&crit);
-
- if (!active) {
- DWORD id;
- HANDLE reaper = CreateThread(NULL, 0, &Reaper::reaperThreadEntry,
- this, 0, &id);
- if (reaper != NULL) {
- result = true;
- }
- }
-
- LeaveCriticalSection(&crit);
-
- return result;
-}
-
-bool
-Reaper::stop() {
- bool result = false;
-
- EnterCriticalSection(&crit);
-
- if (active) {
- shouldShutDown = true;
- SetEvent(event);
- while (active) {
- Sleep(1);
- }
- shouldShutDown = false;
- result = true;
- }
-
- LeaveCriticalSection(&crit);
-
- return result;
-}
-
-void
-Reaper::registerProcess(HANDLE processHandle, void* userData) {
- ProcessInfo info;
-
- info.handle = processHandle;
- info.userData = userData;
-
- EnterCriticalSection(&crit);
-
- procInfo.push_back(info);
- SetEvent(event);
-
- LeaveCriticalSection(&crit);
-}
-
-void
-Reaper::reaperThread() {
- while (!shouldShutDown) {
- // Take atomic snapshot of the current process list and user data
- EnterCriticalSection(&crit);
-
- int num = procInfo.size();
- HANDLE* handleList = new HANDLE[1 + num];
- void** dataList = new void*[num];
- for (int i = 0; i < num; i++) {
- handleList[i] = procInfo[i].handle;
- dataList[i] = procInfo[i].userData;
- }
-
- LeaveCriticalSection(&crit);
-
- // Topmost handle becomes the event object, so other threads can
- // signal this one to notice differences in the above list (or
- // shut down)
- handleList[num] = event;
-
- // Wait for these objects
- DWORD idx = WaitForMultipleObjects(1 + num, handleList,
- FALSE, INFINITE);
- if ((idx >= WAIT_OBJECT_0) && (idx <= WAIT_OBJECT_0 + num)) {
- idx -= WAIT_OBJECT_0;
- if (idx < num) {
- // A process exited (i.e., it wasn't that we were woken up
- // just because the event went off)
- (*cb)(dataList[idx]);
- // Remove this process from the list (NOTE: requires that
- // ordering does not change, i.e., that all additions are to
- // the back of the process list)
- EnterCriticalSection(&crit);
-
- std::vector<ProcessInfo>::iterator iter = procInfo.begin();
- iter += idx;
- procInfo.erase(iter);
-
- LeaveCriticalSection(&crit);
- } else {
- // Notification from other thread
- ResetEvent(event);
- }
- } else {
- // Unexpected return value. For now, warn.
- cerr << "Reaper::reaperThread(): unexpected return value "
- << idx << " from WaitForMultipleObjects" << endl;
- }
-
- // Clean up these lists
- delete[] handleList;
- delete[] dataList;
- }
-
- // Time to shut down
- active = false;
-}
-
-DWORD WINAPI
-Reaper::reaperThreadEntry(LPVOID data) {
- Reaper* reaper = (Reaper*) data;
- reaper->reaperThread();
- return 0;
-}
--- a/hotspot/agent/src/os/win32/Reaper.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _REAPER_
-#define _REAPER_
-
-#include <vector>
-#include <windows.h>
-
-typedef void ReaperCB(void* userData);
-
-/** A Reaper maintains a thread which waits for child processes to
- terminate; upon termination it calls a user-specified ReaperCB to
- clean up resources associated with those child processes. */
-
-class Reaper {
-private:
- Reaper& operator=(const Reaper&);
- Reaper(const Reaper&);
-
-public:
- Reaper(ReaperCB*);
- ~Reaper();
-
- // Start the reaper thread.
- bool start();
-
- // Stop the reaper thread. This is called automatically in the
- // reaper's destructor. It is not thread safe and should be called
- // by at most one thread at a time.
- bool stop();
-
- // Register a given child process with the reaper. This should be
- // called by the application's main thread. When that process
- // terminates, the cleanup callback will be called with the
- // specified userData in the context of the reaper thread. Callbacks
- // are guaranteed to be called serially, so they can safely refer to
- // static data as well as the given user data.
- void registerProcess(HANDLE processHandle, void* userData);
-
-private:
- // For thread safety of register()
- CRITICAL_SECTION crit;
-
- ReaperCB* cb;
-
- // State variables
- volatile bool active;
- volatile bool shouldShutDown;
-
- struct ProcessInfo {
- HANDLE handle;
- void* userData;
- };
-
- // Bookkeeping
- std::vector<ProcessInfo> procInfo;
-
- // Synchronization between application thread and reaper thread
- HANDLE event;
-
- // Entry point for reaper thread
- void reaperThread();
-
- // Static function which is actual thread entry point
- static DWORD WINAPI reaperThreadEntry(LPVOID data);
-};
-
-#endif // #defined _REAPER_
--- a/hotspot/agent/src/os/win32/SwDbgSrv.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1266 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-// A Simple Windows Debug Server.
-//
-// This software provides a socket-based debug server which uses
-// mostly ASCII protocols to communicate with its clients. Since the
-// Windows security model is largely based around being able to run
-// programs on the machine, this server only accepts connections
-// coming from localhost.
-//
-// When run as a service (under Windows NT), this software provides
-// clients the ability to attach to and detach from processes without
-// killing those processes. Ordinarily this is forbidden by the
-// Windows debugging APIs (although more recent debugging environments
-// from Microsoft seem to have circumvented this restriction, perhaps
-// in a different way). This is achieved by forking a persistent
-// subprocess for each debugging session which remains alive as long
-// as the target process is.
-//
-// At this point the client can read information out of the target
-// process's address space. Future work includes exposing more
-// functionality like writing to the remote address space and
-// suspending and resuming threads.
-
-#include <iostream>
-#include <vector>
-#include <stdlib.h>
-// Must come before everything else
-#include <winsock2.h>
-#include <assert.h>
-#include "Dispatcher.hpp"
-#include "Handler.hpp"
-#include "initWinsock.hpp"
-#include "ioUtils.hpp"
-#include "isNT4.hpp"
-#include "Message.hpp"
-#include "nt4internals.hpp"
-#include "ports.h"
-#include "procList.hpp"
-#include "serverLists.hpp"
-#include "Reaper.hpp"
-
-// Uncomment the #define below to get messages on stderr
-// #define DEBUGGING
-
-using namespace std;
-
-static ChildList childList;
-static ClientList clientList;
-static Reaper* reaper = NULL;
-
-// Needed prototypes
-void shutdownChild(ChildInfo* childInfo);
-void detachClient(ClientInfo* clientInfo);
-void shutdownClient(ClientInfo* clientInfo);
-
-char *
-longToDotFormat(long addr)
-{
- char *temp_s = new char[20];
-
- sprintf(temp_s, "%d.%d.%d.%d", ((addr & 0xff000000) >> 24),
- ((addr & 0x00ff0000) >> 16), ((addr & 0x0000ff00) >> 8),
- (addr & 0x000000ff));
-
- return temp_s;
-}
-
-// NOTE that we do this query every time. It is a bad idea to cache IP
-// addresses. For example, we might be hosted on a machine using DHCP
-// and the connection addresses might change over time. (Yes, this
-// actually happened.)
-bool
-isConnectionOkay(ULONG connAddr) {
- if (connAddr == INADDR_LOOPBACK) {
- return true;
- }
-
- const int MAXNAME = 1024;
- char myname[MAXNAME];
- gethostname(myname, MAXNAME);
- struct hostent* myInfo = gethostbyname(myname);
- if (myInfo == NULL) {
-#ifdef DEBUGGING
- cerr << "My host information was null" << endl;
-#endif
- } else {
- // Run down the list of IP addresses for myself
- assert(myInfo->h_length == sizeof(ULONG));
-#ifdef DEBUGGING
- cerr << "My known IP addresses: " << endl;
-#endif
- for (char** pp = myInfo->h_addr_list; *pp != NULL; pp++) {
- char* p = *pp;
- ULONG altAddr = ntohl(*((ULONG*) p));
-#ifdef DEBUGGING
- char* name = longToDotFormat(altAddr);
- cerr << name << endl;
- delete[] name;
-#endif
- if (altAddr == connAddr) {
-#ifdef DEBUGGING
- cerr << "FOUND" << endl;
-#endif
- return true;
- }
- }
-#ifdef DEBUGGING
- cerr << "Done." << endl;
-#endif
- }
-
- return false;
-}
-
-SOCKET
-setupListeningSocket(short port) {
- SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
- if (listening == INVALID_SOCKET) {
- cerr << "Error creating listening socket" << endl;
- exit(1);
- }
-
- int reuseAddress = 1;
- if (setsockopt(listening, SOL_SOCKET, SO_REUSEADDR,
- (char *)&reuseAddress, sizeof(reuseAddress)) == -1) {
- cerr << "Error reusing address" << endl;
- exit(1);
- }
-
- struct sockaddr_in serverInfo;
-
- memset((char *)&serverInfo, 0, sizeof(serverInfo));
- serverInfo.sin_addr.s_addr = INADDR_ANY;
- serverInfo.sin_family = AF_INET;
- serverInfo.sin_port = htons(port);
-
- if (bind(listening, (struct sockaddr *) &serverInfo, sizeof(serverInfo)) < 0) {
- cerr << "Error binding socket" << endl;
- exit(1);
- }
-
- if (listen(listening, 5) < 0) {
- cerr << "Error listening" << endl;
- exit(1);
- }
-
- return listening;
-}
-
-/** Accepts a connection from the given listening socket, but only if
- the connection came from localhost. Returns INVALID_SOCKET if the
- connection came from any other IP address or if an error occurred
- during the call to accept(). */
-SOCKET
-acceptFromLocalhost(SOCKET listening) {
- struct sockaddr_in peerAddr;
- int peerAddrLen = sizeof(peerAddr);
- SOCKET fd = accept(listening, (sockaddr*) &peerAddr, &peerAddrLen);
- if (fd == INVALID_SOCKET) {
- return fd;
- }
-
- if (!isConnectionOkay(ntohl(peerAddr.sin_addr.s_addr))) {
- // Reject connections from other machines for security purposes.
- // The Windows security model seems to assume one user per
- // machine, and that security is compromised if another user is
- // able to run executables on the given host. (If these
- // assumptions are not strict enough, we will have to change
- // this.)
- shutdown(fd, SD_BOTH);
- closesocket(fd);
- return INVALID_SOCKET;
- }
-
- // Disable TCP buffering on all sockets. We send small amounts of
- // data back and forth and don't want buffering.
- int buffer_val = 1;
- if (setsockopt(fd, IPPROTO_IP, TCP_NODELAY,
- (char *) &buffer_val, sizeof(buffer_val)) < 0) {
- shutdown(fd, SD_BOTH);
- closesocket(fd);
- }
-
- return fd;
-}
-
-void
-reapCB(void* arg) {
- ChildInfo* info = (ChildInfo*) arg;
- ListsLocker ll;
- DWORD pid = info->getPid();
- shutdownChild(info);
-#ifdef DEBUGGING
- cerr << "Reaped child for process " << pid << endl;
-#endif
-}
-
-/** Starts a child process with stdin and stdout redirected to pipes,
- handles to which are returned. auxHandle1 and auxHandle2 should be
- closed as well when the child process exits. Returns false if
- process creation failed. */
-bool
-startChildProcess(DWORD pidToDebug,
- DWORD childStdinBufSize,
- DWORD childStdoutBufSize,
- LPHANDLE childProcessHandle,
- LPHANDLE writeToStdinHandle,
- LPHANDLE readFromStdoutHandle,
- LPHANDLE auxHandle1,
- LPHANDLE auxHandle2) {
- // Code adapted from Microsoft example
- // "Creating a Child Process with Redirected Input and Output"
-
- SECURITY_ATTRIBUTES saAttr;
- BOOL fSuccess;
-
- HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
- hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
- hSaveStdin, hSaveStdout;
-
- // Set the bInheritHandle flag so pipe handles are inherited.
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- // The steps for redirecting child process's STDOUT:
- // 1. Save current STDOUT, to be restored later.
- // 2. Create anonymous pipe to be STDOUT for child process.
- // 3. Set STDOUT of the parent process to be write handle to
- // the pipe, so it is inherited by the child process.
- // 4. Create a noninheritable duplicate of the read handle and
- // close the inheritable read handle.
-
- // Save the handle to the current STDOUT.
- hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- // Create a pipe for the child process's STDOUT.
- if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, childStdoutBufSize)) {
- return false;
- }
- // Set a write handle to the pipe to be STDOUT.
- if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) {
- return false;
- }
- // Create noninheritable read handle and close the inheritable read
- // handle.
- fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
- GetCurrentProcess(), &hChildStdoutRdDup,
- 0, FALSE,
- DUPLICATE_SAME_ACCESS);
- if( !fSuccess ) {
- return false;
- }
- CloseHandle(hChildStdoutRd);
-
- // The steps for redirecting child process's STDIN:
- // 1. Save current STDIN, to be restored later.
- // 2. Create anonymous pipe to be STDIN for child process.
- // 3. Set STDIN of the parent to be the read handle to the
- // pipe, so it is inherited by the child process.
- // 4. Create a noninheritable duplicate of the write handle,
- // and close the inheritable write handle.
- // Save the handle to the current STDIN.
- hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
- // Create a pipe for the child process's STDIN.
- if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, childStdinBufSize)) {
- return false;
- }
- // Set a read handle to the pipe to be STDIN.
- if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd)) {
- return false;
- }
- // Duplicate the write handle to the pipe so it is not inherited.
- fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
- GetCurrentProcess(), &hChildStdinWrDup, 0,
- FALSE, // not inherited
- DUPLICATE_SAME_ACCESS);
- if (! fSuccess) {
- return false;
- }
- CloseHandle(hChildStdinWr);
-
- // Create the child process
- char cmdLine[256];
- sprintf(cmdLine, "SwDbgSub.exe %u", pidToDebug);
- PROCESS_INFORMATION procInfo;
- STARTUPINFO startInfo;
- memset((char*) &startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
- BOOL res = CreateProcess(NULL,
- cmdLine,
- NULL,
- NULL,
- TRUE, // inherit handles: important
- 0,
- NULL,
- NULL,
- &startInfo,
- &procInfo);
- if (!res) {
- return false;
- }
- // After process creation, restore the saved STDIN and STDOUT.
- if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin)) {
- return false;
- }
- if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) {
- return false;
- }
-
- // hChildStdinWrDup can be used to write to the child's stdin
- // hChildStdoutRdDup can be used to read from the child's stdout
-
- // NOTE: example code closes hChildStdoutWr before reading from
- // hChildStdoutRdDup. "Close the write end of the pipe before
- // reading from the read end of the pipe"??? Looks like this is
- // example-specific.
-
- // Set up return arguments
- // hChildStdoutRd and hChildStdinWr are already closed at this point
- *childProcessHandle = procInfo.hProcess;
- *writeToStdinHandle = hChildStdinWrDup;
- *readFromStdoutHandle = hChildStdoutRdDup;
- *auxHandle1 = hChildStdinRd;
- *auxHandle2 = hChildStdoutWr;
- return true;
-}
-
-/** Clears the event and writes the message to the child process */
-bool
-sendMessage(ChildInfo* child, Message* message) {
- DWORD numBytesWritten;
- if (!WriteFile(child->getWriteToStdinHandle(),
- message, sizeof(Message), &numBytesWritten, NULL)) {
- return false;
- }
- if (numBytesWritten != sizeof(Message)) {
- return false;
- }
- // Follow up "poke" messages with the raw data
- if (message->type == Message::POKE) {
- if (!WriteFile(child->getWriteToStdinHandle(),
- message->pokeArg.data, message->pokeArg.numBytes, &numBytesWritten, NULL)) {
- return false;
- }
- if (numBytesWritten != message->pokeArg.numBytes) {
- return false;
- }
- }
- return true;
-}
-
-/** Copies data from child's stdout to the client's IOBuf and sends it
- along */
-bool
-forwardReplyToClient(ChildInfo* child, ClientInfo* client) {
- DWORD total = 0;
- IOBuf::FillState ret;
-
- do {
- DWORD temp;
- ret = client->getIOBuf()->fillFromFileHandle(child->getReadFromStdoutHandle(),
- &temp);
- if (ret == IOBuf::DONE || ret == IOBuf::MORE_DATA_PENDING) {
- if (!client->getIOBuf()->flush()) {
-#ifdef DEBUGGING
- cerr << "Forward failed because flush failed" << endl;
-#endif
- return false;
- }
- total += temp;
- }
- } while (ret == IOBuf::MORE_DATA_PENDING);
-
- return (ret == IOBuf::FAILED) ? false : true;
-}
-
-//----------------------------------------------------------------------
-// Server Handler
-//
-
-class ServerHandler : public Handler {
-public:
- ServerHandler();
-
- // Starts up in Unicode mode by default
- bool getASCII();
-
- void setIOBuf(IOBuf* ioBuf);
-
- void procList(char* arg);
-
- // Must be called before calling one of the routines below
- void setClientInfo(ClientInfo* info);
-
- // Indicates to outer loop that exit was called or that an error
- // occurred and that the client exited.
- bool exited();
- // Clears this state
- void clearExited();
-
- void ascii(char* arg);
- void unicode(char* arg);
- void attach(char* arg);
- void detach(char* arg);
- void libInfo(char* arg);
- void peek(char* arg);
- void poke(char* arg);
- void threadList(char* arg);
- void dupHandle(char* arg);
- void closeHandle(char* arg);
- void getContext(char* arg);
- void setContext(char* arg);
- void selectorEntry(char* arg);
- void suspend(char* arg);
- void resume(char* arg);
- void pollEvent(char* arg);
- void continueEvent(char* arg);
- void exit(char* arg);
-
- // This is pretty gross. Needed to make the target process know
- // about clients that have disconnected unexpectedly while attached.
- friend void shutdownClient(ClientInfo*);
-private:
- // Writes: charSize <space> numChars <space> <binary string>
- // Handles both ASCII and UNICODE modes
- void writeString(USHORT len, WCHAR* str);
-
- // Handles only ASCII mode
- void writeString(USHORT len, char* str);
-
- ClientInfo* clientInfo;
- IOBuf* ioBuf;
- bool _exited;
- bool _ascii;
-};
-
-static ServerHandler* handler;
-
-ServerHandler::ServerHandler() {
- _exited = false;
- _ascii = false;
- ioBuf = NULL;
-}
-
-bool
-ServerHandler::getASCII() {
- return _ascii;
-}
-
-void
-ServerHandler::setIOBuf(IOBuf* buf) {
- ioBuf = buf;
-}
-
-void
-ServerHandler::setClientInfo(ClientInfo* info) {
- clientInfo = info;
-}
-
-bool
-ServerHandler::exited() {
- return _exited;
-}
-
-void
-ServerHandler::clearExited() {
- _exited = false;
-}
-
-void
-ServerHandler::ascii(char* arg) {
- _ascii = true;
-}
-
-void
-ServerHandler::unicode(char* arg) {
- _ascii = false;
-}
-
-void
-ServerHandler::procList(char* arg) {
-#ifdef DEBUGGING
- cerr << "proclist" << endl;
-#endif
-
- ProcEntryList processes;
- ::procList(processes);
-
- ioBuf->writeInt(processes.size());
-
- for (ProcEntryList::iterator iter = processes.begin();
- iter != processes.end(); iter++) {
- ProcEntry& entry = *iter;
- ioBuf->writeSpace();
- ioBuf->writeUnsignedInt(entry.getPid());
- ioBuf->writeSpace();
- writeString(entry.getNameLength(), entry.getName());
- }
-
- ioBuf->writeEOL();
- ioBuf->flush();
-}
-
-void
-ServerHandler::attach(char* arg) {
- // If the client is already attached to a process, fail.
- if (clientInfo->getTarget() != NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- // Try to get pid
- DWORD pid;
- if (!scanUnsignedLong(&arg, &pid)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- // See whether this pid is already forked
- ListsLocker ll;
- ChildInfo* childInfo = childList.getChildByPid(pid);
- if (childInfo != NULL) {
- // If this child already has a client, return false
- if (childInfo->getClient() != NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- // Otherwise, can associate this client with this child process
- childInfo->setClient(clientInfo);
- clientInfo->setTarget(childInfo);
-
- // Tell the child we are attaching so it can suspend the target
- // process
- Message msg;
- msg.type = Message::ATTACH;
- sendMessage(childInfo, &msg);
-
- ioBuf->writeBoolAsInt(true);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- } else {
- // Have to fork a new child subprocess
- HANDLE childProcessHandle;
- HANDLE writeToStdinHandle;
- HANDLE readFromStdoutHandle;
- HANDLE auxHandle1;
- HANDLE auxHandle2;
- if (!startChildProcess(pid,
- 32768,
- 131072,
- &childProcessHandle,
- &writeToStdinHandle,
- &readFromStdoutHandle,
- &auxHandle1,
- &auxHandle2)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- // See whether the child succeeded in attaching to the process
- char res;
- DWORD numRead;
- if (!ReadFile(readFromStdoutHandle,
- &res,
- sizeof(char),
- &numRead,
- NULL)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- if (!res) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- // OK, success.
- childInfo = new ChildInfo(pid, childProcessHandle,
- writeToStdinHandle, readFromStdoutHandle,
- auxHandle1, auxHandle2);
- childList.addChild(childInfo);
- reaper->registerProcess(childProcessHandle, childInfo);
- // Associate this client with this child process
- childInfo->setClient(clientInfo);
- clientInfo->setTarget(childInfo);
-
- // Tell the child process to actually suspend the target process
- Message msg;
- msg.type = Message::ATTACH;
- sendMessage(childInfo, &msg);
-
- // Write result to client
- ioBuf->writeBoolAsInt(true);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-}
-
-void
-ServerHandler::detach(char* arg) {
- // If the client is not attached, fail.
- if (clientInfo->getTarget() == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- detachClient(clientInfo);
-
- ioBuf->writeBoolAsInt(true);
- ioBuf->writeEOL();
- ioBuf->flush();
-}
-
-void
-ServerHandler::libInfo(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeInt(0);
- ioBuf->writeEOL();
- ioBuf->flush();
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::LIBINFO;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::peek(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeString("B");
- ioBuf->writeBinChar(0);
- ioBuf->flush();
- return;
- }
-
- // Try to get address
- DWORD address;
- if (!scanAddress(&arg, &address)) {
- ioBuf->writeString("B");
- ioBuf->writeBinChar(0);
- ioBuf->flush();
- return;
- }
-
- // Try to get number of bytes
- DWORD numBytes;
- if (!scanUnsignedLong(&arg, &numBytes)) {
- ioBuf->writeString("B");
- ioBuf->writeBinChar(0);
- ioBuf->flush();
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::PEEK;
- msg.peekArg.address = address;
- msg.peekArg.numBytes = numBytes;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::poke(char* arg) {
-#ifdef DEBUGGING
- cerr << "ServerHandler::poke" << endl;
-#endif
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get address
- DWORD address;
- if (!scanAddress(&arg, &address)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get number of bytes
- if (!scanAndSkipBinEscapeChar(&arg)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
- DWORD numBytes;
- if (!scanBinUnsignedLong(&arg, &numBytes)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Raw data is now in "arg"
- // Send message to child
- Message msg;
- msg.type = Message::POKE;
- msg.pokeArg.address = address;
- msg.pokeArg.numBytes = numBytes;
- msg.pokeArg.data = arg;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::threadList(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::THREADLIST;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::dupHandle(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get handle
- DWORD address;
- if (!scanAddress(&arg, &address)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::DUPHANDLE;
- msg.handleArg.handle = (HANDLE) address;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::closeHandle(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- return;
- }
-
- // Try to get handle
- DWORD address;
- if (!scanAddress(&arg, &address)) {
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::CLOSEHANDLE;
- msg.handleArg.handle = (HANDLE) address;
- sendMessage(child, &msg);
-
- // No reply
-}
-
-void
-ServerHandler::getContext(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get handle
- DWORD address;
- if (!scanAddress(&arg, &address)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::GETCONTEXT;
- msg.handleArg.handle = (HANDLE) address;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::setContext(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get handle
- DWORD address;
- if (!scanAddress(&arg, &address)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get context
- DWORD regs[NUM_REGS_IN_CONTEXT];
- for (int i = 0; i < NUM_REGS_IN_CONTEXT; i++) {
- if (!scanAddress(&arg, ®s[i])) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::SETCONTEXT;
- msg.setContextArg.handle = (HANDLE) address;
- msg.setContextArg.Eax = regs[0];
- msg.setContextArg.Ebx = regs[1];
- msg.setContextArg.Ecx = regs[2];
- msg.setContextArg.Edx = regs[3];
- msg.setContextArg.Esi = regs[4];
- msg.setContextArg.Edi = regs[5];
- msg.setContextArg.Ebp = regs[6];
- msg.setContextArg.Esp = regs[7];
- msg.setContextArg.Eip = regs[8];
- msg.setContextArg.Ds = regs[9];
- msg.setContextArg.Es = regs[10];
- msg.setContextArg.Fs = regs[11];
- msg.setContextArg.Gs = regs[12];
- msg.setContextArg.Cs = regs[13];
- msg.setContextArg.Ss = regs[14];
- msg.setContextArg.EFlags = regs[15];
- msg.setContextArg.Dr0 = regs[16];
- msg.setContextArg.Dr1 = regs[17];
- msg.setContextArg.Dr2 = regs[18];
- msg.setContextArg.Dr3 = regs[19];
- msg.setContextArg.Dr6 = regs[20];
- msg.setContextArg.Dr7 = regs[21];
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::selectorEntry(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get thread handle
- DWORD address;
- if (!scanAddress(&arg, &address)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get selector
- DWORD selector;
- if (!scanUnsignedLong(&arg, &selector)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::SELECTORENTRY;
- msg.selectorArg.handle = (HANDLE) address;
- msg.selectorArg.selector = selector;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::suspend(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::SUSPEND;
- sendMessage(child, &msg);
-
- // No reply
-}
-
-void
-ServerHandler::resume(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::RESUME;
- sendMessage(child, &msg);
-
- // No reply
-}
-
-void
-ServerHandler::pollEvent(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::POLLEVENT;
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::continueEvent(char* arg) {
- ListsLocker ll;
- ChildInfo* child = clientInfo->getTarget();
- if (child == NULL) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Try to get bool arg
- int passEventToClient;
- if (!scanInt(&arg, &passEventToClient)) {
- ioBuf->writeBoolAsInt(false);
- ioBuf->flush();
- return;
- }
-
- // Send message to child
- Message msg;
- msg.type = Message::CONTINUEEVENT;
- msg.boolArg.val = ((passEventToClient != 0) ? true : false);
- sendMessage(child, &msg);
-
- // Forward reply to client
- forwardReplyToClient(child, clientInfo);
-}
-
-void
-ServerHandler::exit(char* arg) {
- shutdownClient(clientInfo);
- _exited = true;
-}
-
-void
-ServerHandler::writeString(USHORT len, WCHAR* str) {
- if (_ascii) {
- char* cStr = new char[len + 1];
- sprintf(cStr, "%.*ls", len, str);
- writeString(len, cStr);
- delete[] cStr;
- } else {
- ioBuf->writeInt(sizeof(unsigned short));
- ioBuf->writeSpace();
- ioBuf->writeInt(len);
- ioBuf->writeSpace();
- for (int i = 0; i < len; i++) {
- ioBuf->writeBinUnsignedShort(str[i]);
- }
- }
-}
-
-void
-ServerHandler::writeString(USHORT len, char* str) {
- ioBuf->writeInt(1);
- ioBuf->writeSpace();
- ioBuf->writeInt(len);
- ioBuf->writeSpace();
- ioBuf->writeString(str);
-}
-
-//
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// Shutdown routines
-//
-
-void
-shutdownChild(ChildInfo* childInfo) {
- childList.removeChild(childInfo);
- childInfo->closeAll();
- if (childInfo->getClient() != NULL) {
- shutdownClient(childInfo->getClient());
- }
- delete childInfo;
-}
-
-void
-detachClient(ClientInfo* info) {
- ListsLocker ll;
- // May have been dissociated while not under cover of lock
- if (info->getTarget() == NULL) {
- return;
- }
-
- // Tell the child that we have detached to let the target process
- // continue running
- Message msg;
- msg.type = Message::DETACH;
- sendMessage(info->getTarget(), &msg);
-
- // Dissociate the client and the target
- info->getTarget()->setClient(NULL);
- info->setTarget(NULL);
-}
-
-void
-shutdownClient(ClientInfo* clientInfo) {
-#ifdef DEBUGGING
- cerr << "Shutting down client" << endl;
-#endif
-
- // If we're connected, inform the target process that we're
- // disconnecting
- detachClient(clientInfo);
-
- // Remove this client from the list and delete it
- clientList.removeClient(clientInfo);
- if (clientInfo->getTarget() != NULL) {
- clientInfo->getTarget()->setClient(NULL);
- }
- clientInfo->closeAll();
- delete clientInfo;
-}
-
-//
-//----------------------------------------------------------------------
-
-
-/** Main dispatcher for client commands. NOTE: do not refer to this
- clientInfo data structure after calling this routine, as it may be
- deleted internally. */
-void
-readAndDispatch(ClientInfo* clientInfo) {
- IOBuf::ReadLineResult res;
- IOBuf* ioBuf = clientInfo->getIOBuf();
- unsigned long howMany;
- ioctlsocket(clientInfo->getDataSocket(), FIONREAD, &howMany);
- if (howMany == 0) {
- // Client closed down.
- shutdownClient(clientInfo);
- return;
- }
- // Read and process as much data as possible
- do {
- res = ioBuf->tryReadLine();
- if (res == IOBuf::RL_ERROR) {
-#ifdef DEBUGGING
- cerr << "Error while reading line" << endl;
-#endif
- shutdownClient(clientInfo);
- return;
- } else if (res == IOBuf::RL_GOT_DATA) {
-#ifdef DEBUGGING
- cerr << "Got data: \"" << ioBuf->getLine() << "\"" << endl;
-#endif
- handler->setIOBuf(ioBuf);
- handler->setClientInfo(clientInfo);
- handler->clearExited();
- Dispatcher::dispatch(ioBuf->getLine(), handler);
- }
- } while (res == IOBuf::RL_GOT_DATA && (!handler->exited()));
-#ifdef DEBUGGING
- cerr << "Exiting readAndDispatch" << endl;
-#endif
-}
-
-int
-main(int argc, char **argv)
-{
- initWinsock();
-
- if (isNT4()) {
- loadPSAPIDLL(); // Will exit if not present
- }
-
- SOCKET clientListeningSock = setupListeningSocket(CLIENT_PORT);
-
- handler = new ServerHandler();
- Lists::init();
-
- reaper = new Reaper(&reapCB);
- if (!reaper->start()) {
- exit(1);
- }
-
- while (true) {
- // Select on all sockets:
- // - client listening socket
- // - sockets for all client connections
-
- // When one of the client connections closes, close its socket
- // handles.
-
- fd_set set;
- SOCKET maxSock = 0;
-
- // Set up fd_set
- {
- int i;
- FD_ZERO(&set);
- FD_SET(clientListeningSock, &set);
- if (clientListeningSock > maxSock) {
- maxSock = clientListeningSock;
- }
- for (i = 0; i < clientList.size(); i++) {
- ClientInfo* info = clientList.get(i);
- if (info->getDataSocket() > maxSock) {
- maxSock = info->getDataSocket();
- }
- FD_SET(info->getDataSocket(), &set);
- }
- }
- struct timeval timeout;
- timeout.tv_sec = 300; // 5 minutes
- timeout.tv_usec = 0;
- int res = select(maxSock, &set, NULL, NULL, &timeout);
- if (res > 0) {
-
- ////////////////
- // New client //
- ////////////////
- if (FD_ISSET(clientListeningSock, &set)) {
- SOCKET fd = acceptFromLocalhost(clientListeningSock);
- if (fd != INVALID_SOCKET) {
- // Create new client information object
- ClientInfo* info = new ClientInfo(fd);
- // Add to list of clients
- clientList.addClient(info);
-#ifdef DEBUGGING
- cerr << "New client" << endl;
-#endif
- }
- }
-
- ///////////////////////////
- // Commands from clients //
- ///////////////////////////
- ClientInfo* clientInfo;
- if (clientList.isAnyDataSocketSet(&set, &clientInfo)) {
- readAndDispatch(clientInfo);
- }
- } else if (res < 0) {
- // Looks like one of the clients was killed. Try to figure out which one.
- bool found = false;
- fd_set set;
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- for (int i = 0; i < clientList.size(); i++) {
- ClientInfo* info = clientList.get(i);
- FD_ZERO(&set);
- FD_SET(info->getDataSocket(), &set);
- if (select(1 + info->getDataSocket(), &set, NULL, NULL, &timeout) < 0) {
- found = true;
- clientList.removeClient(info);
- info->closeAll();
- delete info;
- break;
- }
- }
- if (!found) {
- // This indicates trouble -- one of our listening sockets died.
- exit(1);
- }
- }
- }
-
- return 0;
-}
--- a/hotspot/agent/src/os/win32/SwDbgSrv.dsp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-# Microsoft Developer Studio Project File - Name="SwDbgSrv" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=SwDbgSrv - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "SwDbgSrv.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "SwDbgSrv.mak" CFG="SwDbgSrv - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "SwDbgSrv - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "SwDbgSrv - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "SwDbgSrv - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "SwDbgSrv - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "SwDbgSrv___Win32_Debug"
-# PROP BASE Intermediate_Dir "SwDbgSrv___Win32_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "SwDbgSrv - Win32 Release"
-# Name "SwDbgSrv - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\Buffer.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Dispatcher.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\initWinsock.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\IOBuf.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\ioUtils.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\isNT4.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\nt4internals.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\procList.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Reaper.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\serverLists.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\SwDbgSrv.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\toolHelp.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
--- a/hotspot/agent/src/os/win32/SwDbgSrv.dsw Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "SwDbgSrv"=.\SwDbgSrv.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "SwDbgSub"=.\SwDbgSub.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
--- a/hotspot/agent/src/os/win32/SwDbgSub.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,883 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-// This is the source code for the subprocess forked by the Simple
-// Windows Debug Server. It assumes most of the responsibility for the
-// debug session, and processes all of the commands sent by clients.
-
-// Disable too-long symbol warnings
-#pragma warning ( disable : 4786 )
-
-#include <iostream>
-#include <vector>
-#include <stdlib.h>
-#include <assert.h>
-// Must come before windows.h
-#include <winsock2.h>
-#include <windows.h>
-#include "IOBuf.hpp"
-#include "libInfo.hpp"
-#include "LockableList.hpp"
-#include "Message.hpp"
-#include "Monitor.hpp"
-#include "nt4internals.hpp"
-
-// Uncomment the #define below to get messages on stderr
-// #define DEBUGGING
-
-using namespace std;
-
-DWORD pid;
-HANDLE procHandle;
-IOBuf* ioBuf;
-
-// State flags indicating whether the attach to the remote process
-// definitively succeeded or failed
-volatile bool attachFailed = false;
-volatile bool attachSucceeded = false;
-
-// State flag indicating whether the target process is suspended.
-// Modified by suspend()/resume(), viewed by debug thread, but only
-// under cover of the threads lock.
-volatile bool suspended = false;
-
-// State flags indicating whether we are considered to be attached to
-// the target process and are therefore queuing up events to be sent
-// back to the debug server. These flags are only accessed and
-// modified under the cover of the eventLock.
-Monitor* eventLock;
-// The following is set to true when a client is attached to this process
-volatile bool generateDebugEvents = false;
-// Pointer to current debug event; non-NULL indicates a debug event is
-// waiting to be sent to the client. Main thread sets this to NULL to
-// indicate that the event has been consumed; also sets
-// passEventToClient, below.
-volatile DEBUG_EVENT* curDebugEvent = NULL;
-// Set by main thread to indicate whether the most recently posted
-// debug event should be passed on to the target process.
-volatile bool passEventToClient = true;
-
-void conditionalPostDebugEvent(DEBUG_EVENT* ev, DWORD* continueOrNotHandledFlag) {
- // FIXME: make it possible for the client to enable and disable
- // certain types of events (have to do so in a platform-independent
- // manner)
- switch (ev->dwDebugEventCode) {
- case EXCEPTION_DEBUG_EVENT:
- switch (ev->u.Exception.ExceptionRecord.ExceptionCode) {
- case EXCEPTION_BREAKPOINT: break;
- case EXCEPTION_SINGLE_STEP: break;
- case EXCEPTION_ACCESS_VIOLATION: break;
- default: return;
- }
- }
- eventLock->lock();
- if (generateDebugEvents) {
- curDebugEvent = ev;
- while (curDebugEvent != NULL) {
- eventLock->wait();
- }
- if (passEventToClient) {
- *continueOrNotHandledFlag = DBG_EXCEPTION_NOT_HANDLED;
- } else {
- *continueOrNotHandledFlag = DBG_CONTINUE;
- }
- }
- eventLock->unlock();
-}
-
-
-//----------------------------------------------------------------------
-// Module list
-//
-
-vector<LibInfo> libs;
-
-//----------------------------------------------------------------------
-// Thread list
-//
-
-struct ThreadInfo {
- DWORD tid;
- HANDLE thread;
-
- ThreadInfo(DWORD tid, HANDLE thread) {
- this->tid = tid;
- this->thread = thread;
- }
-};
-
-class ThreadList : public LockableList<ThreadInfo> {
-public:
- bool removeByThreadID(DWORD tid) {
- for (InternalListType::iterator iter = internalList.begin();
- iter != internalList.end(); iter++) {
- if ((*iter).tid == tid) {
- internalList.erase(iter);
- return true;
- }
- }
- return false;
- }
- HANDLE threadIDToHandle(DWORD tid) {
- for (InternalListType::iterator iter = internalList.begin();
- iter != internalList.end(); iter++) {
- if ((*iter).tid == tid) {
- return (*iter).thread;
- }
- }
- return NULL;
- }
-};
-
-ThreadList threads;
-
-//----------------------------------------------------------------------
-// INITIALIZATION AND TERMINATION
-//
-
-void
-printError(const char* prefix) {
- DWORD detail = GetLastError();
- LPTSTR message;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- 0,
- detail,
- 0,
- (LPTSTR) &message,
- 1,
- NULL);
- // FIXME: This is signaling an error: "The handle is invalid." ?
- // Do I have to do all of my WaitForDebugEvent calls from the same thread?
- cerr << prefix << ": " << message << endl;
- LocalFree(message);
-}
-
-void
-endProcess(bool waitForProcess = true) {
- NT4::unloadNTDLL();
- if (waitForProcess) {
- // Though we're exiting because of an error, do not tear down the
- // target process.
- WaitForSingleObject(procHandle, INFINITE);
- }
- CloseHandle(procHandle);
- exit(0);
-}
-
-DWORD WINAPI
-debugThreadEntry(void*) {
-#ifdef DEBUGGING
- DWORD lastMsgId = 0;
- int count = 0;
-#endif
-
- if (!DebugActiveProcess(pid)) {
- attachFailed = true;
- return 0;
- }
-
- // Wait for debug events. We keep the information from some of these
- // on the side in anticipation of later queries by the client. NOTE
- // that we leave the process running. The main thread is responsible
- // for suspending and resuming all currently-active threads upon
- // client attach and detach.
-
- while (true) {
- DEBUG_EVENT ev;
- if (!WaitForDebugEvent(&ev, INFINITE)) {
-#ifdef DEBUGGING
- if (++count < 10) {
- // FIXME: This is signaling an error: "The handle is invalid." ?
- // Do I have to do all of my WaitForDebugEvent calls from the same thread?
- printError("WaitForDebugEvent failed");
- }
-#endif
- } else {
-
-#ifdef DEBUGGING
- if (ev.dwDebugEventCode != lastMsgId) {
- lastMsgId = ev.dwDebugEventCode;
- count = 0;
- cerr << "Debug thread received event " << ev.dwDebugEventCode << endl;
- } else {
- if (++count < 10) {
- cerr << "Debug thread received event " << ev.dwDebugEventCode << endl;
- }
- }
-#endif
-
- DWORD dbgContinueMode = DBG_CONTINUE;
-
- switch (ev.dwDebugEventCode) {
- case LOAD_DLL_DEBUG_EVENT:
- conditionalPostDebugEvent(&ev, &dbgContinueMode);
- break;
-
- case UNLOAD_DLL_DEBUG_EVENT:
- conditionalPostDebugEvent(&ev, &dbgContinueMode);
- break;
-
- case CREATE_PROCESS_DEBUG_EVENT:
- threads.lock();
- // FIXME: will this deal properly with child processes? If
- // not, is it possible to make it do so?
-#ifdef DEBUGGING
- cerr << "CREATE_PROCESS_DEBUG_EVENT " << ev.dwThreadId
- << " " << ev.u.CreateProcessInfo.hThread << endl;
-#endif
- if (ev.u.CreateProcessInfo.hThread != NULL) {
- threads.add(ThreadInfo(ev.dwThreadId, ev.u.CreateProcessInfo.hThread));
- }
- threads.unlock();
- break;
-
- case CREATE_THREAD_DEBUG_EVENT:
- threads.lock();
-#ifdef DEBUGGING
- cerr << "CREATE_THREAD_DEBUG_EVENT " << ev.dwThreadId
- << " " << ev.u.CreateThread.hThread << endl;
-#endif
- if (suspended) {
- // Suspend this thread before adding it to the thread list
- SuspendThread(ev.u.CreateThread.hThread);
- }
- threads.add(ThreadInfo(ev.dwThreadId, ev.u.CreateThread.hThread));
- threads.unlock();
- break;
-
- case EXIT_THREAD_DEBUG_EVENT:
- threads.lock();
-#ifdef DEBUGGING
- cerr << "EXIT_THREAD_DEBUG_EVENT " << ev.dwThreadId << endl;
-#endif
- threads.removeByThreadID(ev.dwThreadId);
- threads.unlock();
- break;
-
- case EXCEPTION_DEBUG_EVENT:
- // cerr << "EXCEPTION_DEBUG_EVENT" << endl;
- switch (ev.u.Exception.ExceptionRecord.ExceptionCode) {
- case EXCEPTION_BREAKPOINT:
- // cerr << "EXCEPTION_BREAKPOINT" << endl;
- if (!attachSucceeded && !attachFailed) {
- attachSucceeded = true;
- }
- break;
-
- default:
- dbgContinueMode = DBG_EXCEPTION_NOT_HANDLED;
- break;
- }
- conditionalPostDebugEvent(&ev, &dbgContinueMode);
- break;
-
- case EXIT_PROCESS_DEBUG_EVENT:
- endProcess(false);
- // NOT REACHED
- break;
-
- default:
-#ifdef DEBUGGING
- cerr << "Received debug event " << ev.dwDebugEventCode << endl;
-#endif
- break;
- }
-
- ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, dbgContinueMode);
- }
- }
-}
-
-bool
-attachToProcess() {
- // Create event lock
- eventLock = new Monitor();
-
- // Get a process handle for later
- procHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
- if (procHandle == NULL) {
- return false;
- }
-
- // Start up the debug thread
- DWORD debugThreadId;
- if (CreateThread(NULL, 0, &debugThreadEntry, NULL, 0, &debugThreadId) == NULL) {
- // Failed to make background debug thread. Fail.
- return false;
- }
-
- while ((!attachSucceeded) && (!attachFailed)) {
- Sleep(1);
- }
-
- if (attachFailed) {
- return false;
- }
-
- assert(attachSucceeded);
-
- return true;
-}
-
-bool
-readMessage(Message* msg) {
- DWORD numRead;
- if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE),
- msg,
- sizeof(Message),
- &numRead,
- NULL)) {
- return false;
- }
- if (numRead != sizeof(Message)) {
- return false;
- }
- // For "poke" messages, must follow up by reading raw data
- if (msg->type == Message::POKE) {
- char* dataBuf = new char[msg->pokeArg.numBytes];
- if (dataBuf == NULL) {
- return false;
- }
- if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE),
- dataBuf,
- msg->pokeArg.numBytes,
- &numRead,
- NULL)) {
- delete[] dataBuf;
- return false;
- }
- if (numRead != msg->pokeArg.numBytes) {
- delete[] dataBuf;
- return false;
- }
- msg->pokeArg.data = (void *) dataBuf;
- }
- return true;
-}
-
-void
-handlePeek(Message* msg) {
-#ifdef DEBUGGING
- cerr << "Entering handlePeek()" << endl;
-#endif
-
- char* memBuf = new char[msg->peekArg.numBytes];
- if (memBuf == NULL) {
- ioBuf->writeString("B");
- ioBuf->writeBinChar(0);
- ioBuf->flush();
- delete[] memBuf;
- return;
- }
-
- // Try fast case first
- DWORD numRead;
- BOOL res = ReadProcessMemory(procHandle,
- (LPCVOID) msg->peekArg.address,
- memBuf,
- msg->peekArg.numBytes,
- &numRead);
- if (res && (numRead == msg->peekArg.numBytes)) {
-
- // OK, complete success. Phew.
-#ifdef DEBUGGING
- cerr << "Peek success case" << endl;
-#endif
- ioBuf->writeString("B");
- ioBuf->writeBinChar(1);
- ioBuf->writeBinUnsignedInt(numRead);
- ioBuf->writeBinChar(1);
- ioBuf->writeBinBuf(memBuf, numRead);
- } else {
-#ifdef DEBUGGING
- cerr << "*** Peek slow case ***" << endl;
-#endif
-
- ioBuf->writeString("B");
- ioBuf->writeBinChar(1);
-
- // Use VirtualQuery to speed things up a bit
- DWORD numLeft = msg->peekArg.numBytes;
- char* curAddr = (char*) msg->peekArg.address;
- while (numLeft > 0) {
- MEMORY_BASIC_INFORMATION memInfo;
- VirtualQueryEx(procHandle, curAddr, &memInfo, sizeof(memInfo));
- DWORD numToRead = memInfo.RegionSize;
- if (numToRead > numLeft) {
- numToRead = numLeft;
- }
- DWORD numRead;
- if (memInfo.State == MEM_COMMIT) {
- // Read the process memory at this address for this length
- // FIXME: should check the result of this read
- ReadProcessMemory(procHandle, curAddr, memBuf,
- numToRead, &numRead);
- // Write this out
-#ifdef DEBUGGING
- cerr << "*** Writing " << numToRead << " bytes as mapped ***" << endl;
-#endif
- ioBuf->writeBinUnsignedInt(numToRead);
- ioBuf->writeBinChar(1);
- ioBuf->writeBinBuf(memBuf, numToRead);
- } else {
- // Indicate region is free
-#ifdef DEBUGGING
- cerr << "*** Writing " << numToRead << " bytes as unmapped ***" << endl;
-#endif
- ioBuf->writeBinUnsignedInt(numToRead);
- ioBuf->writeBinChar(0);
- }
- curAddr += numToRead;
- numLeft -= numToRead;
- }
- }
-
- ioBuf->flush();
- delete[] memBuf;
-#ifdef DEBUGGING
- cerr << "Exiting handlePeek()" << endl;
-#endif
-}
-
-void
-handlePoke(Message* msg) {
-#ifdef DEBUGGING
- cerr << "Entering handlePoke()" << endl;
-#endif
- DWORD numWritten;
- BOOL res = WriteProcessMemory(procHandle,
- (LPVOID) msg->pokeArg.address,
- msg->pokeArg.data,
- msg->pokeArg.numBytes,
- &numWritten);
- if (res && (numWritten == msg->pokeArg.numBytes)) {
- // Success
- ioBuf->writeBoolAsInt(true);
-#ifdef DEBUGGING
- cerr << " (Succeeded)" << endl;
-#endif
- } else {
- // Failure
- ioBuf->writeBoolAsInt(false);
-#ifdef DEBUGGING
- cerr << " (Failed)" << endl;
-#endif
- }
- ioBuf->writeEOL();
- ioBuf->flush();
- // We clean up the data
- char* dataBuf = (char*) msg->pokeArg.data;
- delete[] dataBuf;
-#ifdef DEBUGGING
- cerr << "Exiting handlePoke()" << endl;
-#endif
-}
-
-bool
-suspend() {
- if (suspended) {
- return false;
- }
- // Before we suspend, we must take a snapshot of the loaded module
- // names and base addresses, since acquiring this snapshot requires
- // starting and exiting a thread in the remote process (at least on
- // NT 4).
- libs.clear();
-#ifdef DEBUGGING
- cerr << "Starting suspension" << endl;
-#endif
- libInfo(pid, libs);
-#ifdef DEBUGGING
- cerr << " Got lib info" << endl;
-#endif
- threads.lock();
-#ifdef DEBUGGING
- cerr << " Got thread lock" << endl;
-#endif
- suspended = true;
- int j = 0;
- for (int i = 0; i < threads.size(); i++) {
- j++;
- SuspendThread(threads.get(i).thread);
- }
-#ifdef DEBUGGING
- cerr << "Suspended " << j << " threads" << endl;
-#endif
- threads.unlock();
- return true;
-}
-
-bool
-resume() {
- if (!suspended) {
- return false;
- }
- threads.lock();
- suspended = false;
- for (int i = 0; i < threads.size(); i++) {
- ResumeThread(threads.get(i).thread);
- }
- threads.unlock();
-#ifdef DEBUGGING
- cerr << "Resumed process" << endl;
-#endif
- return true;
-}
-
-int
-main(int argc, char **argv)
-{
- if (argc != 2) {
- // Should only be used by performing CreateProcess within SwDbgSrv
- exit(1);
- }
-
- if (sscanf(argv[1], "%u", &pid) != 1) {
- exit(1);
- }
-
- // Try to attach to process
- if (!attachToProcess()) {
- // Attach failed. Notify parent by writing result to stdout file
- // handle.
- char res = 0;
- DWORD numBytes;
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), &res, sizeof(res),
- &numBytes, NULL);
- exit(1);
- }
-
- // Server is expecting success result back.
- char res = 1;
- DWORD numBytes;
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), &res, sizeof(res),
- &numBytes, NULL);
-
- // Initialize our I/O buffer
- ioBuf = new IOBuf(32768, 131072);
- ioBuf->setOutputFileHandle(GetStdHandle(STD_OUTPUT_HANDLE));
-
- // At this point we are attached. Enter our main loop which services
- // requests from the server. Note that in order to handle attach/
- // detach properly (i.e., resumption of process upon "detach") we
- // will need another thread which handles debug events.
- while (true) {
- // Read a message from the server
- Message msg;
- if (!readMessage(&msg)) {
- endProcess();
- }
-
-#ifdef DEBUGGING
- cerr << "Main thread read message: " << msg.type << endl;
-#endif
-
- switch (msg.type) {
- // ATTACH and DETACH messages MUST come in pairs
- case Message::ATTACH:
- suspend();
- eventLock->lock();
- generateDebugEvents = true;
- eventLock->unlock();
- break;
-
- case Message::DETACH:
- eventLock->lock();
- generateDebugEvents = false;
- // Flush remaining event if any
- if (curDebugEvent != NULL) {
- curDebugEvent = NULL;
- eventLock->notifyAll();
- }
- eventLock->unlock();
- resume();
- break;
-
- case Message::LIBINFO:
- {
- if (!suspended) {
- ioBuf->writeInt(0);
- } else {
- // Send back formatted text
- ioBuf->writeInt(libs.size());
- for (int i = 0; i < libs.size(); i++) {
- ioBuf->writeSpace();
- ioBuf->writeInt(1);
- ioBuf->writeSpace();
- ioBuf->writeInt(libs[i].name.size());
- ioBuf->writeSpace();
- ioBuf->writeString(libs[i].name.c_str());
- ioBuf->writeSpace();
- ioBuf->writeAddress(libs[i].base);
- }
- }
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
- }
-
- case Message::PEEK:
- handlePeek(&msg);
- break;
-
- case Message::POKE:
- handlePoke(&msg);
- break;
-
- case Message::THREADLIST:
- {
- if (!suspended) {
- ioBuf->writeInt(0);
- } else {
- threads.lock();
- ioBuf->writeInt(threads.size());
- for (int i = 0; i < threads.size(); i++) {
- ioBuf->writeSpace();
- ioBuf->writeAddress((void*) threads.get(i).thread);
- }
- threads.unlock();
- }
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
- }
-
- case Message::DUPHANDLE:
- {
- HANDLE dup;
- if (DuplicateHandle(procHandle,
- msg.handleArg.handle,
- GetCurrentProcess(),
- &dup,
- 0,
- FALSE,
- DUPLICATE_SAME_ACCESS)) {
- ioBuf->writeBoolAsInt(true);
- ioBuf->writeSpace();
- ioBuf->writeAddress((void*) dup);
- } else {
- ioBuf->writeBoolAsInt(false);
- }
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
- }
-
- case Message::CLOSEHANDLE:
- {
- CloseHandle(msg.handleArg.handle);
- break;
- }
-
- case Message::GETCONTEXT:
- {
- if (!suspended) {
- ioBuf->writeBoolAsInt(false);
- } else {
- CONTEXT context;
- context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
- if (GetThreadContext(msg.handleArg.handle, &context)) {
- ioBuf->writeBoolAsInt(true);
- // EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, DS, ES, FS, GS,
- // CS, SS, EFLAGS, DR0, DR1, DR2, DR3, DR6, DR7
- // See README-commands.txt
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Eax);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Ebx);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Ecx);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Edx);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Esi);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Edi);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Ebp);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Esp);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Eip);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegDs);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegEs);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegFs);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegGs);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegCs);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegSs);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.EFlags);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr0);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr1);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr2);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr3);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr6);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr7);
- } else {
- ioBuf->writeBoolAsInt(false);
- }
- }
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
- }
-
- case Message::SETCONTEXT:
- {
- if (!suspended) {
- ioBuf->writeBoolAsInt(false);
- } else {
- CONTEXT context;
- context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
- context.Eax = msg.setContextArg.Eax;
- context.Ebx = msg.setContextArg.Ebx;
- context.Ecx = msg.setContextArg.Ecx;
- context.Edx = msg.setContextArg.Edx;
- context.Esi = msg.setContextArg.Esi;
- context.Edi = msg.setContextArg.Edi;
- context.Ebp = msg.setContextArg.Ebp;
- context.Esp = msg.setContextArg.Esp;
- context.Eip = msg.setContextArg.Eip;
- context.SegDs = msg.setContextArg.Ds;
- context.SegEs = msg.setContextArg.Es;
- context.SegFs = msg.setContextArg.Fs;
- context.SegGs = msg.setContextArg.Gs;
- context.SegCs = msg.setContextArg.Cs;
- context.SegSs = msg.setContextArg.Ss;
- context.EFlags = msg.setContextArg.EFlags;
- context.Dr0 = msg.setContextArg.Dr0;
- context.Dr1 = msg.setContextArg.Dr1;
- context.Dr2 = msg.setContextArg.Dr2;
- context.Dr3 = msg.setContextArg.Dr3;
- context.Dr6 = msg.setContextArg.Dr6;
- context.Dr7 = msg.setContextArg.Dr7;
- if (SetThreadContext(msg.setContextArg.handle, &context)) {
- ioBuf->writeBoolAsInt(true);
- } else {
- ioBuf->writeBoolAsInt(false);
- }
- }
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
- }
-
- case Message::SELECTORENTRY:
- {
- LDT_ENTRY entry;
-
- if (GetThreadSelectorEntry(msg.selectorArg.handle,
- msg.selectorArg.selector,
- &entry)) {
- ioBuf->writeBoolAsInt(true);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.LimitLow);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.BaseLow);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.BaseMid);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.Flags1);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.Flags2);
- ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.BaseHi);
- } else {
- ioBuf->writeBoolAsInt(false);
- }
-
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
- }
-
- case Message::SUSPEND:
- suspend();
- break;
-
- case Message::RESUME:
- resume();
- break;
-
- case Message::POLLEVENT:
- eventLock->lock();
- if (curDebugEvent == NULL) {
- ioBuf->writeBoolAsInt(false);
- } else {
- ioBuf->writeBoolAsInt(true);
- ioBuf->writeSpace();
- threads.lock();
- ioBuf->writeAddress((void*) threads.threadIDToHandle(curDebugEvent->dwThreadId));
- threads.unlock();
- ioBuf->writeSpace();
- ioBuf->writeUnsignedInt(curDebugEvent->dwDebugEventCode);
- // Figure out what else to write
- switch (curDebugEvent->dwDebugEventCode) {
- case LOAD_DLL_DEBUG_EVENT:
- ioBuf->writeSpace();
- ioBuf->writeAddress(curDebugEvent->u.LoadDll.lpBaseOfDll);
- break;
-
- case UNLOAD_DLL_DEBUG_EVENT:
- ioBuf->writeSpace();
- ioBuf->writeAddress(curDebugEvent->u.UnloadDll.lpBaseOfDll);
- break;
-
- case EXCEPTION_DEBUG_EVENT:
- {
- DWORD code = curDebugEvent->u.Exception.ExceptionRecord.ExceptionCode;
- ioBuf->writeSpace();
- ioBuf->writeUnsignedInt(code);
- ioBuf->writeSpace();
- ioBuf->writeAddress(curDebugEvent->u.Exception.ExceptionRecord.ExceptionAddress);
- switch (curDebugEvent->u.Exception.ExceptionRecord.ExceptionCode) {
- case EXCEPTION_ACCESS_VIOLATION:
- ioBuf->writeSpace();
- ioBuf->writeBoolAsInt(curDebugEvent->u.Exception.ExceptionRecord.ExceptionInformation[0] != 0);
- ioBuf->writeSpace();
- ioBuf->writeAddress((void*) curDebugEvent->u.Exception.ExceptionRecord.ExceptionInformation[1]);
- break;
-
- default:
- break;
- }
- break;
- }
-
- default:
- break;
- }
- }
- eventLock->unlock();
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
-
- case Message::CONTINUEEVENT:
- eventLock->lock();
- if (curDebugEvent == NULL) {
- ioBuf->writeBoolAsInt(false);
- } else {
- curDebugEvent = NULL;
- passEventToClient = msg.boolArg.val;
- ioBuf->writeBoolAsInt(true);
- eventLock->notify();
- }
- eventLock->unlock();
- ioBuf->writeEOL();
- ioBuf->flush();
- break;
- }
- }
-
- endProcess();
-
- // NOT REACHED
- return 0;
-}
--- a/hotspot/agent/src/os/win32/SwDbgSub.dsp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-# Microsoft Developer Studio Project File - Name="SwDbgSub" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=SwDbgSub - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "SwDbgSub.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "SwDbgSub.mak" CFG="SwDbgSub - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "SwDbgSub - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "SwDbgSub - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "SwDbgSub - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF "$(CFG)" == "SwDbgSub - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "SwDbgSub___Win32_Debug"
-# PROP BASE Intermediate_Dir "SwDbgSub___Win32_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "SwDbgSub - Win32 Release"
-# Name "SwDbgSub - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\Buffer.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\IOBuf.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\isNT4.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\libInfo.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Monitor.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\nt4internals.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\SwDbgSub.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\toolHelp.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
--- a/hotspot/agent/src/os/win32/initWinsock.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <iostream>
-#include <winsock2.h>
-
-using namespace std;
-
-void
-initWinsock()
-{
- static int initted = 0;
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- if (!initted) {
- wVersionRequested = MAKEWORD( 2, 0 );
-
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- {
- /* Tell the user that we couldn't find a usable */
- /* WinSock DLL. */
- cerr << "SocketBase::SocketBase: unable to find usable "
- << "WinSock DLL" << endl;
- exit(1);
- }
- }
-
- /* Confirm that the WinSock DLL supports 2.0.*/
- /* Note that if the DLL supports versions greater */
- /* than 2.0 in addition to 2.0, it will still return */
- /* 2.0 in wVersion since that is the version we */
- /* requested. */
-
- if ( LOBYTE( wsaData.wVersion ) != 2 ||
- HIBYTE( wsaData.wVersion ) != 0 ) {
- /* Tell the user that we couldn't find a usable */
- /* WinSock DLL. */
- {
- cerr << "Unable to find suitable version of WinSock DLL" << endl;
- WSACleanup( );
- exit(1);
- }
- }
-
- initted = 1;
- }
-}
--- a/hotspot/agent/src/os/win32/initWinsock.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _INIT_WINSOCK_
-#define _INIT_WINSOCK_
-
-void initWinsock();
-
-#endif // #defined _INIT_WINSOCK_
--- a/hotspot/agent/src/os/win32/ioUtils.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <ctype.h>
-#include <string.h>
-#include "ioUtils.hpp"
-#include "IOBuf.hpp"
-
-bool
-scanInt(char** data, int* num) {
- *num = 0;
-
- // Skip whitespace
- while ((**data != 0) && (isspace(**data))) {
- ++*data;
- }
-
- if (**data == 0) {
- return false;
- }
-
- while ((**data != 0) && (!isspace(**data))) {
- char cur = **data;
- if ((cur < '0') || (cur > '9')) {
- return false;
- }
- *num *= 10;
- *num += cur - '0';
- ++*data;
- }
-
- return true;
-}
-
-bool
-scanUnsignedLong(char** data, unsigned long* num) {
- *num = 0;
-
- // Skip whitespace
- while ((**data != 0) && (isspace(**data))) {
- ++*data;
- }
-
- if (**data == 0) {
- return false;
- }
-
- while ((**data != 0) && (!isspace(**data))) {
- char cur = **data;
- if ((cur < '0') || (cur > '9')) {
- return false;
- }
- *num *= 10;
- *num += cur - '0';
- ++*data;
- }
-
- return true;
-}
-
-bool
-charToNibble(char ascii, int* value) {
- if (ascii >= '0' && ascii <= '9') {
- *value = ascii - '0';
- return true;
- } else if (ascii >= 'A' && ascii <= 'F') {
- *value = 10 + ascii - 'A';
- return true;
- } else if (ascii >= 'a' && ascii <= 'f') {
- *value = 10 + ascii - 'a';
- return true;
- }
-
- return false;
-}
-
-bool
-scanAddress(char** data, unsigned long* addr) {
- *addr = 0;
-
- // Skip whitespace
- while ((**data != 0) && (isspace(**data))) {
- ++*data;
- }
-
- if (**data == 0) {
- return false;
- }
-
- if (strncmp(*data, "0x", 2) != 0) {
- return false;
- }
-
- *data += 2;
-
- while ((**data != 0) && (!isspace(**data))) {
- int val;
- bool res = charToNibble(**data, &val);
- if (!res) {
- return false;
- }
- *addr <<= 4;
- *addr |= val;
- ++*data;
- }
-
- return true;
-}
-
-bool
-scanAndSkipBinEscapeChar(char** data) {
- // Skip whitespace
- while ((**data != 0) && (isspace(**data))) {
- ++*data;
- }
-
- if (!IOBuf::isBinEscapeChar(**data)) {
- return false;
- }
-
- ++*data;
-
- return true;
-}
-
-bool
-scanBinUnsignedLong(char** data, unsigned long* num) {
- *num = 0;
- for (int i = 0; i < 4; i++) {
- unsigned char val = (unsigned char) **data;
- *num = (*num << 8) | val;
- ++*data;
- }
- return true;
-}
--- a/hotspot/agent/src/os/win32/ioUtils.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _IO_UTILS_
-#define _IO_UTILS_
-
-bool scanInt(char** data, int* num);
-bool scanUnsignedLong(char** data, unsigned long* num);
-bool scanAddress(char** data, unsigned long* addr);
-
-// Binary utils (for poke)
-bool scanAndSkipBinEscapeChar(char** data);
-bool scanBinUnsignedLong(char** data, unsigned long* num);
-
-#endif // #defined _IO_UTILS_
--- a/hotspot/agent/src/os/win32/isNT4.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "isNT4.hpp"
-#include <windows.h>
-
-bool
-isNT4() {
- OSVERSIONINFO info;
- info.dwOSVersionInfoSize = sizeof(info);
-
- if (!GetVersionEx(&info)) {
- return false;
- }
-
- return ((info.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
- (info.dwMajorVersion == 4));
-}
--- a/hotspot/agent/src/os/win32/isNT4.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _ISNT4_H_
-#define _ISNT4_H_
-
-// We need to special-case the Windows NT 4.0 implementations of some
-// of the debugging routines because the Tool Help API is not
-// available on this platform.
-
-bool isNT4();
-
-#endif // #defined _ISNT4_H_
--- a/hotspot/agent/src/os/win32/libInfo.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-// Disable too-long symbol warnings
-#pragma warning ( disable : 4786 )
-
-#include "libInfo.hpp"
-#include "nt4internals.hpp"
-#include "isNT4.hpp"
-#include "toolHelp.hpp"
-#include <assert.h>
-
-using namespace std;
-
-typedef void LibInfoImplFunc(DWORD pid, vector<LibInfo>& info);
-
-static void libInfoImplNT4(DWORD pid, vector<LibInfo>& info);
-static void libInfoImplToolHelp(DWORD pid, vector<LibInfo>& info);
-
-void
-libInfo(DWORD pid, vector<LibInfo>& info) {
- static LibInfoImplFunc* impl = NULL;
-
- if (impl == NULL) {
- // See which operating system we're on
- impl = (isNT4() ? &libInfoImplNT4 : &libInfoImplToolHelp);
- }
-
- assert(impl != NULL);
-
- (*impl)(pid, info);
-}
-
-static ULONG
-ModuleCount(NT4::PDEBUG_BUFFER db) {
- return db->ModuleInformation ? *PULONG(db->ModuleInformation) : 0;
-}
-
-#define MAX2(a, b) (((a) < (b)) ? (b) : (a))
-
-static void
-libInfoImplNT4(DWORD pid, vector<LibInfo>& info) {
- static EnumProcessModulesFunc* enumFunc = NULL;
- static GetModuleFileNameExFunc* fnFunc = NULL;
- static GetModuleInformationFunc* infoFunc = NULL;
-
- if (enumFunc == NULL) {
- HMODULE dll = loadPSAPIDLL();
-
- enumFunc = (EnumProcessModulesFunc*) GetProcAddress(dll, "EnumProcessModules");
- fnFunc = (GetModuleFileNameExFunc*) GetProcAddress(dll, "GetModuleFileNameExA");
- infoFunc = (GetModuleInformationFunc*) GetProcAddress(dll, "GetModuleInformation");
-
- assert(enumFunc != NULL);
- assert(fnFunc != NULL);
- assert(infoFunc != NULL);
- }
-
- static HMODULE* mods = new HMODULE[256];
- static int numMods = 256;
-
- if (mods == NULL) {
- mods = new HMODULE[numMods];
- if (mods == NULL) {
- return;
- }
- }
-
- bool done = false;
-
- HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
- if (proc == NULL) {
- return;
- }
-
- do {
- DWORD bufSize = numMods * sizeof(HMODULE);
- DWORD neededSize;
-
- if (!(*enumFunc)(proc, mods, bufSize, &neededSize)) {
- // Enum failed
- CloseHandle(proc);
- return;
- }
-
- int numFetched = neededSize / sizeof(HMODULE);
-
- if (numMods < numFetched) {
- // Grow buffer
- numMods = MAX2(numFetched, 2 * numMods);
- delete[] mods;
- mods = new HMODULE[numMods];
- if (mods == NULL) {
- CloseHandle(proc);
- return;
- }
- } else {
- char filename[MAX_PATH];
- MODULEINFO modInfo;
-
- // Iterate through and fetch each one's info
- for (int i = 0; i < numFetched; i++) {
- if (!(*fnFunc)(proc, mods[i], filename, MAX_PATH)) {
- CloseHandle(proc);
- return;
- }
-
- if (!(*infoFunc)(proc, mods[i], &modInfo, sizeof(MODULEINFO))) {
- CloseHandle(proc);
- return;
- }
-
- info.push_back(LibInfo(string(filename), (void*) modInfo.lpBaseOfDll));
- }
-
- done = true;
- }
- } while (!done);
-
- CloseHandle(proc);
- return;
-}
-
-void
-libInfoImplToolHelp(DWORD pid, vector<LibInfo>& info) {
- using namespace ToolHelp;
-
- static CreateToolhelp32SnapshotFunc* snapshotFunc = NULL;
- static Module32FirstFunc* firstFunc = NULL;
- static Module32NextFunc* nextFunc = NULL;
-
- if (snapshotFunc == NULL) {
- HMODULE dll = loadDLL();
-
- snapshotFunc =
- (CreateToolhelp32SnapshotFunc*) GetProcAddress(dll,
- "CreateToolhelp32Snapshot");
-
- firstFunc = (Module32FirstFunc*) GetProcAddress(dll,
- "Module32First");
-
- nextFunc = (Module32NextFunc*) GetProcAddress(dll,
- "Module32Next");
-
- assert(snapshotFunc != NULL);
- assert(firstFunc != NULL);
- assert(nextFunc != NULL);
- }
-
- HANDLE snapshot = (*snapshotFunc)(TH32CS_SNAPMODULE, pid);
- if (snapshot == (HANDLE) -1) {
- // Error occurred during snapshot
- return;
- }
-
- // Iterate
- MODULEENTRY32 module;
- if ((*firstFunc)(snapshot, &module)) {
- do {
- info.push_back(LibInfo(string(module.szExePath), (void*) module.modBaseAddr));
- } while ((*nextFunc)(snapshot, &module));
- }
-
- CloseHandle(snapshot);
-}
--- a/hotspot/agent/src/os/win32/libInfo.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _LIBINFO_
-#define _LIBINFO_
-
-#include <vector>
-#include <string>
-#include <windows.h>
-
-struct LibInfo {
- std::string name;
- void* base;
-
- LibInfo(const std::string& name, void* base) {
- this->name = name;
- this->base = base;
- }
-};
-
-void libInfo(DWORD pid, std::vector<LibInfo>& info);
-
-#endif // #defined _LIBINFO_
--- a/hotspot/agent/src/os/win32/nt4internals.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "nt4internals.hpp"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-namespace NT4 {
-
-static HMODULE ntDLL = NULL;
-
-HMODULE loadNTDLL() {
- if (ntDLL == NULL) {
- ntDLL = LoadLibrary("NTDLL.DLL");
- }
-
- assert(ntDLL != NULL);
- return ntDLL;
-}
-
-void unloadNTDLL() {
- if (ntDLL != NULL) {
- FreeLibrary(ntDLL);
- ntDLL = NULL;
- }
-}
-
-} // namespace NT4
-
-static HMODULE psapiDLL = NULL;
-
-HMODULE
-loadPSAPIDLL() {
- if (psapiDLL == NULL) {
- psapiDLL = LoadLibrary("PSAPI.DLL");
- }
-
- if (psapiDLL == NULL) {
- fprintf(stderr, "Simple Windows Debug Server requires PSAPI.DLL on Windows NT 4.0.\n");
- fprintf(stderr, "Please install this DLL from the SDK and restart the server.\n");
- exit(1);
- }
-
- return psapiDLL;
-}
-
-void
-unloadPSAPIDLL() {
- if (psapiDLL != NULL) {
- FreeLibrary(psapiDLL);
- psapiDLL = NULL;
- }
-}
--- a/hotspot/agent/src/os/win32/nt4internals.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _NT4INTERNALS_H_
-#define _NT4INTERNALS_H_
-
-#include <windows.h>
-
-namespace NT4 {
-extern "C" {
-
-// Data structures and constants required to be able to get necessary
-// debugging-related information on Windows NT 4.0 through internal
-// (i.e., non-public) APIs. These are adapted from those in the
-// _Windows NT/2000 Native API Reference_ by Gary Nebbett, Macmillan
-// Technical Publishing, 201 West 103rd Street, Indianapolis, IN
-// 46290, 2000.
-
-typedef LONG NTSTATUS;
-typedef LONG KPRIORITY;
-
-#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
-#define NTAPI __stdcall
-#else
-#define _cdecl
-#define NTAPI
-#endif
-
-#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
-
-typedef enum _SYSTEM_INFORMATION_CLASS {
- SystemProcessesAndThreadsInformation = 5
-} SYSTEM_INFORMATION_CLASS;
-
-typedef struct _UNICODE_STRING {
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
-} UNICODE_STRING;
-
-typedef struct _VM_COUNTERS {
- ULONG PeakVirtualSize;
- ULONG VirtualSize;
- ULONG PageFaultCount;
- ULONG PeakWorkingSetSize;
- ULONG WorkingSetSize;
- ULONG QuotaPeakPagedPoolUsage;
- ULONG QuotaPagedPoolUsage;
- ULONG QuotaPeakNonPagedPoolUsage;
- ULONG QuotaNonPagedPoolUsage;
- ULONG PagefileUsage;
- ULONG PeakPagefileUsage;
-} VM_COUNTERS, *PVM_COUNTERS;
-
-typedef struct _IO_COUNTERS {
- LARGE_INTEGER ReadOperationCount;
- LARGE_INTEGER WriteOperationCount;
- LARGE_INTEGER OtherOperationCount;
- LARGE_INTEGER ReadTransferCount;
- LARGE_INTEGER WriteTransferCount;
- LARGE_INTEGER OtherTransferCount;
-} IO_COUNTERS, *PIO_COUNTERS;
-
-typedef struct _CLIENT_ID {
- HANDLE UniqueProcess;
- HANDLE UniqueThread;
-} CLIENT_ID, *PCLIENT_ID;
-
-typedef enum {
- StateInitialized,
- StateReady,
- StateRunning,
- StateStandby,
- StateTerminated,
- StateWait,
- StateTransition,
- StateUnknown
-} THREAD_STATE;
-
-typedef enum {
- Executive,
- FreePage,
- PageIn,
- PoolAllocation,
- DelayExecution,
- Suspended,
- UserRequest,
- WrExecutive,
- WrFreePage,
- WrPageIn,
- WrPoolAllocation,
- WrDelayExecution,
- WrSuspended,
- WrUserRequest,
- WrEventPair,
- WrQueue,
- WrLpcReceive,
- WrLpcReply,
- WrVirtualMemory,
- WrPageOut,
- WrRendezvous,
- Spare2,
- Spare3,
- Spare4,
- Spare5,
- Spare6,
- WrKernel
-} KWAIT_REASON;
-
-typedef struct _SYSTEM_THREADS {
- LARGE_INTEGER KernelTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER CreateTime;
- ULONG WaitTime;
- PVOID StartAddress;
- CLIENT_ID ClientId;
- KPRIORITY Priority;
- KPRIORITY BasePriority;
- ULONG ContextSwitchCount;
- THREAD_STATE State;
- KWAIT_REASON WaitReason;
-} SYSTEM_THREADS, *PSYSTEM_THREADS;
-
-typedef struct _SYSTEM_PROCESSES { // Information class 5
- ULONG NextEntryDelta;
- ULONG ThreadCount;
- ULONG Reserved1[6];
- LARGE_INTEGER CreateTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER KernelTime;
- UNICODE_STRING ProcessName;
- KPRIORITY BasePriority;
- ULONG ProcessId;
- ULONG InheritedFromProcessId;
- ULONG HandleCount;
- ULONG Reserved2[2];
- ULONG PrivatePageCount;
- VM_COUNTERS VmCounters;
- IO_COUNTERS IoCounters; // Windows 2000 only
- SYSTEM_THREADS Threads[1];
-} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
-
-typedef NTSTATUS NTAPI
-ZwQuerySystemInformationFunc(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
- IN OUT PVOID SystemInformation,
- IN ULONG SystemInformationLength,
- OUT PULONG ReturnLength OPTIONAL
- );
-
-typedef struct _DEBUG_BUFFER {
- HANDLE SectionHandle;
- PVOID SectionBase;
- PVOID RemoteSectionBase;
- ULONG SectionBaseDelta;
- HANDLE EventPairHandle;
- ULONG Unknown[2];
- HANDLE RemoteThreadHandle;
- ULONG InfoClassMask;
- ULONG SizeOfInfo;
- ULONG AllocatedSize;
- ULONG SectionSize;
- PVOID ModuleInformation;
- PVOID BackTraceInformation;
- PVOID HeapInformation;
- PVOID LockInformation;
- PVOID Reserved[8];
-} DEBUG_BUFFER, *PDEBUG_BUFFER;
-
-typedef PDEBUG_BUFFER NTAPI
-RtlCreateQueryDebugBufferFunc(IN ULONG Size,
- IN BOOLEAN EventPair);
-
-#define PDI_MODULES 0x01 // The loaded modules of the process
-#define PDI_BACKTRACE 0x02 // The heap stack back traces
-#define PDI_HEAPS 0x04 // The heaps of the process
-#define PDI_HEAP_TAGS 0x08 // The heap tags
-#define PDI_HEAP_BLOCKS 0x10 // The heap blocks
-#define PDI_LOCKS 0x20 // The locks created by the process
-
-typedef struct _DEBUG_MODULE_INFORMATION { // c.f. SYSTEM_MODULE_INFORMATION
- ULONG Reserved[2];
- ULONG Base;
- ULONG Size;
- ULONG Flags;
- USHORT Index;
- USHORT Unknown;
- USHORT LoadCount;
- USHORT ModuleNameOffset;
- CHAR ImageName[256];
-} DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;
-
-// Flags
-#define LDRP_STATIC_LINK 0x00000002
-#define LDRP_IMAGE_DLL 0x00000004
-#define LDRP_LOAD_IN_PROGRESS 0x00001000
-#define LDRP_UNLOAD_IN_PROGRESS 0x00002000
-#define LDRP_ENTRY_PROCESSED 0x00004000
-#define LDRP_ENTRY_INSERTED 0x00008000
-#define LDRP_CURRENT_LOAD 0x00010000
-#define LDRP_FAILED_BUILTIN_LOAD 0x00020000
-#define LDRP_DONT_CALL_FOR_THREADS 0x00040000
-#define LDRP_PROCESS_ATTACH_CALLED 0x00080000
-#define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000
-#define LDRP_IMAGE_NOT_AT_BASE 0x00200000
-#define LDRP_WX86_IGNORE_MACHINETYPE 0x00400000
-
-// NOTE that this will require creating a thread in the target
-// process, implying that we can not call this while the process is
-// suspended. May have to run this command in the child processes
-// rather than the server.
-
-typedef NTSTATUS NTAPI
-RtlQueryProcessDebugInformationFunc(IN ULONG ProcessId,
- IN ULONG DebugInfoClassMask,
- IN OUT PDEBUG_BUFFER DebugBuffer);
-
-typedef NTSTATUS NTAPI
-RtlDestroyQueryDebugBufferFunc(IN PDEBUG_BUFFER DebugBuffer);
-
-// Routines to load and unload NTDLL.DLL.
-HMODULE loadNTDLL();
-// Safe to call even if has not been loaded
-void unloadNTDLL();
-
-} // extern "C"
-} // namespace NT4
-
-//----------------------------------------------------------------------
-
-// On NT 4 only, we now use PSAPI to enumerate the loaded modules in
-// the target processes. RtlQueryProcessDebugInformation creates a
-// thread in the target process, which causes problems when we are
-// handling events like breakpoints in the debugger. The dependence on
-// an external DLL which might not be present is unfortunate, but we
-// can either redistribute this DLL (if allowed) or refuse to start on
-// NT 4 if it is not present.
-
-typedef struct _MODULEINFO {
- LPVOID lpBaseOfDll;
- DWORD SizeOfImage;
- LPVOID EntryPoint;
-} MODULEINFO, *LPMODULEINFO;
-
-typedef BOOL (WINAPI EnumProcessModulesFunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
-typedef DWORD (WINAPI GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
-typedef BOOL (WINAPI GetModuleInformationFunc)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
-// Routines to load and unload PSAPI.DLL.
-HMODULE loadPSAPIDLL();
-// Safe to call even if has not been loaded
-void unloadPSAPIDLL();
-
-#endif // #defined _NT4INTERNALS_H_
--- a/hotspot/agent/src/os/win32/ports.h Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _PORTS_H_
-#define _PORTS_H_
-
-// This is the "public" port which end-user clients can connect to
-// with an arbitrary application, including telnet.
-const short CLIENT_PORT = 27000;
-
-#endif // #defined _PORTS_H_
--- a/hotspot/agent/src/os/win32/procList.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "procList.hpp"
-#include "nt4internals.hpp"
-#include "isNT4.hpp"
-#include "toolHelp.hpp"
-#include <assert.h>
-
-using namespace std;
-using namespace NT4;
-
-typedef void ProcListImplFunc(ProcEntryList& processes);
-
-void procListImplNT4(ProcEntryList& processes);
-void procListImplToolHelp(ProcEntryList& processes);
-
-ProcEntry::ProcEntry(ULONG pid, USHORT nameLength, WCHAR* name) {
- this->pid = pid;
- this->nameLength = nameLength;
- this->name = new WCHAR[nameLength];
- memcpy(this->name, name, nameLength * sizeof(WCHAR));
-}
-
-ProcEntry::ProcEntry(ULONG pid, USHORT nameLength, char* name) {
- this->pid = pid;
- this->nameLength = nameLength;
- this->name = new WCHAR[nameLength];
- int j = 0;
- for (int i = 0; i < nameLength; i++) {
- // FIXME: what is the proper promotion from ASCII to UNICODE?
- this->name[i] = name[i] & 0xFF;
- }
-}
-
-ProcEntry::ProcEntry(const ProcEntry& arg) {
- name = NULL;
- copyFrom(arg);
-}
-
-ProcEntry&
-ProcEntry::operator=(const ProcEntry& arg) {
- copyFrom(arg);
- return *this;
-}
-
-ProcEntry::~ProcEntry() {
- delete[] name;
-}
-
-void
-ProcEntry::copyFrom(const ProcEntry& arg) {
- if (name != NULL) {
- delete[] name;
- }
- pid = arg.pid;
- nameLength = arg.nameLength;
- name = new WCHAR[nameLength];
- memcpy(name, arg.name, nameLength * sizeof(WCHAR));
-}
-
-ULONG
-ProcEntry::getPid() {
- return pid;
-}
-
-USHORT
-ProcEntry::getNameLength() {
- return nameLength;
-}
-
-WCHAR*
-ProcEntry::getName() {
- return name;
-}
-
-void
-procList(ProcEntryList& processes) {
- static ProcListImplFunc* impl = NULL;
-
- if (impl == NULL) {
- // See which operating system we're on
- impl = (isNT4() ? &procListImplNT4 : &procListImplToolHelp);
- }
-
- assert(impl != NULL);
-
- (*impl)(processes);
-}
-
-void
-procListImplNT4(ProcEntryList& processes) {
- using namespace NT4;
-
- static ZwQuerySystemInformationFunc* query = NULL;
-
- if (query == NULL) {
- HMODULE ntDLL = loadNTDLL();
- query =
- (ZwQuerySystemInformationFunc*) GetProcAddress(ntDLL,
- "ZwQuerySystemInformation");
- assert(query != NULL);
- }
-
- ULONG n = 0x100;
- PSYSTEM_PROCESSES sp = new SYSTEM_PROCESSES[n];
- while ((*query)(SystemProcessesAndThreadsInformation,
- sp, n * sizeof(SYSTEM_PROCESSES), 0) == STATUS_INFO_LENGTH_MISMATCH) {
- delete[] sp;
- n *= 2;
- sp = new SYSTEM_PROCESSES[n];
- }
-
- bool done = false;
- for (PSYSTEM_PROCESSES p = sp; !done;
- p = PSYSTEM_PROCESSES(PCHAR(p) + p->NextEntryDelta)) {
- processes.push_back(ProcEntry(p->ProcessId,
- p->ProcessName.Length / 2,
- p->ProcessName.Buffer));
- done = p->NextEntryDelta == 0;
- }
-}
-
-void
-procListImplToolHelp(ProcEntryList& processes) {
- using namespace ToolHelp;
-
- static CreateToolhelp32SnapshotFunc* snapshotFunc = NULL;
- static Process32FirstFunc* firstFunc = NULL;
- static Process32NextFunc* nextFunc = NULL;
-
- if (snapshotFunc == NULL) {
- HMODULE dll = loadDLL();
-
- snapshotFunc =
- (CreateToolhelp32SnapshotFunc*) GetProcAddress(dll,
- "CreateToolhelp32Snapshot");
-
- firstFunc = (Process32FirstFunc*) GetProcAddress(dll,
- "Process32First");
-
- nextFunc = (Process32NextFunc*) GetProcAddress(dll,
- "Process32Next");
-
- assert(snapshotFunc != NULL);
- assert(firstFunc != NULL);
- assert(nextFunc != NULL);
- }
-
- HANDLE snapshot = (*snapshotFunc)(TH32CS_SNAPPROCESS, 0 /* ignored */);
- if (snapshot == (HANDLE) -1) {
- // Error occurred during snapshot
- return;
- }
-
- // Iterate
- PROCESSENTRY32 proc;
- if ((*firstFunc)(snapshot, &proc)) {
- do {
- // FIXME: could make this uniform to the NT version by cutting
- // off the path name just before the executable name
- processes.push_back(ProcEntry(proc.th32ProcessID,
- strlen(proc.szExeFile),
- proc.szExeFile));
- } while ((*nextFunc)(snapshot, &proc));
- }
-
- CloseHandle(snapshot);
-}
--- a/hotspot/agent/src/os/win32/procList.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _PROCLIST_
-#define _PROCLIST_
-
-#include <windows.h>
-#include <vector>
-
-class ProcEntry {
-public:
- /** name may not be NULL */
- ProcEntry(ULONG pid, USHORT nameLength, wchar_t* name);
- ProcEntry(ULONG pid, USHORT nameLength, char* name);
- ~ProcEntry();
- ProcEntry(const ProcEntry& arg);
- ProcEntry& operator=(const ProcEntry& arg);
-
- ULONG getPid();
- /** Returns number of WCHAR characters in getName() */
- USHORT getNameLength();
- WCHAR* getName();
-
-private:
- ULONG pid;
- USHORT nameLength;
- WCHAR* name;
- void copyFrom(const ProcEntry& arg);
-};
-
-typedef std::vector<ProcEntry> ProcEntryList;
-void procList(ProcEntryList& processes);
-
-#endif // #defined _PROCLIST_
--- a/hotspot/agent/src/os/win32/serverLists.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include <assert.h>
-#include "serverLists.hpp"
-
-//----------------------------------------------------------------------
-// Lists
-//
-
-CRITICAL_SECTION Lists::crit;
-
-void
-Lists::init() {
- InitializeCriticalSection(&crit);
-}
-
-void
-Lists::lock() {
- EnterCriticalSection(&crit);
-}
-
-void
-Lists::unlock() {
- LeaveCriticalSection(&crit);
-}
-
-//----------------------------------------------------------------------
-// ListsLocker
-//
-
-ListsLocker::ListsLocker() {
- Lists::lock();
-}
-
-ListsLocker::~ListsLocker() {
- Lists::unlock();
-}
-
-//----------------------------------------------------------------------
-// ChildInfo
-//
-
-ChildInfo::ChildInfo(DWORD pid, HANDLE childProcessHandle,
- HANDLE writeToStdinHandle, HANDLE readFromStdoutHandle,
- HANDLE auxHandle1, HANDLE auxHandle2) {
- this->pid = pid;
- this->childProcessHandle = childProcessHandle;
- this->writeToStdinHandle = writeToStdinHandle;
- this->readFromStdoutHandle = readFromStdoutHandle;
- this->auxHandle1 = auxHandle1;
- this->auxHandle2 = auxHandle2;
- client = NULL;
-}
-
-DWORD
-ChildInfo::getPid() {
- return pid;
-}
-
-HANDLE
-ChildInfo::getChildProcessHandle() {
- return childProcessHandle;
-}
-
-HANDLE
-ChildInfo::getWriteToStdinHandle() {
- return writeToStdinHandle;
-}
-
-HANDLE
-ChildInfo::getReadFromStdoutHandle() {
- return readFromStdoutHandle;
-}
-
-void
-ChildInfo::setClient(ClientInfo* clientInfo) {
- client = clientInfo;
-}
-
-ClientInfo*
-ChildInfo::getClient() {
- return client;
-}
-
-void
-ChildInfo::closeAll() {
- CloseHandle(childProcessHandle);
- CloseHandle(writeToStdinHandle);
- CloseHandle(readFromStdoutHandle);
- CloseHandle(auxHandle1);
- CloseHandle(auxHandle2);
-}
-
-//----------------------------------------------------------------------
-// ChildList
-//
-
-ChildList::ChildList() {
-}
-
-ChildList::~ChildList() {
-}
-
-void
-ChildList::addChild(ChildInfo* info) {
- // Could store these in binary sorted order by pid for efficiency
- childList.push_back(info);
-}
-
-ChildInfo*
-ChildList::removeChild(HANDLE childProcessHandle) {
- for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
- iter++) {
- ChildInfo* info = *iter;
- if (info->getChildProcessHandle() == childProcessHandle) {
- childList.erase(iter);
- return info;
- }
- }
- assert(false);
- return NULL;
-}
-
-void
-ChildList::removeChild(ChildInfo* info) {
- for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
- iter++) {
- if (*iter == info) {
- childList.erase(iter);
- return;
- }
- }
- assert(false);
-}
-
-ChildInfo*
-ChildList::getChildByPid(DWORD pid) {
- for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
- iter++) {
- ChildInfo* info = *iter;
- if (info->getPid() == pid) {
- return info;
- }
- }
- return NULL;
-}
-
-int
-ChildList::size() {
- return childList.size();
-}
-
-ChildInfo*
-ChildList::getChildByIndex(int index) {
- return childList[index];
-}
-
-//----------------------------------------------------------------------
-// ClientInfo
-//
-
-ClientInfo::ClientInfo(SOCKET dataSocket) {
- this->dataSocket = dataSocket;
- buf = new IOBuf(32768, 131072);
- buf->setSocket(dataSocket);
- target = NULL;
-}
-
-ClientInfo::~ClientInfo() {
- delete buf;
-}
-
-SOCKET
-ClientInfo::getDataSocket() {
- return dataSocket;
-}
-
-IOBuf*
-ClientInfo::getIOBuf() {
- return buf;
-}
-
-void
-ClientInfo::setTarget(ChildInfo* childInfo) {
- target = childInfo;
-}
-
-ChildInfo*
-ClientInfo::getTarget() {
- return target;
-}
-
-void
-ClientInfo::closeAll() {
- shutdown(dataSocket, SD_BOTH);
- closesocket(dataSocket);
- dataSocket = INVALID_SOCKET;
-}
-
-//----------------------------------------------------------------------
-// ClientList
-//
-
-ClientList::ClientList() {
-}
-
-ClientList::~ClientList() {
-}
-
-void
-ClientList::addClient(ClientInfo* info) {
- clientList.push_back(info);
-}
-
-bool
-ClientList::isAnyDataSocketSet(fd_set* fds, ClientInfo** out) {
- for (ClientInfoList::iterator iter = clientList.begin(); iter != clientList.end();
- iter++) {
- ClientInfo* info = *iter;
- if (FD_ISSET(info->getDataSocket(), fds)) {
- *out = info;
- return true;
- }
- }
- return false;
-}
-
-void
-ClientList::removeClient(ClientInfo* client) {
- for (ClientInfoList::iterator iter = clientList.begin(); iter != clientList.end();
- iter++) {
- if (*iter == client) {
- clientList.erase(iter);
- return;
- }
- }
- assert(false);
-}
-
-int
-ClientList::size() {
- return clientList.size();
-}
-
-ClientInfo*
-ClientList::get(int num) {
- return clientList[num];
-}
--- a/hotspot/agent/src/os/win32/serverLists.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _SERVER_LISTS_
-#define _SERVER_LISTS_
-
-#include <vector>
-#include <winsock2.h>
-#include "IOBuf.hpp"
-
-//
-// NOTE:
-//
-// All of these lists are guarded by the global lock managed by the
-// Lists class. Lists::init() must be called at the start of the
-// program.
-//
-
-class Lists {
- friend class ListsLocker;
-public:
- static void init();
-private:
- static void lock();
- static void unlock();
- static CRITICAL_SECTION crit;
-};
-
-// Should be allocated on stack. Ensures proper locking/unlocking
-// pairing.
-class ListsLocker {
-public:
- ListsLocker();
- ~ListsLocker();
-};
-
-// We must keep track of all of the child processes we have forked to
-// handle attaching to a target process. This is necessary because we
-// allow clients to detach from processes, but the child processes we
-// fork must necessarily stay alive for the duration of the target
-// application. A subsequent attach operation to the target process
-// results in the same child process being reused. For this reason,
-// child processes are known to be in one of two states: attached and
-// detached.
-
-class ClientInfo;
-
-class ChildInfo {
-public:
- /** The pid of the ChildInfo indicates the process ID of the target
- process which the subprocess was created to debug, not the pid
- of the subprocess itself. */
- ChildInfo(DWORD pid, HANDLE childProcessHandle,
- HANDLE writeToStdinHandle, HANDLE readFromStdoutHandle,
- HANDLE auxHandle1, HANDLE auxHandle2);
-
- DWORD getPid();
- HANDLE getChildProcessHandle();
- HANDLE getWriteToStdinHandle();
- HANDLE getReadFromStdoutHandle();
-
- /** Set the client which is currently attached to the target process
- via this child process. Set this to NULL to indicate that the
- child process is ready to accept another attachment. */
- void setClient(ClientInfo* clientInfo);
-
- ClientInfo* getClient();
-
- /** This is NOT automatically called in the destructor */
- void closeAll();
-
-private:
- DWORD pid;
- HANDLE childProcessHandle;
- HANDLE writeToStdinHandle;
- HANDLE readFromStdoutHandle;
- HANDLE auxHandle1;
- HANDLE auxHandle2;
- ClientInfo* client;
-};
-
-// We keep track of a list of child debugger processes, each of which
-// is responsible for debugging a certain target process. These
-// debugger processes can serve multiple clients during their
-// lifetime. When a client detaches from a given process or tells the
-// debugger to "exit", the debug server is notified that the child
-// process is once again available to accept connections from clients.
-
-class ChildList {
-private:
- typedef std::vector<ChildInfo*> ChildInfoList;
-
-public:
- ChildList();
- ~ChildList();
-
- void addChild(ChildInfo*);
-
- /** Removes and returns the ChildInfo* associated with the given
- child process handle. */
- ChildInfo* removeChild(HANDLE childProcessHandle);
-
- /** Removes the given ChildInfo. */
- void removeChild(ChildInfo* info);
-
- /** Return the ChildInfo* associated with a given process ID without
- removing it from the list. */
- ChildInfo* getChildByPid(DWORD pid);
-
- /** Iteration support */
- int size();
-
- /** Iteration support */
- ChildInfo* getChildByIndex(int index);
-
-private:
- ChildInfoList childList;
-};
-
-// We also keep a list of clients whose requests we are responsible
-// for serving. Clients can attach and detach from child processes.
-
-class ClientInfo {
-public:
- ClientInfo(SOCKET dataSocket);
- ~ClientInfo();
-
- SOCKET getDataSocket();
- /** Gets an IOBuf configured for the data socket, which should be
- used for all communication with the client. */
- IOBuf* getIOBuf();
-
- /** Set the information for the process to which this client is
- attached. Set this to NULL to indicate that the client is not
- currently attached to any target process. */
- void setTarget(ChildInfo* childInfo);
-
- /** Get the information for the process to which this client is
- currently attached, or NULL if none. */
- ChildInfo* getTarget();
-
- /** Close down the socket connection to this client. This is NOT
- automatically called by the destructor. */
- void closeAll();
-
-private:
- SOCKET dataSocket;
- IOBuf* buf;
- ChildInfo* target;
-};
-
-class ClientList {
-private:
- typedef std::vector<ClientInfo*> ClientInfoList;
-
-public:
- ClientList();
- ~ClientList();
-
- /** Adds a client to the list. */
- void addClient(ClientInfo* info);
-
- /** Check to see whether the parent socket of any of the ClientInfo
- objects is readable in the given fd_set. If so, returns TRUE and
- sets the given ClientInfo* (a non-NULL pointer to which must be
- given) appropriately. */
- bool isAnyDataSocketSet(fd_set* fds, ClientInfo** info);
-
- /** Removes a client from the list. User is responsible for deleting
- the ClientInfo* using operator delete. */
- void removeClient(ClientInfo* client);
-
- /** Iteration support. */
- int size();
-
- /** Iteration support. */
- ClientInfo* get(int num);
-
-private:
- ClientInfoList clientList;
-};
-
-#endif // #defined _SERVER_LISTS_
--- a/hotspot/agent/src/os/win32/toolHelp.cpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "toolHelp.hpp"
-#include <assert.h>
-
-namespace ToolHelp {
-
-static HMODULE kernelDLL = NULL;
-
-HMODULE loadDLL() {
- if (kernelDLL == NULL) {
- kernelDLL = LoadLibrary("KERNEL32.DLL");
- }
-
- assert(kernelDLL != NULL);
- return kernelDLL;
-}
-
-void unloadDLL() {
- if (kernelDLL != NULL) {
- FreeLibrary(kernelDLL);
- kernelDLL = NULL;
- }
-}
-
-} // namespace ToolHelp
--- a/hotspot/agent/src/os/win32/toolHelp.hpp Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _TOOLHELP_H_
-#define _TOOLHELP_H_
-
-#include <windows.h>
-#include <tlhelp32.h>
-
-namespace ToolHelp {
-extern "C" {
-
- ///////////////
- // Snapshots //
- ///////////////
- typedef HANDLE WINAPI
- CreateToolhelp32SnapshotFunc(DWORD dwFlags, DWORD th32ProcessID);
-
- //////////////////
- // Process List //
- //////////////////
- typedef BOOL WINAPI Process32FirstFunc(HANDLE hSnapshot,
- LPPROCESSENTRY32 lppe);
-
- typedef BOOL WINAPI Process32NextFunc(HANDLE hSnapshot,
- LPPROCESSENTRY32 lppe);
-
- // NOTE: although these routines are defined in TLHELP32.H, they
- // seem to always return false (maybe only under US locales)
- typedef BOOL WINAPI Process32FirstWFunc(HANDLE hSnapshot,
- LPPROCESSENTRY32W lppe);
-
- typedef BOOL WINAPI Process32NextWFunc(HANDLE hSnapshot,
- LPPROCESSENTRY32W lppe);
-
- /////////////////
- // Module List //
- /////////////////
- typedef BOOL WINAPI
- Module32FirstFunc(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
-
- typedef BOOL WINAPI
- Module32NextFunc (HANDLE hSnapshot, LPMODULEENTRY32 lpme);
-
-
- // Routines to load and unload KERNEL32.DLL.
- HMODULE loadDLL();
- // Safe to call even if has not been loaded
- void unloadDLL();
-
-} // extern "C"
-} // namespace "ToolHelp"
-
-#endif // #defined _TOOLHELP_H_
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, 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
@@ -170,6 +170,7 @@
final String errMsg = formatMessage(e.getMessage(), 80);
System.err.println("Unable to connect to process ID " + pid + ":\n\n" + errMsg);
agent.detach();
+ e.printStackTrace();
return;
}
}
@@ -191,6 +192,7 @@
final String errMsg = formatMessage(e.getMessage(), 80);
System.err.println("Unable to open core file\n" + corePath + ":\n\n" + errMsg);
agent.detach();
+ e.printStackTrace();
return;
}
}
@@ -209,6 +211,7 @@
final String errMsg = formatMessage(e.getMessage(), 80);
System.err.println("Unable to connect to machine \"" + remoteMachineName + "\":\n\n" + errMsg);
agent.detach();
+ e.printStackTrace();
return;
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Thu Sep 15 12:44:09 2011 -0700
@@ -40,6 +40,8 @@
import sun.jvm.hotspot.interpreter.*;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.opto.*;
+import sun.jvm.hotspot.ci.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.soql.*;
@@ -48,6 +50,8 @@
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.tools.ObjectHistogram;
import sun.jvm.hotspot.tools.StackTrace;
+import sun.jvm.hotspot.tools.jcore.ClassDump;
+import sun.jvm.hotspot.tools.jcore.ClassFilter;
public class CommandProcessor {
public abstract static class DebuggerInterface {
@@ -59,6 +63,27 @@
public abstract void reattach();
}
+ public static class BootFilter implements ClassFilter {
+ public boolean canInclude(InstanceKlass kls) {
+ return kls.getClassLoader() == null;
+ }
+ }
+
+ public static class NonBootFilter implements ClassFilter {
+ private HashMap emitted = new HashMap();
+ public boolean canInclude(InstanceKlass kls) {
+ if (kls.getClassLoader() == null) return false;
+ if (emitted.get(kls.getName()) != null) {
+ // Since multiple class loaders are being shoved
+ // together duplicate classes are a possibilty. For
+ // now just ignore them.
+ return false;
+ }
+ emitted.put(kls.getName(), kls);
+ return true;
+ }
+ }
+
static class Tokens {
final String input;
int i;
@@ -258,9 +283,14 @@
}
void dumpFields(Type type) {
+ dumpFields(type, true);
+ }
+
+ void dumpFields(Type type, boolean allowStatic) {
Iterator i = type.getFields();
while (i.hasNext()) {
Field f = (Field) i.next();
+ if (!allowStatic && f.isStatic()) continue;
out.print("field ");
quote(type.getName());
out.print(" ");
@@ -458,13 +488,18 @@
});
}
},
- new Command("flags", "flags [ flag ]", false) {
+ new Command("flags", "flags [ flag | -nd ]", false) {
public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens != 0 && tokens != 1) {
usage();
} else {
String name = tokens > 0 ? t.nextToken() : null;
+ boolean nonDefault = false;
+ if (name != null && name.equals("-nd")) {
+ name = null;
+ nonDefault = true;
+ }
VM.Flag[] flags = VM.getVM().getCommandLineFlags();
if (flags == null) {
@@ -474,7 +509,12 @@
for (int f = 0; f < flags.length; f++) {
VM.Flag flag = flags[f];
if (name == null || flag.getName().equals(name)) {
- out.println(flag.getName() + " = " + flag.getValue());
+
+ if (nonDefault && flag.getOrigin() == 0) {
+ // only print flags which aren't their defaults
+ continue;
+ }
+ out.println(flag.getName() + " = " + flag.getValue() + " " + flag.getOrigin());
printed = true;
}
}
@@ -586,6 +626,158 @@
}
}
},
+ new Command("printmdo", "printmdo [ -a | expression ]", false) {
+ // Print every MDO in the heap or the one referenced by expression.
+ public void doit(Tokens t) {
+ if (t.countTokens() != 1) {
+ usage();
+ } else {
+ String s = t.nextToken();
+ if (s.equals("-a")) {
+ HeapVisitor iterator = new DefaultHeapVisitor() {
+ public boolean doObj(Oop obj) {
+ if (obj instanceof MethodData) {
+ Method m = ((MethodData)obj).getMethod();
+ out.println("MethodData " + obj.getHandle() + " for " +
+ "method " + m.getMethodHolder().getName().asString() + "." +
+ m.getName().asString() +
+ m.getSignature().asString() + "@" + m.getHandle());
+ ((MethodData)obj).printDataOn(out);
+ }
+ return false;
+ }
+ };
+ VM.getVM().getObjectHeap().iteratePerm(iterator);
+ } else {
+ Address a = VM.getVM().getDebugger().parseAddress(s);
+ OopHandle handle = a.addOffsetToAsOopHandle(0);
+ MethodData mdo = (MethodData)VM.getVM().getObjectHeap().newOop(handle);
+ mdo.printDataOn(out);
+ }
+ }
+ }
+ },
+ new Command("dumpideal", "dumpideal { -a | id }", false) {
+ // Do a full dump of the nodes reachabile from root in each compiler thread.
+ public void doit(Tokens t) {
+ if (t.countTokens() != 1) {
+ usage();
+ } else {
+ String name = t.nextToken();
+ boolean all = name.equals("-a");
+ Threads threads = VM.getVM().getThreads();
+ for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ thread.printThreadIDOn(new PrintStream(bos));
+ if (all || bos.toString().equals(name)) {
+ if (thread instanceof CompilerThread) {
+ CompilerThread ct = (CompilerThread)thread;
+ out.println(ct);
+ ciEnv env = ct.env();
+ if (env != null) {
+ Compile c = env.compilerData();
+ c.root().dump(9999, out);
+ } else {
+ out.println(" not compiling");
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ new Command("dumpcfg", "dumpcfg { -a | id }", false) {
+ // Dump the PhaseCFG for every compiler thread that has one live.
+ public void doit(Tokens t) {
+ if (t.countTokens() != 1) {
+ usage();
+ } else {
+ String name = t.nextToken();
+ boolean all = name.equals("-a");
+ Threads threads = VM.getVM().getThreads();
+ for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ thread.printThreadIDOn(new PrintStream(bos));
+ if (all || bos.toString().equals(name)) {
+ if (thread instanceof CompilerThread) {
+ CompilerThread ct = (CompilerThread)thread;
+ out.println(ct);
+ ciEnv env = ct.env();
+ if (env != null) {
+ Compile c = env.compilerData();
+ c.cfg().dump(out);
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ new Command("dumpilt", "dumpilt { -a | id }", false) {
+ // dumps the InlineTree of a C2 compile
+ public void doit(Tokens t) {
+ if (t.countTokens() != 1) {
+ usage();
+ } else {
+ String name = t.nextToken();
+ boolean all = name.equals("-a");
+ Threads threads = VM.getVM().getThreads();
+ for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ thread.printThreadIDOn(new PrintStream(bos));
+ if (all || bos.toString().equals(name)) {
+ if (thread instanceof CompilerThread) {
+ CompilerThread ct = (CompilerThread)thread;
+ ciEnv env = ct.env();
+ if (env != null) {
+ Compile c = env.compilerData();
+ InlineTree ilt = c.ilt();
+ if (ilt != null) {
+ ilt.print(out);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ new Command("vmstructsdump", "vmstructsdump", false) {
+ public void doit(Tokens t) {
+ if (t.countTokens() != 0) {
+ usage();
+ return;
+ }
+
+ // Dump a copy of the type database in a form that can
+ // be read back.
+ Iterator i = agent.getTypeDataBase().getTypes();
+ // Make sure the types are emitted in an order than can be read back in
+ HashSet emitted = new HashSet();
+ Stack pending = new Stack();
+ while (i.hasNext()) {
+ Type n = (Type)i.next();
+ if (emitted.contains(n.getName())) {
+ continue;
+ }
+
+ while (n != null && !emitted.contains(n.getName())) {
+ pending.push(n);
+ n = n.getSuperclass();
+ }
+ while (!pending.empty()) {
+ n = (Type)pending.pop();
+ dumpType(n);
+ emitted.add(n.getName());
+ }
+ }
+ i = agent.getTypeDataBase().getTypes();
+ while (i.hasNext()) {
+ dumpFields((Type)i.next(), false);
+ }
+ }
+ },
+
new Command("inspect", "inspect expression", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {
@@ -760,6 +952,50 @@
}
}
},
+ new Command("intConstant", "intConstant [ name [ value ] ]", true) {
+ public void doit(Tokens t) {
+ if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
+ usage();
+ return;
+ }
+ HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
+ if (t.countTokens() == 1) {
+ out.println("intConstant " + name + " " + db.lookupIntConstant(name));
+ } else if (t.countTokens() == 0) {
+ Iterator i = db.getIntConstants();
+ while (i.hasNext()) {
+ String name = (String)i.next();
+ out.println("intConstant " + name + " " + db.lookupIntConstant(name));
+ }
+ } else if (t.countTokens() == 2) {
+ String name = t.nextToken();
+ Integer value = Integer.valueOf(t.nextToken());
+ db.addIntConstant(name, value);
+ }
+ }
+ },
+ new Command("longConstant", "longConstant [ name [ value ] ]", true) {
+ public void doit(Tokens t) {
+ if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
+ usage();
+ return;
+ }
+ HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
+ if (t.countTokens() == 1) {
+ out.println("longConstant " + name + " " + db.lookupLongConstant(name));
+ } else if (t.countTokens() == 0) {
+ Iterator i = db.getLongConstants();
+ while (i.hasNext()) {
+ String name = (String)i.next();
+ out.println("longConstant " + name + " " + db.lookupLongConstant(name));
+ }
+ } else if (t.countTokens() == 2) {
+ String name = t.nextToken();
+ Long value = Long.valueOf(t.nextToken());
+ db.addLongConstant(name, value);
+ }
+ }
+ },
new Command("field", "field [ type [ name fieldtype isStatic offset address ] ]", true) {
public void doit(Tokens t) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
@@ -1311,13 +1547,13 @@
return;
}
- executeCommand(ln);
+ executeCommand(ln, prompt);
}
}
static Pattern historyPattern = Pattern.compile("((!\\*)|(!\\$)|(!!-?)|(!-?[0-9][0-9]*)|(![a-zA-Z][^ ]*))");
- public void executeCommand(String ln) {
+ public void executeCommand(String ln, boolean putInHistory) {
if (ln.indexOf('!') != -1) {
int size = history.size();
if (size == 0) {
@@ -1406,7 +1642,7 @@
Tokens t = new Tokens(ln);
if (t.hasMoreTokens()) {
boolean error = false;
- history.add(ln);
+ if (putInHistory) history.add(ln);
int len = t.countTokens();
if (len > 2) {
String r = t.at(len - 2);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/DebugServer.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/DebugServer.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package sun.jvm.hotspot;
import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.dbx.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.oops.*;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,8 @@
import java.net.*;
import java.rmi.*;
import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.dbx.*;
import sun.jvm.hotspot.debugger.proc.*;
import sun.jvm.hotspot.debugger.remote.*;
-import sun.jvm.hotspot.debugger.win32.*;
import sun.jvm.hotspot.debugger.windbg.*;
import sun.jvm.hotspot.debugger.linux.*;
import sun.jvm.hotspot.memory.*;
@@ -436,113 +434,35 @@
private void setupDebuggerSolaris() {
setupJVMLibNamesSolaris();
- if(System.getProperty("sun.jvm.hotspot.debugger.useProcDebugger") != null) {
- ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true);
- debugger = dbg;
- attachDebugger();
-
- // Set up CPU-dependent stuff
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("sparc")) {
- int addressSize = dbg.getRemoteProcessAddressSize();
- if (addressSize == -1) {
- throw new DebuggerException("Error occurred while trying to determine the remote process's " +
- "address size");
- }
+ ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true);
+ debugger = dbg;
+ attachDebugger();
- if (addressSize == 32) {
- machDesc = new MachineDescriptionSPARC32Bit();
- } else if (addressSize == 64) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
- }
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else {
- throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64");
- }
-
- dbg.setMachineDescription(machDesc);
- return;
-
- } else {
- String dbxPathName;
- String dbxPathPrefix;
- String dbxSvcAgentDSOPathName;
- String dbxSvcAgentDSOPathPrefix;
- String[] dbxSvcAgentDSOPathNames = null;
-
- // use path names/prefixes specified on command
- dbxPathName = System.getProperty("dbxPathName");
- if (dbxPathName == null) {
- dbxPathPrefix = System.getProperty("dbxPathPrefix");
- if (dbxPathPrefix == null) {
- dbxPathPrefix = defaultDbxPathPrefix;
- }
- dbxPathName = dbxPathPrefix + fileSep + os + fileSep + cpu + fileSep + "bin" + fileSep + "dbx";
+ // Set up CPU-dependent stuff
+ if (cpu.equals("x86")) {
+ machDesc = new MachineDescriptionIntelX86();
+ } else if (cpu.equals("sparc")) {
+ int addressSize = dbg.getRemoteProcessAddressSize();
+ if (addressSize == -1) {
+ throw new DebuggerException("Error occurred while trying to determine the remote process's " +
+ "address size");
}
- dbxSvcAgentDSOPathName = System.getProperty("dbxSvcAgentDSOPathName");
- if (dbxSvcAgentDSOPathName != null) {
- dbxSvcAgentDSOPathNames = new String[] { dbxSvcAgentDSOPathName } ;
+ if (addressSize == 32) {
+ machDesc = new MachineDescriptionSPARC32Bit();
+ } else if (addressSize == 64) {
+ machDesc = new MachineDescriptionSPARC64Bit();
} else {
- dbxSvcAgentDSOPathPrefix = System.getProperty("dbxSvcAgentDSOPathPrefix");
- if (dbxSvcAgentDSOPathPrefix == null) {
- dbxSvcAgentDSOPathPrefix = defaultDbxSvcAgentDSOPathPrefix;
- }
- if (cpu.equals("sparc")) {
- dbxSvcAgentDSOPathNames = new String[] {
- // FIXME: bad hack for SPARC v9. This is necessary because
- // there are two dbx executables on SPARC, one for v8 and one
- // for v9, and it isn't obvious how to tell the two apart
- // using the dbx command line. See
- // DbxDebuggerLocal.importDbxModule().
- dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + "v9" + fileSep + "lib" +
- fileSep + "libsvc_agent_dbx.so",
- dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" +
- fileSep + "libsvc_agent_dbx.so",
- };
- } else {
- dbxSvcAgentDSOPathNames = new String[] {
- dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" +
- fileSep + "libsvc_agent_dbx.so"
- };
- }
+ throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
}
+ } else if (cpu.equals("amd64")) {
+ machDesc = new MachineDescriptionAMD64();
+ } else {
+ throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64");
+ }
- // Note we do not use a cache for the local debugger in server
- // mode; it's taken care of on the client side
- DbxDebuggerLocal dbg = new DbxDebuggerLocal(null, dbxPathName, dbxSvcAgentDSOPathNames, !isServer);
- debugger = dbg;
-
- attachDebugger();
-
- // Set up CPU-dependent stuff
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("sparc")) {
- int addressSize = dbg.getRemoteProcessAddressSize();
- if (addressSize == -1) {
- throw new DebuggerException("Error occurred while trying to determine the remote process's " +
- "address size. It's possible that the Serviceability Agent's dbx module failed to " +
- "initialize. Examine the standard output and standard error streams from the dbx " +
- "process for more information.");
- }
-
- if (addressSize == 32) {
- machDesc = new MachineDescriptionSPARC32Bit();
- } else if (addressSize == 64) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
- }
- }
-
- dbg.setMachineDescription(machDesc);
-
- }
+ dbg.setMachineDescription(machDesc);
+ return;
}
private void connectRemoteDebugger() throws DebuggerException {
@@ -589,11 +509,7 @@
// mode; it will be taken care of on the client side (once remote
// debugging is implemented).
- if (System.getProperty("sun.jvm.hotspot.debugger.useWindbgDebugger") != null) {
- debugger = new WindbgDebuggerLocal(machDesc, !isServer);
- } else {
- debugger = new Win32DebuggerLocal(machDesc, !isServer);
- }
+ debugger = new WindbgDebuggerLocal(machDesc, !isServer);
attachDebugger();
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Thu Sep 15 12:44:09 2011 -0700
@@ -87,6 +87,7 @@
readVMStructs();
readVMIntConstants();
readVMLongConstants();
+ readExternalDefinitions();
}
public Type lookupType(String cTypeName, boolean throwException) {
@@ -98,9 +99,9 @@
fieldType = (BasicType)lookupType(cTypeName.substring(0, cTypeName.length() - 6), false);
}
if (fieldType == null) {
- if (cTypeName.startsWith("GrowableArray<") && cTypeName.endsWith(">*")) {
+ if (cTypeName.startsWith("GrowableArray<") && cTypeName.endsWith(">")) {
String ttype = cTypeName.substring("GrowableArray<".length(),
- cTypeName.length() - 2);
+ cTypeName.length() - 1);
Type templateType = lookupType(ttype, false);
if (templateType == null && typeNameIsPointerType(ttype)) {
templateType = recursiveCreateBasicPointerType(ttype);
@@ -108,7 +109,21 @@
if (templateType == null) {
lookupOrFail(ttype);
}
- fieldType = recursiveCreateBasicPointerType(cTypeName);
+
+ BasicType basicTargetType = createBasicType(cTypeName, false, false, false);
+
+ // transfer fields from GenericGrowableArray to template instance
+ BasicType generic = lookupOrFail("GenericGrowableArray");
+ BasicType specific = lookupOrFail("GrowableArray<int>");
+ basicTargetType.setSize(specific.getSize());
+ Iterator fields = generic.getFields();
+ while (fields.hasNext()) {
+ Field f = (Field)fields.next();
+ basicTargetType.addField(internalCreateField(basicTargetType, f.getName(),
+ f.getType(), f.isStatic(),
+ f.getOffset(), null));
+ }
+ fieldType = basicTargetType;
}
}
if (fieldType == null && typeNameIsPointerType(cTypeName)) {
@@ -208,6 +223,156 @@
return type;
}
+ private void readExternalDefinitions() {
+ String file = System.getProperty("sun.jvm.hotspot.typedb");
+ if (file != null) {
+ System.out.println("Reading " + file);
+ BufferedReader in = null;
+ try {
+ StreamTokenizer t = new StreamTokenizer(in = new BufferedReader(new InputStreamReader(new FileInputStream(file))));
+ t.resetSyntax();
+ t.wordChars('\u0000','\uFFFF');
+ t.whitespaceChars(' ', ' ');
+ t.whitespaceChars('\n', '\n');
+ t.whitespaceChars('\r', '\r');
+ t.quoteChar('\"');
+ t.eolIsSignificant(true);
+ while (t.nextToken() != StreamTokenizer.TT_EOF) {
+ if (t.ttype == StreamTokenizer.TT_EOL) {
+ continue;
+ }
+
+ if (t.sval.equals("field")) {
+ t.nextToken();
+ BasicType containingType = (BasicType)lookupType(t.sval);
+ t.nextToken();
+ String fieldName = t.sval;
+
+ // The field's Type must already be in the database -- no exceptions
+ t.nextToken();
+ Type fieldType = lookupType(t.sval);
+ t.nextToken();
+ boolean isStatic = Boolean.valueOf(t.sval).booleanValue();
+ t.nextToken();
+ long offset = Long.parseLong(t.sval);
+ t.nextToken();
+ Address staticAddress = null;
+ if (isStatic) {
+ throw new InternalError("static fields not supported");
+ }
+
+ // check to see if the field already exists
+ Iterator i = containingType.getFields();
+ boolean defined = false;
+ while (i.hasNext()) {
+ Field f = (Field) i.next();
+ if (f.getName().equals(fieldName)) {
+ if (f.isStatic() != isStatic) {
+ throw new RuntimeException("static/nonstatic mismatch: " + fieldName);
+ }
+ if (!isStatic) {
+ if (f.getOffset() != offset) {
+ throw new RuntimeException("bad redefinition of field offset: " + fieldName);
+ }
+ } else {
+ if (!f.getStaticFieldAddress().equals(staticAddress)) {
+ throw new RuntimeException("bad redefinition of field location: " + fieldName);
+ }
+ }
+ if (f.getType() != fieldType) {
+ System.out.println(fieldType);
+ System.out.println(f.getType());
+ throw new RuntimeException("bad redefinition of field type: " + fieldName);
+ }
+ defined = true;
+ break;
+ }
+ }
+
+ if (!defined) {
+ // Create field by type
+ createField(containingType,
+ fieldName, fieldType,
+ isStatic,
+ offset,
+ staticAddress);
+ }
+ } else if (t.sval.equals("type")) {
+ t.nextToken();
+ String typeName = t.sval;
+ t.nextToken();
+ String superclassName = t.sval;
+ if (superclassName.equals("null")) {
+ superclassName = null;
+ }
+ t.nextToken();
+ boolean isOop = Boolean.valueOf(t.sval).booleanValue();
+ t.nextToken();
+ boolean isInteger = Boolean.valueOf(t.sval).booleanValue();
+ t.nextToken();
+ boolean isUnsigned = Boolean.valueOf(t.sval).booleanValue();
+ t.nextToken();
+ long size = Long.parseLong(t.sval);
+
+ BasicType type = null;
+ try {
+ type = (BasicType)lookupType(typeName);
+ } catch (RuntimeException e) {
+ }
+ if (type != null) {
+ if (type.isOopType() != isOop) {
+ throw new RuntimeException("oop mismatch in type definition: " + typeName);
+ }
+ if (type.isCIntegerType() != isInteger) {
+ throw new RuntimeException("integer type mismatch in type definition: " + typeName);
+ }
+ if (type.isCIntegerType() && (((CIntegerType)type).isUnsigned()) != isUnsigned) {
+ throw new RuntimeException("unsigned mismatch in type definition: " + typeName);
+ }
+ if (type.getSuperclass() == null) {
+ if (superclassName != null) {
+ if (type.getSize() == -1) {
+ type.setSuperclass(lookupType(superclassName));
+ } else {
+ throw new RuntimeException("unexpected superclass in type definition: " + typeName);
+ }
+ }
+ } else {
+ if (superclassName == null) {
+ throw new RuntimeException("missing superclass in type definition: " + typeName);
+ }
+ if (!type.getSuperclass().getName().equals(superclassName)) {
+ throw new RuntimeException("incorrect superclass in type definition: " + typeName);
+ }
+ }
+ if (type.getSize() != size) {
+ if (type.getSize() == -1 || type.getSize() == 0) {
+ type.setSize(size);
+ } else {
+ throw new RuntimeException("size mismatch in type definition: " + typeName + ": " + type.getSize() + " != " + size);
+ }
+ }
+ }
+
+ if (lookupType(typeName, false) == null) {
+ // Create type
+ createType(typeName, superclassName, isOop, isInteger, isUnsigned, size);
+ }
+ } else {
+ throw new InternalError("\"" + t.sval + "\"");
+ }
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ try {
+ in.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
private void readVMStructs() {
// Get the variables we need in order to traverse the VMStructEntry[]
long structEntryTypeNameOffset;
@@ -504,20 +669,6 @@
BasicType basicTargetType = createBasicType(targetTypeName, false, true, true);
basicTargetType.setSize(1);
targetType = basicTargetType;
- } else if (targetTypeName.startsWith("GrowableArray<")) {
- BasicType basicTargetType = createBasicType(targetTypeName, false, false, false);
-
- // transfer fields from GenericGrowableArray to template instance
- BasicType generic = lookupOrFail("GenericGrowableArray");
- basicTargetType.setSize(generic.getSize());
- Iterator fields = generic.getFields();
- while (fields.hasNext()) {
- Field f = (Field)fields.next();
- basicTargetType.addField(internalCreateField(basicTargetType, f.getName(),
- f.getType(), f.isStatic(),
- f.getOffset(), null));
- }
- targetType = basicTargetType;
} else {
if (DEBUG) {
System.err.println("WARNING: missing target type \"" + targetTypeName + "\" for pointer type \"" + typeName + "\"");
@@ -572,7 +723,7 @@
// Classes are created with a size of UNINITIALIZED_SIZE.
// Set size if necessary.
- if (curType.getSize() == UNINITIALIZED_SIZE) {
+ if (curType.getSize() == UNINITIALIZED_SIZE || curType.getSize() == 0) {
curType.setSize(size);
} else {
if (curType.getSize() != size) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/TestDebugger.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/TestDebugger.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,12 @@
package sun.jvm.hotspot;
import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.dbx.*;
+import sun.jvm.hotspot.debugger.proc.*;
// A test of the debugger backend. This should be used to connect to
// the helloWorld.cpp program.
public class TestDebugger {
- // FIXME: make these configurable, i.e., via a dotfile
- private static final String dbxPathName = "/export/home/kbr/ws/dbx_61/dev/Derived-sparcv9-S2./src/dbx/dbx";
- private static final String[] dbxSvcAgentDSOPathNames =
- new String[] {
- "/export/home/kbr/main/sa_baseline/src/os/solaris/agent/libsvc_agent_dbx.so"
- };
private static void usage() {
System.out.println("usage: java TestDebugger [pid]");
@@ -58,8 +52,7 @@
usage();
}
- JVMDebugger debugger = new DbxDebuggerLocal(new MachineDescriptionSPARC64Bit(),
- dbxPathName, dbxSvcAgentDSOPathNames, true);
+ JVMDebugger debugger = new ProcDebuggerLocal(null, true);
try {
debugger.attach(pid);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.posix.*;
-import sun.jvm.hotspot.debugger.win32.*;
+import sun.jvm.hotspot.debugger.windbg.*;
import sun.jvm.hotspot.livejvm.*;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
@@ -604,7 +604,7 @@
throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Windows");
}
- localDebugger = new Win32DebuggerLocal(new MachineDescriptionIntelX86(), true);
+ localDebugger = new WindbgDebuggerLocal(new MachineDescriptionIntelX86(), true);
} else if (os.equals("linux")) {
if (!cpu.equals("x86")) {
throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Linux");
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,10 +29,8 @@
import java.rmi.*;
import sun.jvm.hotspot.*;
import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.dbx.*;
import sun.jvm.hotspot.debugger.proc.*;
import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.win32.*;
import sun.jvm.hotspot.debugger.windbg.*;
import sun.jvm.hotspot.debugger.linux.*;
import sun.jvm.hotspot.debugger.sparc.*;
@@ -627,104 +625,33 @@
private void setupDebuggerSolaris() {
setupJVMLibNamesSolaris();
- String prop = System.getProperty("sun.jvm.hotspot.debugger.useProcDebugger");
- if (prop != null && !prop.equals("false")) {
- ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true);
- debugger = dbg;
- attachDebugger();
-
- // Set up CPU-dependent stuff
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("sparc")) {
- int addressSize = dbg.getRemoteProcessAddressSize();
- if (addressSize == -1) {
- throw new DebuggerException("Error occurred while trying to determine the remote process's address size");
- }
+ ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true);
+ debugger = dbg;
+ attachDebugger();
- if (addressSize == 32) {
- machDesc = new MachineDescriptionSPARC32Bit();
- } else if (addressSize == 64) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
- }
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else {
- throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64");
- }
-
- dbg.setMachineDescription(machDesc);
- return;
- } else {
- String dbxPathName;
- String dbxPathPrefix;
- String dbxSvcAgentDSOPathName;
- String dbxSvcAgentDSOPathPrefix;
- String[] dbxSvcAgentDSOPathNames = null;
-
- // use path names/prefixes specified on command
- dbxPathName = System.getProperty("dbxPathName");
- if (dbxPathName == null) {
- dbxPathPrefix = System.getProperty("dbxPathPrefix");
- if (dbxPathPrefix == null) {
- dbxPathPrefix = defaultDbxPathPrefix;
- }
- dbxPathName = dbxPathPrefix + fileSep + os + fileSep + cpu + fileSep + "bin" + fileSep + "dbx";
+ // Set up CPU-dependent stuff
+ if (cpu.equals("x86")) {
+ machDesc = new MachineDescriptionIntelX86();
+ } else if (cpu.equals("sparc")) {
+ int addressSize = dbg.getRemoteProcessAddressSize();
+ if (addressSize == -1) {
+ throw new DebuggerException("Error occurred while trying to determine the remote process's address size");
}
- dbxSvcAgentDSOPathName = System.getProperty("dbxSvcAgentDSOPathName");
- if (dbxSvcAgentDSOPathName != null) {
- dbxSvcAgentDSOPathNames = new String[] { dbxSvcAgentDSOPathName } ;
+ if (addressSize == 32) {
+ machDesc = new MachineDescriptionSPARC32Bit();
+ } else if (addressSize == 64) {
+ machDesc = new MachineDescriptionSPARC64Bit();
} else {
- dbxSvcAgentDSOPathPrefix = System.getProperty("dbxSvcAgentDSOPathPrefix");
- if (dbxSvcAgentDSOPathPrefix == null) {
- dbxSvcAgentDSOPathPrefix = defaultDbxSvcAgentDSOPathPrefix;
- }
- if (cpu.equals("sparc")) {
- dbxSvcAgentDSOPathNames = new String[] {
- // FIXME: bad hack for SPARC v9. This is necessary because
- // there are two dbx executables on SPARC, one for v8 and one
- // for v9, and it isn't obvious how to tell the two apart
- // using the dbx command line. See
- // DbxDebuggerLocal.importDbxModule().
- dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + "v9" + fileSep + "lib" + fileSep + "libsvc_agent_dbx.so",
- dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" + fileSep + "libsvc_agent_dbx.so",
- };
- } else {
- dbxSvcAgentDSOPathNames = new String[] {
- dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" + fileSep + "libsvc_agent_dbx.so"
- };
- }
+ throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
}
- // Note we do not use a cache for the local debugger in server
- // mode; it's taken care of on the client side
- DbxDebuggerLocal dbg = new DbxDebuggerLocal(null, dbxPathName, dbxSvcAgentDSOPathNames, !isServer);
- debugger = dbg;
-
- attachDebugger();
+ } else if (cpu.equals("amd64")) {
+ machDesc = new MachineDescriptionAMD64();
+ } else {
+ throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64");
+ }
- // Set up CPU-dependent stuff
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("sparc")) {
- int addressSize = dbg.getRemoteProcessAddressSize();
- if (addressSize == -1) {
- throw new DebuggerException("Error occurred while trying to determine the remote process's address size. It's possible that the Serviceability Agent's dbx module failed to initialize. Examine the standard output and standard error streams from the dbx process for more information.");
- }
-
- if (addressSize == 32) {
- machDesc = new MachineDescriptionSPARC32Bit();
- } else if (addressSize == 64) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
- }
- }
-
- dbg.setMachineDescription(machDesc);
- }
+ dbg.setMachineDescription(machDesc);
}
private void connectRemoteDebugger() throws DebuggerException {
@@ -772,11 +699,7 @@
// mode; it will be taken care of on the client side (once remote
// debugging is implemented).
- if (System.getProperty("sun.jvm.hotspot.debugger.useWindbgDebugger") != null) {
- debugger = new WindbgDebuggerLocal(machDesc, !isServer);
- } else {
- debugger = new Win32DebuggerLocal(machDesc, !isServer);
- }
+ debugger = new WindbgDebuggerLocal(machDesc, !isServer);
attachDebugger();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciArrayKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciArrayKlass extends ciKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciArrayKlass");
+ dimensionField = new IntField(type.getJIntField("_dimension"), 0);
+ }
+
+ private static IntField dimensionField;
+
+ public ciArrayKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciArrayKlassKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciArrayKlassKlass extends ciKlassKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciArrayKlassKlass");
+ }
+
+
+ public ciArrayKlassKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciConstant.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciConstant extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciConstant");
+ valueObjectField = type.getAddressField("_value._object");
+ valueDoubleField = type.getJDoubleField("_value._double");
+ valueFloatField = type.getJFloatField("_value._float");
+ valueLongField = type.getJLongField("_value._long");
+ valueIntField = type.getJIntField("_value._int");
+ typeField = new CIntField(type.getCIntegerField("_type"), 0);
+ }
+
+ private static AddressField valueObjectField;
+ private static JDoubleField valueDoubleField;
+ private static JFloatField valueFloatField;
+ private static JLongField valueLongField;
+ private static JIntField valueIntField;
+ private static CIntField typeField;
+
+ public ciConstant(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.opto.*;
+import sun.jvm.hotspot.compiler.CompileTask;
+import sun.jvm.hotspot.prims.JvmtiExport;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.GrowableArray;
+
+public class ciEnv extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciEnv");
+ dependenciesField = type.getAddressField("_dependencies");
+ factoryField = type.getAddressField("_factory");
+ compilerDataField = type.getAddressField("_compiler_data");
+ taskField = type.getAddressField("_task");
+ systemDictionaryModificationCounterField = new CIntField(type.getCIntegerField("_system_dictionary_modification_counter"), 0);
+ }
+
+ private static AddressField dependenciesField;
+ private static AddressField factoryField;
+ private static AddressField compilerDataField;
+ private static AddressField taskField;
+ private static CIntField systemDictionaryModificationCounterField;
+
+ public ciEnv(Address addr) {
+ super(addr);
+ }
+
+ public Compile compilerData() {
+ return new Compile(compilerDataField.getValue(this.getAddress()));
+ }
+
+ public ciObjectFactory factory() {
+ return new ciObjectFactory(factoryField.getValue(this.getAddress()));
+ }
+
+ public CompileTask task() {
+ return new CompileTask(taskField.getValue(this.getAddress()));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciField.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciField extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciField");
+ constantValueField = type.getAddressField("_constant_value");
+ isConstantField = type.getAddressField("_is_constant");
+ offsetField = new CIntField(type.getCIntegerField("_offset"), 0);
+ signatureField = type.getAddressField("_signature");
+ nameField = type.getAddressField("_name");
+ holderField = type.getAddressField("_holder");
+ }
+
+ private static AddressField constantValueField;
+ private static AddressField isConstantField;
+ private static CIntField offsetField;
+ private static AddressField signatureField;
+ private static AddressField nameField;
+ private static AddressField holderField;
+
+ public ciField(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciInstance.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciInstance extends ciObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciInstance");
+ }
+
+
+ public ciInstance(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciInstanceKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.SystemDictionary;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.types.WrongTypeException;
+
+public class ciInstanceKlass extends ciKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciInstanceKlass");
+ initStateField = new CIntField(type.getCIntegerField("_init_state"), 0);
+ isSharedField = new CIntField(type.getCIntegerField("_is_shared"), 0);
+ CLASS_STATE_LINKED = db.lookupIntConstant("instanceKlass::linked").intValue();
+ CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue();
+ }
+
+ private static CIntField initStateField;
+ private static CIntField isSharedField;
+ private static int CLASS_STATE_LINKED;
+ private static int CLASS_STATE_FULLY_INITIALIZED;
+
+ public ciInstanceKlass(Address addr) {
+ super(addr);
+ }
+
+ public int initState() {
+ int initState = (int)initStateField.getValue(getAddress());
+ if (isShared() && initState < CLASS_STATE_LINKED) {
+ InstanceKlass ik = (InstanceKlass)getOop();
+ initState = ik.getInitStateAsInt();
+ }
+ return initState;
+ }
+
+ public boolean isShared() {
+ return isSharedField.getValue(getAddress()) != 0;
+ }
+
+ public boolean isLinked() {
+ return initState() >= CLASS_STATE_LINKED;
+ }
+
+ public boolean isInitialized() {
+ return initState() == CLASS_STATE_FULLY_INITIALIZED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciInstanceKlassKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciInstanceKlassKlass extends ciKlassKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciInstanceKlassKlass");
+ }
+
+
+ public ciInstanceKlassKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciKlass extends ciType {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciKlass");
+ nameField = type.getAddressField("_name");
+ }
+
+ private static AddressField nameField;
+
+ public String name() {
+ ciSymbol sym = new ciSymbol(nameField.getValue(getAddress()));
+ return sym.asUtf88();
+ }
+
+ public ciKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciKlassKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciKlassKlass extends ciKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciKlassKlass");
+ }
+
+
+ public ciKlassKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciMethod extends ciObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciMethod");
+ interpreterThrowoutCountField = new CIntField(type.getCIntegerField("_interpreter_throwout_count"), 0);
+ interpreterInvocationCountField = new CIntField(type.getCIntegerField("_interpreter_invocation_count"), 0);
+ try {
+ // XXX
+ instructionsSizeField = new CIntField(type.getCIntegerField("_instructions_size"), 0);
+ } catch (Exception e) {
+ }
+ }
+
+ private static CIntField interpreterThrowoutCountField;
+ private static CIntField interpreterInvocationCountField;
+ private static CIntField instructionsSizeField;
+
+ public ciMethod(Address addr) {
+ super(addr);
+ }
+
+ public Method method() {
+ return (Method)getOop();
+ }
+
+ public int interpreterThrowoutCount() {
+ return (int) interpreterThrowoutCountField.getValue(getAddress());
+ }
+
+ public int interpreterInvocationCount() {
+ return (int) interpreterInvocationCountField.getValue(getAddress());
+ }
+
+ public int instructionsSize() {
+ if (instructionsSizeField == null) {
+ // XXX
+ Method method = (Method)getOop();
+ NMethod nm = method.getNativeMethod();
+ if (nm != null) return (int)nm.codeEnd().minus(nm.getVerifiedEntryPoint());
+ return 0;
+ }
+ return (int) instructionsSizeField.getValue(getAddress());
+ }
+
+ public void printShortName(PrintStream st) {
+ Method method = (Method)getOop();
+ st.printf(" %s::%s", method.getMethodHolder().getName().asString().replace('/', '.'),
+ method.getName().asString());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciMethodData extends ciObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciMethodData");
+ origField = type.getAddressField("_orig");
+ currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
+ argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 0);
+ argStackField = new CIntField(type.getCIntegerField("_arg_stack"), 0);
+ argLocalField = new CIntField(type.getCIntegerField("_arg_local"), 0);
+ eflagsField = new CIntField(type.getCIntegerField("_eflags"), 0);
+ hintDiField = new CIntField(type.getCIntegerField("_hint_di"), 0);
+ currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
+ dataField = type.getAddressField("_data");
+ extraDataSizeField = new CIntField(type.getCIntegerField("_extra_data_size"), 0);
+ dataSizeField = new CIntField(type.getCIntegerField("_data_size"), 0);
+ stateField = new CIntField(type.getCIntegerField("_state"), 0);
+ sizeofMethodDataOopDesc = (int)db.lookupType("methodDataOopDesc").getSize();;
+ }
+
+ private static AddressField origField;
+ private static CIntField currentMileageField;
+ private static CIntField argReturnedField;
+ private static CIntField argStackField;
+ private static CIntField argLocalField;
+ private static CIntField eflagsField;
+ private static CIntField hintDiField;
+ private static AddressField dataField;
+ private static CIntField extraDataSizeField;
+ private static CIntField dataSizeField;
+ private static CIntField stateField;
+ private static int sizeofMethodDataOopDesc;
+
+ public ciMethodData(Address addr) {
+ super(addr);
+ }
+
+ private byte[] fetchDataAt(Address base, long size) {
+ byte[] result = new byte[(int)size];
+ for (int i = 0; i < size; i++) {
+ result[i] = base.getJByteAt(i);
+ }
+ return result;
+ }
+
+ public byte[] orig() {
+ // fetch the orig methodDataOopDesc data between header and dataSize
+ Address base = getAddress().addOffsetTo(origField.getOffset());
+ byte[] result = new byte[MethodData.sizeofMethodDataOopDesc];
+ for (int i = 0; i < MethodData.sizeofMethodDataOopDesc; i++) {
+ result[i] = base.getJByteAt(i);
+ }
+ return result;
+ }
+
+ public long[] data() {
+ // Read the data as an array of intptr_t elements
+ Address base = dataField.getValue(getAddress());
+ int elements = dataSize() / MethodData.cellSize;
+ long[] result = new long[elements];
+ for (int i = 0; i < elements; i++) {
+ Address value = base.getAddressAt(i * MethodData.cellSize);
+ if (value != null) {
+ result[i] = value.minus(null);
+ }
+ }
+ return result;
+ }
+
+ int dataSize() {
+ return (int)dataSizeField.getValue(getAddress());
+ }
+
+ int state() {
+ return (int)stateField.getValue(getAddress());
+ }
+
+ int currentMileage() {
+ return (int)currentMileageField.getValue(getAddress());
+ }
+
+ boolean outOfBounds(int dataIndex) {
+ return dataIndex >= dataSize();
+ }
+
+ ProfileData dataAt(int dataIndex) {
+ if (outOfBounds(dataIndex)) {
+ return null;
+ }
+ DataLayout dataLayout = new DataLayout(dataField.getValue(getAddress()), dataIndex);
+
+ switch (dataLayout.tag()) {
+ case DataLayout.noTag:
+ default:
+ throw new InternalError();
+ case DataLayout.bitDataTag:
+ return new BitData(dataLayout);
+ case DataLayout.counterDataTag:
+ return new CounterData(dataLayout);
+ case DataLayout.jumpDataTag:
+ return new JumpData(dataLayout);
+ case DataLayout.receiverTypeDataTag:
+ return new ciReceiverTypeData(dataLayout);
+ case DataLayout.virtualCallDataTag:
+ return new ciVirtualCallData(dataLayout);
+ case DataLayout.retDataTag:
+ return new RetData(dataLayout);
+ case DataLayout.branchDataTag:
+ return new BranchData(dataLayout);
+ case DataLayout.multiBranchDataTag:
+ return new MultiBranchData(dataLayout);
+ }
+ }
+
+ int dpToDi(int dp) {
+ return dp;
+ }
+
+ int firstDi() { return 0; }
+ ProfileData firstData() { return dataAt(firstDi()); }
+ ProfileData nextData(ProfileData current) {
+ int currentIndex = dpToDi(current.dp());
+ int nextIndex = currentIndex + current.sizeInBytes();
+ return dataAt(nextIndex);
+ }
+ boolean isValid(ProfileData current) { return current != null; }
+
+ public void printDataOn(PrintStream st) {
+ ProfileData data = firstData();
+ for ( ; isValid(data); data = nextData(data)) {
+ st.print(dpToDi(data.dp()));
+ st.print(" ");
+ // st->fillTo(6);
+ data.printDataOn(st);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciMethodKlass extends ciKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciMethodKlass");
+ }
+
+
+ public ciMethodKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciObjArrayKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciObjArrayKlass extends ciArrayKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciObjArrayKlass");
+ elementKlassField = type.getAddressField("_element_klass");
+ baseElementKlassField = type.getAddressField("_base_element_klass");
+ }
+
+ private static AddressField elementKlassField;
+ private static AddressField baseElementKlassField;
+
+ public ciObjArrayKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciObjArrayKlassKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciObjArrayKlassKlass extends ciArrayKlassKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciObjArrayKlassKlass");
+ }
+
+
+ public ciObjArrayKlassKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciObject.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciObject extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciObject");
+ identField = new CIntField(type.getCIntegerField("_ident"), 0);
+ klassField = type.getAddressField("_klass");
+ handleField = type.getAddressField("_handle");
+ }
+
+ private static CIntField identField;
+ private static AddressField klassField;
+ private static AddressField handleField;
+
+ public Oop getOop() {
+ OopHandle oh = handleField.getValue(getAddress()).getOopHandleAt(0);
+ return VM.getVM().getObjectHeap().newOop(oh);
+ }
+
+ public ciObject(Address addr) {
+ super(addr);
+ }
+
+ public void printOn(PrintStream out) {
+ getOop().printValueOn(out);
+ out.println();
+ }
+
+ public String toString() {
+ return getOop().toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciObjectFactory.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.lang.reflect.Constructor;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.utilities.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciObjectFactory extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciObjectFactory");
+ unloadedMethodsField = type.getAddressField("_unloaded_methods");
+ ciObjectsField = type.getAddressField("_ci_objects");
+ symbolsField = type.getAddressField("_symbols");
+
+ ciObjectConstructor = new VirtualBaseConstructor<ciObject>(db, db.lookupType("ciObject"), "sun.jvm.hotspot.ci", ciObject.class);
+ ciSymbolConstructor = new VirtualBaseConstructor<ciSymbol>(db, db.lookupType("ciSymbol"), "sun.jvm.hotspot.ci", ciSymbol.class);
+ }
+
+ private static AddressField unloadedMethodsField;
+ private static AddressField ciObjectsField;
+ private static AddressField symbolsField;
+
+ private static VirtualBaseConstructor<ciObject> ciObjectConstructor;
+ private static VirtualBaseConstructor<ciSymbol> ciSymbolConstructor;
+
+ public static ciObject get(Address addr) {
+ if (addr == null) return null;
+
+ return (ciObject)ciObjectConstructor.instantiateWrapperFor(addr);
+ }
+
+ public GrowableArray<ciObject> objects() {
+ return GrowableArray.create(ciObjectsField.getValue(getAddress()), ciObjectConstructor);
+ }
+
+ public GrowableArray<ciSymbol> symbols() {
+ return GrowableArray.create(symbolsField.getValue(getAddress()), ciSymbolConstructor);
+ }
+
+ public ciObjectFactory(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciReceiverTypeData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciReceiverTypeData extends ReceiverTypeData {
+ public ciReceiverTypeData(DataLayout data) {
+ super(data);
+ }
+
+ public Klass receiver(int row) {
+ throw new InternalError("should not call");
+ }
+
+ public ciKlass receiverAt(int row) {
+ //assert((uint)row < rowLimit(), "oob");
+ ciObject recv = ciObjectFactory.get(addressAt(receiverCellIndex(row)));
+ if (recv != null && !(recv instanceof ciKlass)) {
+ System.err.println(recv);
+ }
+ //assert(recv == NULL || recv->isKlass(), "wrong type");
+ return (ciKlass)recv;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciSymbol.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciSymbol extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciSymbol");
+ identField = type.getCIntegerField("_ident");
+ symbolField = type.getAddressField("_symbol");
+ }
+
+ private static AddressField symbolField;
+ private static CIntegerField identField;
+
+ public String asUtf88() {
+ Symbol sym = Symbol.create(symbolField.getValue(getAddress()));
+ return sym.asString();
+ }
+
+ public ciSymbol(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciType.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciType extends ciObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciType");
+ basicTypeField = new CIntField(type.getCIntegerField("_basic_type"), 0);
+ }
+
+ private static CIntField basicTypeField;
+
+ public ciType(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciTypeArrayKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciTypeArrayKlass extends ciArrayKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciTypeArrayKlass");
+ }
+
+ public ciTypeArrayKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciTypeArrayKlassKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciTypeArrayKlassKlass extends ciArrayKlassKlass {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ciTypeArrayKlassKlass");
+ }
+
+
+ public ciTypeArrayKlassKlass(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciVirtualCallData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.ci;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ciVirtualCallData extends VirtualCallData {
+ public ciVirtualCallData(DataLayout data) {
+ super(data);
+ }
+
+ public Klass receiver(int row) {
+ throw new InternalError("should not call");
+ }
+
+ public ciKlass receiverAt(int row) {
+ //assert((uint)row < rowLimit(), "oob");
+ ciObject recv = ciObjectFactory.get(addressAt(receiverCellIndex(row)));
+ if (recv != null && !(recv instanceof ciKlass)) {
+ System.err.println(recv);
+ }
+ //assert(recv == NULL || recv->isKlass(), "wrong type");
+ return (ciKlass)recv;
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, 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
@@ -190,6 +190,8 @@
public boolean handlerTableContains(Address addr) { return handlerTableBegin().lessThanOrEqual(addr) && handlerTableEnd().greaterThan(addr); }
public boolean nulChkTableContains (Address addr) { return nulChkTableBegin() .lessThanOrEqual(addr) && nulChkTableEnd() .greaterThan(addr); }
+ public int getOopsLength() { return (int) (oopsSize() / VM.getVM().getOopSize()); }
+
/** Entry points */
public Address getEntryPoint() { return entryPointField.getValue(addr); }
public Address getVerifiedEntryPoint() { return verifiedEntryPointField.getValue(addr); }
@@ -198,7 +200,7 @@
public OopHandle getOopAt(int index) {
if (index == 0) return null;
if (Assert.ASSERTS_ENABLED) {
- Assert.that(index > 0 && index <= oopsSize(), "must be a valid non-zero index");
+ Assert.that(index > 0 && index <= getOopsLength(), "must be a valid non-zero index");
}
return oopsBegin().getOopHandleAt((index - 1) * VM.getVM().getOopSize());
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/CompileTask.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.compiler;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.opto.*;
+import sun.jvm.hotspot.prims.JvmtiExport;
+import sun.jvm.hotspot.types.*;
+
+public class CompileTask extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("CompileTask");
+ methodField = type.getAddressField("_method");
+ osrBciField = new CIntField(type.getCIntegerField("_osr_bci"), 0);
+ }
+
+ private static AddressField methodField;
+ private static CIntField osrBciField;
+
+ public CompileTask(Address addr) {
+ super(addr);
+ }
+
+ public Method method() {
+ OopHandle oh = methodField.getValue(getAddress()).getOopHandleAt(0);
+ return (Method)VM.getVM().getObjectHeap().newOop(oh);
+ }
+
+ public int osrBci() {
+ return (int)osrBciField.getValue(getAddress());
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/AddressException.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/AddressException.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,4 +39,8 @@
public long getAddress() {
return addr;
}
+
+ public String getMessage() {
+ return Long.toHexString(addr);
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxAddress.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +0,0 @@
-/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx;
-
-import sun.jvm.hotspot.debugger.*;
-
-class DbxAddress implements Address {
- protected DbxDebugger debugger;
- protected long addr;
-
- DbxAddress(DbxDebugger debugger, long addr) {
- this.debugger = debugger;
- this.addr = addr;
- }
-
- //
- // Basic Java routines
- //
-
- public boolean equals(Object arg) {
- if (arg == null) {
- return false;
- }
-
- if (!(arg instanceof DbxAddress)) {
- return false;
- }
-
- return (addr == ((DbxAddress) arg).addr);
- }
-
- public int hashCode() {
- // FIXME: suggestions on a better hash code?
- return (int) addr;
- }
-
- public String toString() {
- return debugger.addressValueToString(addr);
- }
-
- //
- // C/C++-related routines
- //
-
- public long getCIntegerAt(long offset, long numBytes, boolean isUnsigned) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readCInteger(addr + offset, numBytes, isUnsigned);
- }
-
- public Address getAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readAddress(addr + offset);
- }
- public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readCompOopAddress(addr + offset);
- }
-
- //
- // Java-related routines
- //
-
- public boolean getJBooleanAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJBoolean(addr + offset);
- }
-
- public byte getJByteAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJByte(addr + offset);
- }
-
- public char getJCharAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJChar(addr + offset);
- }
-
- public double getJDoubleAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJDouble(addr + offset);
- }
-
- public float getJFloatAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJFloat(addr + offset);
- }
-
- public int getJIntAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJInt(addr + offset);
- }
-
- public long getJLongAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJLong(addr + offset);
- }
-
- public short getJShortAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJShort(addr + offset);
- }
-
- public OopHandle getOopHandleAt(long offset)
- throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
- return debugger.readOopHandle(addr + offset);
- }
-
- public OopHandle getCompOopHandleAt(long offset)
- throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
- return debugger.readCompOopHandle(addr + offset);
- }
-
- // Mutators -- not implemented for now (FIXME)
- public void setCIntegerAt(long offset, long numBytes, long value) {
- throw new DebuggerException("Unimplemented");
- }
- public void setAddressAt(long offset, Address value) {
- throw new DebuggerException("Unimplemented");
- }
- public void setJBooleanAt (long offset, boolean value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setJByteAt (long offset, byte value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setJCharAt (long offset, char value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setJDoubleAt (long offset, double value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setJFloatAt (long offset, float value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setJIntAt (long offset, int value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setJLongAt (long offset, long value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setJShortAt (long offset, short value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
- public void setOopHandleAt (long offset, OopHandle value)
- throws UnmappedAddressException, UnalignedAddressException {
- throw new DebuggerException("Unimplemented");
- }
-
- //
- // Arithmetic operations -- necessary evil.
- //
-
- public Address addOffsetTo (long offset) throws UnsupportedOperationException {
- long value = addr + offset;
- if (value == 0) {
- return null;
- }
- return new DbxAddress(debugger, value);
- }
-
- public OopHandle addOffsetToAsOopHandle(long offset) throws UnsupportedOperationException {
- long value = addr + offset;
- if (value == 0) {
- return null;
- }
- return new DbxOopHandle(debugger, value);
- }
-
- /** (FIXME: any signed/unsigned issues? Should this work for
- OopHandles?) */
- public long minus(Address arg) {
- if (arg == null) {
- return addr;
- }
- return addr - ((DbxAddress) arg).addr;
- }
-
- // Two's complement representation.
- // All negative numbers are larger than positive numbers.
- // Numbers with the same sign can be compared normally.
- // Test harness is below in main().
-
- public boolean lessThan (Address arg) {
- if (arg == null) {
- return false;
- }
- DbxAddress dbxArg = (DbxAddress) arg;
- if ((addr >= 0) && (dbxArg.addr < 0)) {
- return true;
- }
- if ((addr < 0) && (dbxArg.addr >= 0)) {
- return false;
- }
- return (addr < dbxArg.addr);
- }
-
- public boolean lessThanOrEqual (Address arg) {
- if (arg == null) {
- return false;
- }
- DbxAddress dbxArg = (DbxAddress) arg;
- if ((addr >= 0) && (dbxArg.addr < 0)) {
- return true;
- }
- if ((addr < 0) && (dbxArg.addr >= 0)) {
- return false;
- }
- return (addr <= dbxArg.addr);
- }
-
- public boolean greaterThan (Address arg) {
- if (arg == null) {
- return true;
- }
- DbxAddress dbxArg = (DbxAddress) arg;
- if ((addr >= 0) && (dbxArg.addr < 0)) {
- return false;
- }
- if ((addr < 0) && (dbxArg.addr >= 0)) {
- return true;
- }
- return (addr > dbxArg.addr);
- }
-
- public boolean greaterThanOrEqual(Address arg) {
- if (arg == null) {
- return true;
- }
- DbxAddress dbxArg = (DbxAddress) arg;
- if ((addr >= 0) && (dbxArg.addr < 0)) {
- return false;
- }
- if ((addr < 0) && (dbxArg.addr >= 0)) {
- return true;
- }
- return (addr >= dbxArg.addr);
- }
-
- public Address andWithMask(long mask) throws UnsupportedOperationException {
- long value = addr & mask;
- if (value == 0) {
- return null;
- }
- return new DbxAddress(debugger, value);
- }
-
- public Address orWithMask(long mask) throws UnsupportedOperationException {
- long value = addr | mask;
- if (value == 0) {
- return null;
- }
- return new DbxAddress(debugger, value);
- }
-
- public Address xorWithMask(long mask) throws UnsupportedOperationException {
- long value = addr ^ mask;
- if (value == 0) {
- return null;
- }
- return new DbxAddress(debugger, value);
- }
-
-
- //--------------------------------------------------------------------------------
- // Internals only below this point
- //
-
- long getValue() {
- return addr;
- }
-
-
- private static void check(boolean arg, String failMessage) {
- if (!arg) {
- System.err.println(failMessage + ": FAILED");
- System.exit(1);
- }
- }
-
- // Test harness
- public static void main(String[] args) {
- // p/n indicates whether the interior address is really positive
- // or negative. In unsigned terms, p1 < p2 < n1 < n2.
-
- DbxAddress p1 = new DbxAddress(null, 0x7FFFFFFFFFFFFFF0L);
- DbxAddress p2 = (DbxAddress) p1.addOffsetTo(10);
- DbxAddress n1 = (DbxAddress) p2.addOffsetTo(10);
- DbxAddress n2 = (DbxAddress) n1.addOffsetTo(10);
-
- // lessThan positive tests
- check(p1.lessThan(p2), "lessThan 1");
- check(p1.lessThan(n1), "lessThan 2");
- check(p1.lessThan(n2), "lessThan 3");
- check(p2.lessThan(n1), "lessThan 4");
- check(p2.lessThan(n2), "lessThan 5");
- check(n1.lessThan(n2), "lessThan 6");
-
- // lessThan negative tests
- check(!p1.lessThan(p1), "lessThan 7");
- check(!p2.lessThan(p2), "lessThan 8");
- check(!n1.lessThan(n1), "lessThan 9");
- check(!n2.lessThan(n2), "lessThan 10");
-
- check(!p2.lessThan(p1), "lessThan 11");
- check(!n1.lessThan(p1), "lessThan 12");
- check(!n2.lessThan(p1), "lessThan 13");
- check(!n1.lessThan(p2), "lessThan 14");
- check(!n2.lessThan(p2), "lessThan 15");
- check(!n2.lessThan(n1), "lessThan 16");
-
- // lessThanOrEqual positive tests
- check(p1.lessThanOrEqual(p1), "lessThanOrEqual 1");
- check(p2.lessThanOrEqual(p2), "lessThanOrEqual 2");
- check(n1.lessThanOrEqual(n1), "lessThanOrEqual 3");
- check(n2.lessThanOrEqual(n2), "lessThanOrEqual 4");
-
- check(p1.lessThanOrEqual(p2), "lessThanOrEqual 5");
- check(p1.lessThanOrEqual(n1), "lessThanOrEqual 6");
- check(p1.lessThanOrEqual(n2), "lessThanOrEqual 7");
- check(p2.lessThanOrEqual(n1), "lessThanOrEqual 8");
- check(p2.lessThanOrEqual(n2), "lessThanOrEqual 9");
- check(n1.lessThanOrEqual(n2), "lessThanOrEqual 10");
-
- // lessThanOrEqual negative tests
- check(!p2.lessThanOrEqual(p1), "lessThanOrEqual 11");
- check(!n1.lessThanOrEqual(p1), "lessThanOrEqual 12");
- check(!n2.lessThanOrEqual(p1), "lessThanOrEqual 13");
- check(!n1.lessThanOrEqual(p2), "lessThanOrEqual 14");
- check(!n2.lessThanOrEqual(p2), "lessThanOrEqual 15");
- check(!n2.lessThanOrEqual(n1), "lessThanOrEqual 16");
-
- // greaterThan positive tests
- check(n2.greaterThan(p1), "greaterThan 1");
- check(n2.greaterThan(p2), "greaterThan 2");
- check(n2.greaterThan(n1), "greaterThan 3");
- check(n1.greaterThan(p1), "greaterThan 4");
- check(n1.greaterThan(p2), "greaterThan 5");
- check(p2.greaterThan(p1), "greaterThan 6");
-
- // greaterThan negative tests
- check(!p1.greaterThan(p1), "greaterThan 7");
- check(!p2.greaterThan(p2), "greaterThan 8");
- check(!n1.greaterThan(n1), "greaterThan 9");
- check(!n2.greaterThan(n2), "greaterThan 10");
-
- check(!p1.greaterThan(n2), "greaterThan 11");
- check(!p2.greaterThan(n2), "greaterThan 12");
- check(!n1.greaterThan(n2), "greaterThan 13");
- check(!p1.greaterThan(n1), "greaterThan 14");
- check(!p2.greaterThan(n1), "greaterThan 15");
- check(!p1.greaterThan(p2), "greaterThan 16");
-
- // greaterThanOrEqual positive tests
- check(p1.greaterThanOrEqual(p1), "greaterThanOrEqual 1");
- check(p2.greaterThanOrEqual(p2), "greaterThanOrEqual 2");
- check(n1.greaterThanOrEqual(n1), "greaterThanOrEqual 3");
- check(n2.greaterThanOrEqual(n2), "greaterThanOrEqual 4");
-
- check(n2.greaterThanOrEqual(p1), "greaterThanOrEqual 5");
- check(n2.greaterThanOrEqual(p2), "greaterThanOrEqual 6");
- check(n2.greaterThanOrEqual(n1), "greaterThanOrEqual 7");
- check(n1.greaterThanOrEqual(p1), "greaterThanOrEqual 8");
- check(n1.greaterThanOrEqual(p2), "greaterThanOrEqual 9");
- check(p2.greaterThanOrEqual(p1), "greaterThanOrEqual 10");
-
- // greaterThanOrEqual negative tests
- check(!p1.greaterThanOrEqual(n2), "greaterThanOrEqual 11");
- check(!p2.greaterThanOrEqual(n2), "greaterThanOrEqual 12");
- check(!n1.greaterThanOrEqual(n2), "greaterThanOrEqual 13");
- check(!p1.greaterThanOrEqual(n1), "greaterThanOrEqual 14");
- check(!p2.greaterThanOrEqual(n1), "greaterThanOrEqual 15");
- check(!p1.greaterThanOrEqual(p2), "greaterThanOrEqual 16");
-
- System.err.println("DbxAddress: all tests passed successfully.");
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebugger.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx;
-
-import sun.jvm.hotspot.debugger.*;
-
-/** An extension of the JVMDebugger interface with a few additions to
- support 32-bit vs. 64-bit debugging as well as features required
- by the architecture-specific subpackages. */
-
-public interface DbxDebugger extends JVMDebugger {
- public String addressValueToString(long address) throws DebuggerException;
- public boolean readJBoolean(long address) throws DebuggerException;
- public byte readJByte(long address) throws DebuggerException;
- public char readJChar(long address) throws DebuggerException;
- public double readJDouble(long address) throws DebuggerException;
- public float readJFloat(long address) throws DebuggerException;
- public int readJInt(long address) throws DebuggerException;
- public long readJLong(long address) throws DebuggerException;
- public short readJShort(long address) throws DebuggerException;
- public long readCInteger(long address, long numBytes, boolean isUnsigned)
- throws DebuggerException;
- public DbxAddress readAddress(long address) throws DebuggerException;
- public DbxAddress readCompOopAddress(long address) throws DebuggerException;
- public DbxOopHandle readOopHandle(long address) throws DebuggerException;
- public DbxOopHandle readCompOopHandle(long address) throws DebuggerException;
- public long[] getThreadIntegerRegisterSet(int tid) throws DebuggerException;
- public Address newAddress(long value) throws DebuggerException;
-
- // NOTE: this interface implicitly contains the following methods:
- // From the Debugger interface via JVMDebugger
- // public void attach(int processID) throws DebuggerException;
- // public void attach(String executableName, String coreFileName) throws DebuggerException;
- // public boolean detach();
- // public Address parseAddress(String addressString) throws NumberFormatException;
- // public long getAddressValue(Address addr) throws DebuggerException;
- // public String getOS();
- // public String getCPU();
- // From the SymbolLookup interface via Debugger and JVMDebugger
- // public Address lookup(String objectName, String symbol);
- // public OopHandle lookupOop(String objectName, String symbol);
- // From the JVMDebugger interface
- // public void configureJavaPrimitiveTypeSizes(long jbooleanSize,
- // long jbyteSize,
- // long jcharSize,
- // long jdoubleSize,
- // long jfloatSize,
- // long jintSize,
- // long jlongSize,
- // long jshortSize);
- // From the ThreadAccess interface via Debugger and JVMDebugger
- // public ThreadProxy getThreadForIdentifierAddress(Address addr);
- // public ThreadProxy getThreadForThreadId(long id);
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebuggerLocal.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,744 +0,0 @@
-/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.dbx.sparc.*;
-import sun.jvm.hotspot.debugger.dbx.x86.*;
-import sun.jvm.hotspot.debugger.cdbg.CDebugger;
-import sun.jvm.hotspot.utilities.*;
-
-/** <P> An implementation of the JVMDebugger interface which sits on
- top of dbx and relies on the SA's dbx import module for
- communication with the debugger. </P>
-
- <P> <B>NOTE</B> that since we have the notion of fetching "Java
- primitive types" from the remote process (which might have
- different sizes than we expect) we have a bootstrapping
- problem. We need to know the sizes of these types before we can
- fetch them. The current implementation solves this problem by
- requiring that it be configured with these type sizes before they
- can be fetched. The readJ(Type) routines here will throw a
- RuntimeException if they are called before the debugger is
- configured with the Java primitive type sizes. </P>
-*/
-
-public class DbxDebuggerLocal extends DebuggerBase implements DbxDebugger {
- // These may be set by DbxDebuggerRemote
- protected boolean unalignedAccessesOkay;
- protected DbxThreadFactory threadFactory;
-
- private String dbxPathName;
- private String[] dbxSvcAgentDSOPathNames;
- private Process dbxProcess;
- private StreamMonitor dbxOutStreamMonitor;
- private StreamMonitor dbxErrStreamMonitor;
- private PrintWriter dbxOstr;
- private PrintWriter out;
- private InputLexer in;
- private Socket importModuleSocket;
- private static final int PORT = 21928;
- private static final int LONG_TIMEOUT = 60000;
- private static final int DBX_MODULE_NOT_FOUND = 101;
- private static final int DBX_MODULE_LOADED = 102;
-
- //--------------------------------------------------------------------------------
- // Implementation of Debugger interface
- //
-
- /** <P> machDesc may be null if it couldn't be determined yet; i.e.,
- if we're on SPARC, we need to ask the remote process whether
- we're in 32- or 64-bit mode. </P>
-
- <P> useCache should be set to true if debugging is being done
- locally, and to false if the debugger is being created for the
- purpose of supporting remote debugging. </P> */
- public DbxDebuggerLocal(MachineDescription machDesc,
- String dbxPathName,
- String[] dbxSvcAgentDSOPathNames,
- boolean useCache) {
- this.machDesc = machDesc;
- this.dbxPathName = dbxPathName;
- this.dbxSvcAgentDSOPathNames = dbxSvcAgentDSOPathNames;
- int cacheNumPages;
- int cachePageSize;
- if (PlatformInfo.getCPU().equals("sparc")) {
- cacheNumPages = parseCacheNumPagesProperty(2048);
- cachePageSize = 8192;
- threadFactory = new DbxSPARCThreadFactory(this);
- } else if (PlatformInfo.getCPU().equals("x86")) {
- cacheNumPages = 4096;
- cachePageSize = 4096;
- threadFactory = new DbxX86ThreadFactory(this);
- unalignedAccessesOkay = true;
- } else {
- throw new RuntimeException("Thread access for CPU architecture " + PlatformInfo.getCPU() + " not yet supported");
- }
- if (useCache) {
- // Cache portion of the remote process's address space.
- // Fetching data over the socket connection to dbx is relatively
- // slow. For now, this cache works best if it covers the entire
- // heap of the remote process. FIXME: at least should make this
- // tunable from the outside, i.e., via the UI. This is a 16 MB
- // cache divided on SPARC into 2048 8K pages and on x86 into
- // 4096 4K pages; the page size must be adjusted to be the OS's
- // page size. (FIXME: should pick this up from the debugger.)
- initCache(cachePageSize, cacheNumPages);
- }
- }
-
- /** Only called by DbxDebuggerRemote */
- protected DbxDebuggerLocal() {
- }
-
- /** FIXME: implement this with a Runtime.exec() of ps followed by
- parsing of its output */
- public boolean hasProcessList() throws DebuggerException {
- return false;
- }
-
- public List getProcessList() throws DebuggerException {
- throw new DebuggerException("Not yet supported");
- }
-
- /** From the Debugger interface via JVMDebugger */
- public synchronized void attach(int processID) throws DebuggerException {
- try {
- launchProcess();
- dbxErrStreamMonitor.addTrigger("dbx: no process", 1);
- dbxErrStreamMonitor.addTrigger("dbx: Cannot open", 1);
- dbxErrStreamMonitor.addTrigger("dbx: Cannot find", DBX_MODULE_NOT_FOUND);
- dbxOstr = new PrintWriter(dbxProcess.getOutputStream(), true);
- dbxOstr.println("debug - " + processID);
- dbxOstr.println("kprint -u2 \\(ready\\)");
- boolean seen = dbxErrStreamMonitor.waitFor("(ready)", LONG_TIMEOUT);
- if (!seen) {
- detach();
- throw new DebuggerException("Timed out while connecting to process " + processID);
- }
- List retVals = dbxErrStreamMonitor.getTriggersSeen();
- if (retVals.contains(new Integer(1))) {
- detach();
- throw new DebuggerException("No such process " + processID);
- }
-
- // Throws DebuggerException upon failure
- importDbxModule();
-
- dbxOstr.println("svc_agent_run");
-
- connectToImportModule();
-
- // Set "fail fast" mode on process memory reads
- printlnToOutput("peek_fail_fast 1");
- }
- catch (IOException e) {
- detach();
- throw new DebuggerException("Error while connecting to dbx process", e);
- }
- }
-
- /** From the Debugger interface via JVMDebugger */
- public synchronized void attach(String executableName, String coreFileName) throws DebuggerException {
- try {
- launchProcess();
- // Missing executable
- dbxErrStreamMonitor.addTrigger("dbx: Cannot open", 1);
- // Missing core file
- dbxErrStreamMonitor.addTrigger("dbx: can't read", 2);
- // Corrupt executable
- dbxErrStreamMonitor.addTrigger("dbx: File", 3);
- // Corrupt core file
- dbxErrStreamMonitor.addTrigger("dbx: Unable to read", 4);
- // Mismatched core and executable
- dbxErrStreamMonitor.addTrigger("dbx: core object name", 5);
- // Missing loadobject
- dbxErrStreamMonitor.addTrigger("dbx: can't stat", 6);
- // Successful load of svc module
- dbxOstr = new PrintWriter(dbxProcess.getOutputStream(), true);
- dbxOstr.println("debug " + executableName + " " + coreFileName);
- dbxOstr.println("kprint -u2 \\(ready\\)");
- boolean seen = dbxErrStreamMonitor.waitFor("(ready)", LONG_TIMEOUT);
- if (!seen) {
- detach();
- throw new DebuggerException("Timed out while attaching to core file");
- }
- List retVals = dbxErrStreamMonitor.getTriggersSeen();
- if (retVals.size() > 0) {
- detach();
-
- if (retVals.contains(new Integer(1))) {
- throw new DebuggerException("Can not find executable \"" + executableName + "\"");
- } else if (retVals.contains(new Integer(2))) {
- throw new DebuggerException("Can not find core file \"" + coreFileName + "\"");
- } else if (retVals.contains(new Integer(3))) {
- throw new DebuggerException("Corrupt executable \"" + executableName + "\"");
- } else if (retVals.contains(new Integer(4))) {
- throw new DebuggerException("Corrupt core file \"" + coreFileName + "\"");
- } else if (retVals.contains(new Integer(5))) {
- throw new DebuggerException("Mismatched core file/executable \"" + coreFileName + "\"/\"" + executableName + "\"");
- } else {
- throw new DebuggerException("Couldn't find all loaded libraries for executable \"" + executableName + "\"");
- }
- }
-
- // Throws DebuggerException upon failure
- importDbxModule();
-
- dbxOstr.println("svc_agent_run");
-
- connectToImportModule();
-
- // Set "fail fast" mode on process memory reads
- printlnToOutput("peek_fail_fast 1");
- }
- catch (IOException e) {
- detach();
- throw new DebuggerException("Error while connecting to dbx process", e);
- }
- }
-
- /** From the Debugger interface via JVMDebugger */
- public synchronized boolean detach() {
- try {
- if (dbxProcess == null) {
- return false;
- }
-
- if (out != null && dbxOstr != null) {
- printlnToOutput("exit");
- dbxOstr.println("exit");
-
- // Wait briefly for the process to exit (FIXME: should make this
- // nicer)
- try {
- Thread.sleep(500);
- }
- catch (InterruptedException e) {
- }
- }
-
- shutdown();
-
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- }
-
- /** From the Debugger interface via JVMDebugger */
- public Address parseAddress(String addressString) throws NumberFormatException {
- long addr = utils.scanAddress(addressString);
- if (addr == 0) {
- return null;
- }
- return new DbxAddress(this, addr);
- }
-
- /** From the Debugger interface via JVMDebugger */
- public String getOS() {
- return PlatformInfo.getOS();
- }
-
- /** From the Debugger interface via JVMDebugger */
- public String getCPU() {
- return PlatformInfo.getCPU();
- }
-
- public boolean hasConsole() throws DebuggerException {
- return true;
- }
-
- public synchronized String consoleExecuteCommand(String cmd) throws DebuggerException {
- try {
- // A little tricky. We need to cause the dbx import module to
- // exit, then print our command on dbx's stdin along with a
- // command which will allow our StreamMonitors to
- // resynchronize. We need save the output from the StreamMonitors
- // along the way.
- printlnToOutput("exit");
- importModuleSocket.close();
- importModuleSocket = null;
- out = null;
- in = null;
- dbxOstr.println("kprint \\(ready\\)");
- dbxOstr.flush();
- dbxOutStreamMonitor.waitFor("(ready)", LONG_TIMEOUT);
-
- dbxOutStreamMonitor.startCapture();
- dbxErrStreamMonitor.startCapture();
- dbxOstr.println(cmd);
- dbxOstr.println("kprint \\(ready\\)");
- dbxOutStreamMonitor.waitFor("(ready)", LONG_TIMEOUT);
- String result = dbxOutStreamMonitor.stopCapture();
- String result2 = dbxErrStreamMonitor.stopCapture();
- result = result + result2;
- // Cut out the "(ready)" string
- StringBuffer outBuf = new StringBuffer(result.length());
- BufferedReader reader = new BufferedReader(new StringReader(result));
- // FIXME: bug in BufferedReader? readLine returns null when
- // ready() returns true.
- String line = null;
- do {
- line = reader.readLine();
- if ((line != null) && (!line.equals("(ready)"))) {
- outBuf.append(line);
- outBuf.append("\n");
- }
- } while (line != null);
- dbxOstr.println("svc_agent_run");
- dbxOstr.flush();
-
- connectToImportModule();
-
- return outBuf.toString();
- }
- catch (IOException e) {
- detach();
- throw new DebuggerException("Error while executing command on dbx console", e);
- }
- }
-
- public String getConsolePrompt() throws DebuggerException {
- return "(dbx) ";
- }
-
- public CDebugger getCDebugger() throws DebuggerException {
- return null;
- }
-
- /** From the SymbolLookup interface via Debugger and JVMDebugger */
- public synchronized Address lookup(String objectName, String symbol) {
- long addr = lookupInProcess(objectName, symbol);
- if (addr == 0) {
- return null;
- }
- return new DbxAddress(this, addr);
- }
-
- /** From the SymbolLookup interface via Debugger and JVMDebugger */
- public synchronized OopHandle lookupOop(String objectName, String symbol) {
- long addr = lookupInProcess(objectName, symbol);
- if (addr == 0) {
- return null;
- }
- return new DbxOopHandle(this, addr);
- }
-
- /** From the Debugger interface */
- public MachineDescription getMachineDescription() {
- return machDesc;
- }
-
- /** Internal routine supporting lazy setting of MachineDescription,
- since on SPARC we will need to query the remote process to ask
- it what its data model is (32- or 64-bit). NOTE that this is NOT
- present in the DbxDebugger interface because it should not be
- called across the wire (until we support attaching to multiple
- remote processes via RMI -- see the documentation for
- DbxDebuggerRemoteIntf.) */
- public void setMachineDescription(MachineDescription machDesc) {
- this.machDesc = machDesc;
- setBigEndian(machDesc.isBigEndian());
- utils = new DebuggerUtilities(machDesc.getAddressSize(), machDesc.isBigEndian());
- }
-
- /** Internal routine which queries the remote process about its data
- model -- i.e., size of addresses. Returns -1 upon error.
- Currently supported return values are 32 and 64. NOTE that this
- is NOT present in the DbxDebugger interface because it should
- not be called across the wire (until we support attaching to
- multiple remote processes via RMI -- see the documentation for
- DbxDebuggerRemoteIntf.) */
- public int getRemoteProcessAddressSize() {
- if (dbxProcess == null) {
- throw new RuntimeException("Not attached to remote process");
- }
-
- try {
- printlnToOutput("address_size");
- int i = in.parseInt();
- return i;
- }
- catch (IOException e) {
- return -1;
- }
- }
-
- //--------------------------------------------------------------------------------
- // Implementation of ThreadAccess interface
- //
-
- /** From the ThreadAccess interface via Debugger and JVMDebugger */
- public ThreadProxy getThreadForIdentifierAddress(Address addr) {
- return threadFactory.createThreadWrapper(addr);
- }
-
- public ThreadProxy getThreadForThreadId(long id) {
- return threadFactory.createThreadWrapper(id);
- }
-
- //----------------------------------------------------------------------
- // Overridden from DebuggerBase because we need to relax alignment
- // constraints on x86
-
- public long readJLong(long address)
- throws UnmappedAddressException, UnalignedAddressException {
- checkJavaConfigured();
- // FIXME: allow this to be configurable. Undesirable to add a
- // dependency on the runtime package here, though, since this
- // package should be strictly underneath it.
- if (unalignedAccessesOkay) {
- utils.checkAlignment(address, jintSize);
- } else {
- utils.checkAlignment(address, jlongSize);
- }
- byte[] data = readBytes(address, jlongSize);
- return utils.dataToJLong(data, jlongSize);
- }
-
- //--------------------------------------------------------------------------------
- // Internal routines (for implementation of DbxAddress).
- // These must not be called until the MachineDescription has been set up.
- //
-
- /** From the DbxDebugger interface */
- public String addressValueToString(long address) {
- return utils.addressValueToString(address);
- }
-
- /** Need to override this to relax alignment checks on Solaris/x86. */
- public long readCInteger(long address, long numBytes, boolean isUnsigned)
- throws UnmappedAddressException, UnalignedAddressException {
- checkConfigured();
- if (!unalignedAccessesOkay) {
- utils.checkAlignment(address, numBytes);
- } else {
- // Only slightly relaxed semantics -- this is a hack, but is
- // necessary on Solaris/x86 where it seems the compiler is
- // putting some global 64-bit data on 32-bit boundaries
- if (numBytes == 8) {
- utils.checkAlignment(address, 4);
- } else {
- utils.checkAlignment(address, numBytes);
- }
- }
- byte[] data = readBytes(address, numBytes);
- return utils.dataToCInteger(data, isUnsigned);
- }
-
- /** From the DbxDebugger interface */
- public DbxAddress readAddress(long address)
- throws UnmappedAddressException, UnalignedAddressException {
- long value = readAddressValue(address);
- return (value == 0 ? null : new DbxAddress(this, value));
- }
-
- public DbxAddress readCompOopAddress(long address)
- throws UnmappedAddressException, UnalignedAddressException {
- long value = readCompOopAddressValue(address);
- return (value == 0 ? null : new DbxAddress(this, value));
- }
-
- /** From the DbxDebugger interface */
- public DbxOopHandle readOopHandle(long address)
- throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
- long value = readAddressValue(address);
- return (value == 0 ? null : new DbxOopHandle(this, value));
- }
- public DbxOopHandle readCompOopHandle(long address)
- throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
- long value = readCompOopAddressValue(address);
- return (value == 0 ? null : new DbxOopHandle(this, value));
- }
-
- //--------------------------------------------------------------------------------
- // Thread context access. Can not be package private, but should
- // only be accessed by the architecture-specific subpackages.
-
- /** From the DbxDebugger interface. May have to redefine this later. */
- public synchronized long[] getThreadIntegerRegisterSet(int tid) {
- try {
- printlnToOutput("thr_gregs " + tid);
- int num = in.parseInt();
- long[] res = new long[num];
- for (int i = 0; i < num; i++) {
- res[i] = in.parseAddress();
- }
- return res;
- }
- catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- //--------------------------------------------------------------------------------
- // Address access. Can not be package private, but should only be
- // accessed by the architecture-specific subpackages.
-
- /** From the Debugger interface */
- public long getAddressValue(Address addr) {
- if (addr == null) return 0;
- return ((DbxAddress) addr).getValue();
- }
-
- /** From the DbxDebugger interface */
- public Address newAddress(long value) {
- if (value == 0) return null;
- return new DbxAddress(this, value);
- }
-
- //--------------------------------------------------------------------------------
- // Internals only below this point
- //
-
- private void launchProcess() throws IOException {
- dbxProcess = Runtime.getRuntime().exec(dbxPathName);
- // dbxOutStreamMonitor = new StreamMonitor(dbxProcess.getInputStream());
- // dbxErrStreamMonitor = new StreamMonitor(dbxProcess.getErrorStream());
- dbxOutStreamMonitor = new StreamMonitor(dbxProcess.getInputStream(), "dbx stdout", true);
- dbxErrStreamMonitor = new StreamMonitor(dbxProcess.getErrorStream(), "dbx stderr", true);
- }
-
- /** Requires that dbxErrStreamMonitor has a trigger on "dbx: Cannot
- find" with number DBX_MODULE_NOT_FOUND as well as one on "dbx:
- warning:" (plus the serviceability agent's dbx module path name,
- to avoid conflation with inability to load individual object
- files) with number DBX_MODULE_FAILED_TO_LOAD. The former
- indicates an absence of libsvc_agent_dbx.so, while the latter
- indicates that the module failed to load, specifically because
- the architecture was mismatched. (I don't see a way to detect
- from the dbx command prompt whether it's running the v8 or v9
- executbale, so we try to import both flavors of the import
- module; the "v8" file name convention doesn't actually include
- the v8 prefix, so this code should work for Intel as well.) */
- private void importDbxModule() throws DebuggerException {
- // Trigger for a successful load
- dbxOutStreamMonitor.addTrigger("Defining svc_agent_run", DBX_MODULE_LOADED);
- for (int i = 0; i < dbxSvcAgentDSOPathNames.length; i++) {
- dbxOstr.println("import " + dbxSvcAgentDSOPathNames[i]);
- dbxOstr.println("kprint -u2 \\(Ready\\)");
- boolean seen = dbxErrStreamMonitor.waitFor("(Ready)", LONG_TIMEOUT);
- if (!seen) {
- detach();
- throw new DebuggerException("Timed out while importing dbx module from file\n" + dbxSvcAgentDSOPathNames[i]);
- }
- List retVals = dbxErrStreamMonitor.getTriggersSeen();
- if (retVals.contains(new Integer(DBX_MODULE_NOT_FOUND))) {
- detach();
- throw new DebuggerException("Unable to find the Serviceability Agent's dbx import module at pathname \"" +
- dbxSvcAgentDSOPathNames[i] + "\"");
- } else {
- retVals = dbxOutStreamMonitor.getTriggersSeen();
- if (retVals.contains(new Integer(DBX_MODULE_LOADED))) {
- System.out.println("importDbxModule: imported " + dbxSvcAgentDSOPathNames[i]);
- return;
- }
- }
- }
-
- // Failed to load all flavors
- detach();
- String errMsg = ("Unable to find a version of the Serviceability Agent's dbx import module\n" +
- "matching the architecture of dbx at any of the following locations:");
- for (int i = 0; i < dbxSvcAgentDSOPathNames.length; i++) {
- errMsg = errMsg + "\n" + dbxSvcAgentDSOPathNames[i];
- }
- throw new DebuggerException(errMsg);
- }
-
- /** Terminate the debugger forcibly */
- private void shutdown() {
-
- if (dbxProcess != null) {
- // See whether the process has exited and, if not, terminate it
- // forcibly
- try {
- dbxProcess.exitValue();
- }
- catch (IllegalThreadStateException e) {
- dbxProcess.destroy();
- }
- }
-
- try {
- if (importModuleSocket != null) {
- importModuleSocket.close();
- }
- }
- catch (IOException e) {
- }
-
- // Release references to all objects
- clear();
- clearCache();
- }
-
- /** Looks up an address in the remote process's address space.
- Returns 0 if symbol not found or upon error. Package private to
- allow DbxDebuggerRemoteIntfImpl access. */
- synchronized long lookupInProcess(String objectName, String symbol) {
- try {
- printlnToOutput("lookup " + objectName + " " + symbol);
- return in.parseAddress();
- }
- catch (Exception e) {
- return 0;
- }
- }
-
- /** This reads bytes from the remote process. */
- public synchronized ReadResult readBytesFromProcess(long address, long numBytes)
- throws DebuggerException {
- if (numBytes < 0) {
- throw new DebuggerException("Can not read negative number (" + numBytes + ") of bytes from process");
- }
- try {
- String cmd = "peek " + utils.addressValueToString(address) + " " + numBytes;
- printlnToOutput(cmd);
- while (in.readByte() != 'B') {
- }
- byte res = in.readByte();
- if (res == 0) {
- System.err.println("Failing command: " + cmd);
- throw new DebuggerException("Read of remote process address space failed");
- }
- // NOTE: must read ALL of the data regardless of whether we need
- // to throw an UnmappedAddressException. Otherwise will corrupt
- // the input stream each time we have a failure. Not good. Do
- // not want to risk "flushing" the input stream in case a huge
- // read has a hangup in the middle and we leave data on the
- // stream.
- byte[] buf = new byte[(int) numBytes];
- boolean bailOut = false;
- long failureAddress = 0;
- int numReads = 0;
- while (numBytes > 0) {
- long len = in.readUnsignedInt();
- boolean isMapped = ((in.readByte() == 0) ? false : true);
- if (!isMapped) {
- if (!bailOut) {
- bailOut = true;
- failureAddress = address;
- }
- } else {
- // This won't work if we have unmapped regions, but if we do
- // then we're going to throw an exception anyway
-
- // NOTE: there is a factor of 20 speed difference between
- // these two ways of doing this read.
- in.readBytes(buf, 0, (int) len);
- }
-
- // Do NOT do this:
- // for (int i = 0; i < (int) len; i++) {
- // buf[i] = in.readByte();
- // }
-
- numBytes -= len;
- address += len;
- ++numReads;
- }
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(numBytes == 0, "Bug in debug server's implementation of peek: numBytesLeft == " +
- numBytes + ", should be 0 (did " + numReads + " reads)");
- }
- if (bailOut) {
- return new ReadResult(failureAddress);
- }
- return new ReadResult(buf);
- }
- catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- public void writeBytesToProcess(long address, long numBytes, byte[] data)
- throws UnmappedAddressException, DebuggerException {
- // FIXME
- throw new DebuggerException("Unimplemented");
- }
-
- /** This provides DbxDebuggerRemoteIntfImpl access to readBytesFromProcess */
- ReadResult readBytesFromProcessInternal(long address, long numBytes)
- throws DebuggerException {
- return readBytesFromProcess(address, numBytes);
- }
-
- /** Convenience routine */
- private void printlnToOutput(String s) throws IOException {
- out.println(s);
- if (out.checkError()) {
- throw new IOException("Error occurred while writing to debug server");
- }
- }
-
- private void clear() {
- dbxProcess = null;
- dbxOstr = null;
- out = null;
- in = null;
- importModuleSocket = null;
- }
-
- /** Connects to the dbx import module, setting up out and in
- streams. Factored out to allow access to the dbx console. */
- private void connectToImportModule() throws IOException {
- // Try for 20 seconds to connect to dbx import module; time out
- // with failure if didn't succeed
- importModuleSocket = null;
- long endTime = System.currentTimeMillis() + LONG_TIMEOUT;
-
- while ((importModuleSocket == null) && (System.currentTimeMillis() < endTime)) {
- try {
- importModuleSocket = new Socket(InetAddress.getLocalHost(), PORT);
- importModuleSocket.setTcpNoDelay(true);
- }
- catch (IOException e) {
- // Swallow IO exceptions while attempting connection
- try {
- // Don't swamp the CPU
- Thread.sleep(1000);
- }
- catch (InterruptedException ex) {
- }
- }
- }
-
- if (importModuleSocket == null) {
- // Failed to connect because of timeout
- detach();
- throw new DebuggerException("Timed out while attempting to connect to remote dbx process");
- }
-
- out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(importModuleSocket.getOutputStream(), "US-ASCII")), true);
- in = new InputLexer(new BufferedInputStream(importModuleSocket.getInputStream()));
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxOopHandle.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx;
-
-import sun.jvm.hotspot.debugger.*;
-
-class DbxOopHandle extends DbxAddress implements OopHandle {
- DbxOopHandle(DbxDebugger debugger, long addr) {
- super(debugger, addr);
- }
-
- public Address addOffsetTo (long offset) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("addOffsetTo not applicable to OopHandles (interior object pointers not allowed)");
- }
-
- public Address andWithMask(long mask) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("andWithMask not applicable to OopHandles (i.e., anything but C addresses)");
- }
-
- public Address orWithMask(long mask) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("orWithMask not applicable to OopHandles (i.e., anything but C addresses)");
- }
-
- public Address xorWithMask(long mask) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("xorWithMask not applicable to OopHandles (i.e., anything but C addresses)");
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxThreadFactory.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx;
-
-import sun.jvm.hotspot.debugger.*;
-
-/** An interface used only internally by the DbxDebugger to be able to
- create platform-specific Thread objects */
-
-public interface DbxThreadFactory {
- public ThreadProxy createThreadWrapper(Address threadIdentifierAddr);
- public ThreadProxy createThreadWrapper(long id);
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/sparc/DbxSPARCThread.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx.sparc;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.sparc.*;
-import sun.jvm.hotspot.debugger.dbx.*;
-import sun.jvm.hotspot.utilities.*;
-
-public class DbxSPARCThread implements ThreadProxy {
- private DbxDebugger debugger;
- private int id;
-
- public DbxSPARCThread(DbxDebugger debugger, Address addr) {
- this.debugger = debugger;
-
- // FIXME: the size here should be configurable. However, making it
- // so would produce a dependency on the "types" package from the
- // debugger package, which is not desired.
- this.id = (int) addr.getCIntegerAt(0, 4, true);
- }
-
- public DbxSPARCThread(DbxDebugger debugger, long id) {
- this.debugger = debugger;
- this.id = (int) id;
- }
-
- public boolean equals(Object obj) {
- if ((obj == null) || !(obj instanceof DbxSPARCThread)) {
- return false;
- }
-
- return (((DbxSPARCThread) obj).id == id);
- }
-
- public int hashCode() {
- return id;
- }
-
- public ThreadContext getContext() throws IllegalThreadStateException {
- DbxSPARCThreadContext context = new DbxSPARCThreadContext(debugger);
- long[] regs = debugger.getThreadIntegerRegisterSet(id);
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(regs.length == SPARCThreadContext.NPRGREG, "size of register set must match");
- }
- for (int i = 0; i < regs.length; i++) {
- context.setRegister(i, regs[i]);
- }
- return context;
- }
-
- public boolean canSetContext() throws DebuggerException {
- return false;
- }
-
- public void setContext(ThreadContext context)
- throws IllegalThreadStateException, DebuggerException {
- throw new DebuggerException("Unimplemented");
- }
-
- public String toString() {
- return "t@" + id;
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/sparc/DbxSPARCThreadContext.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx.sparc;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.sparc.*;
-import sun.jvm.hotspot.debugger.dbx.*;
-
-public class DbxSPARCThreadContext extends SPARCThreadContext {
- private DbxDebugger debugger;
-
- public DbxSPARCThreadContext(DbxDebugger debugger) {
- super();
- this.debugger = debugger;
- }
-
- public void setRegisterAsAddress(int index, Address value) {
- setRegister(index, debugger.getAddressValue(value));
- }
-
- public Address getRegisterAsAddress(int index) {
- return debugger.newAddress(getRegister(index));
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/sparc/DbxSPARCThreadFactory.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx.sparc;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.dbx.*;
-
-public class DbxSPARCThreadFactory implements DbxThreadFactory {
- private DbxDebugger debugger;
-
- public DbxSPARCThreadFactory(DbxDebugger debugger) {
- this.debugger = debugger;
- }
-
- public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
- return new DbxSPARCThread(debugger, threadIdentifierAddr);
- }
-
- public ThreadProxy createThreadWrapper(long id) {
- return new DbxSPARCThread(debugger, id);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/x86/DbxX86Thread.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx.x86;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.x86.*;
-import sun.jvm.hotspot.debugger.dbx.*;
-import sun.jvm.hotspot.utilities.*;
-
-public class DbxX86Thread implements ThreadProxy {
- private DbxDebugger debugger;
- private int id;
-
- public DbxX86Thread(DbxDebugger debugger, Address addr) {
- this.debugger = debugger;
-
- // FIXME: the size here should be configurable. However, making it
- // so would produce a dependency on the "types" package from the
- // debugger package, which is not desired.
- this.id = (int) addr.getCIntegerAt(0, 4, true);
- }
-
- public DbxX86Thread(DbxDebugger debugger, long id) {
- this.debugger = debugger;
- this.id = (int) id;
- }
-
- public boolean equals(Object obj) {
- if ((obj == null) || !(obj instanceof DbxX86Thread)) {
- return false;
- }
-
- return (((DbxX86Thread) obj).id == id);
- }
-
- public int hashCode() {
- return id;
- }
-
- public ThreadContext getContext() throws IllegalThreadStateException {
- DbxX86ThreadContext context = new DbxX86ThreadContext(debugger);
- long[] regs = debugger.getThreadIntegerRegisterSet(id);
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(regs.length == 19, "unknown size of register set -- adjust this code");
- }
- for (int i = 0; i < regs.length; i++) {
- context.setRegister(i, regs[i]);
- }
- return context;
- }
-
- public boolean canSetContext() throws DebuggerException {
- return false;
- }
-
- public void setContext(ThreadContext context)
- throws IllegalThreadStateException, DebuggerException {
- throw new DebuggerException("Unimplemented");
- }
-
- public String toString() {
- return "t@" + id;
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/x86/DbxX86ThreadContext.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx.x86;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.x86.*;
-import sun.jvm.hotspot.debugger.dbx.*;
-
-public class DbxX86ThreadContext extends X86ThreadContext {
- private DbxDebugger debugger;
-
- public DbxX86ThreadContext(DbxDebugger debugger) {
- super();
- this.debugger = debugger;
- }
-
- public void setRegisterAsAddress(int index, Address value) {
- setRegister(index, debugger.getAddressValue(value));
- }
-
- public Address getRegisterAsAddress(int index) {
- return debugger.newAddress(getRegister(index));
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/x86/DbxX86ThreadFactory.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.dbx.x86;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.dbx.*;
-
-public class DbxX86ThreadFactory implements DbxThreadFactory {
- private DbxDebugger debugger;
-
- public DbxX86ThreadFactory(DbxDebugger debugger) {
- this.debugger = debugger;
- }
-
- public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
- return new DbxX86Thread(debugger, threadIdentifierAddr);
- }
-
- public ThreadProxy createThreadWrapper(long id) {
- return new DbxX86Thread(debugger, id);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/AddressDataSource.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.io.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.win32.coff.*;
-
-class AddressDataSource implements DataSource {
- AddressDataSource(Address addr) {
- this.addr = addr;
- offset = 0;
- }
-
- public byte readByte() throws IOException {
- try {
- byte res = (byte) addr.getCIntegerAt(offset, 1, false);
- ++offset;
- return res;
- } catch (UnmappedAddressException e) {
- throw (IOException) new IOException("Unmapped address at 0x" + Long.toHexString(e.getAddress())).initCause(e);
- } catch (DebuggerException e) {
- throw (IOException) new IOException(e.toString()).initCause(e);
- }
- }
-
- public short readShort() throws IOException {
- // NOTE: byte swapping is taken care of at the COFFFileImpl level
- int b1 = readByte() & 0xFF;
- int b2 = readByte() & 0xFF;
- return (short) ((b1 << 8) | b2);
- }
-
- public int readInt() throws IOException {
- // NOTE: byte swapping is taken care of at the COFFFileImpl level
- int b1 = ((int) readByte()) & 0xFF;
- int b2 = ((int) readByte()) & 0xFF;
- int b3 = ((int) readByte()) & 0xFF;
- int b4 = ((int) readByte()) & 0xFF;
- return ((b1 << 24) | (b2 << 16) | (b3 << 8) | b4);
- }
-
- public long readLong() throws IOException {
- // NOTE: byte swapping is taken care of at the COFFFileImpl level
- long b1 = ((long) readByte()) & 0xFFL;
- long b2 = ((long) readByte()) & 0xFFL;
- long b3 = ((long) readByte()) & 0xFFL;
- long b4 = ((long) readByte()) & 0xFFL;
- long b5 = ((long) readByte()) & 0xFFL;
- long b6 = ((long) readByte()) & 0xFFL;
- long b7 = ((long) readByte()) & 0xFFL;
- long b8 = ((long) readByte()) & 0xFFL;
- return (((((b1 << 24) | (b2 << 16) | (b3 << 8) | b4)) << 32) |
- ((((b5 << 24) | (b6 << 16) | (b7 << 8) | b8))));
- }
-
- public int read(byte[] b) throws IOException {
- for (int i = 0; i < b.length; i++) {
- b[i] = readByte();
- }
- return b.length;
- }
-
- public void seek(long pos) throws IOException {
- offset = pos;
- }
-
- public long getFilePointer() throws IOException {
- return offset;
- }
-
- public void close() throws IOException {
- }
-
- private Address addr;
- private long offset;
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/DLL.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.win32.coff.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.utilities.Assert;
-import sun.jvm.hotspot.utilities.memo.*;
-
-/** Provides a simple wrapper around the COFF library which handles
- relocation. A DLL can represent either a DLL or an EXE file. */
-
-class DLL implements LoadObject {
-
- DLL(Win32Debugger dbg, String filename, long size, Address relocation) throws COFFException {
- this.dbg = dbg;
- fullPathName = filename;
- this.size = size;
- file = new MemoizedObject() {
- public Object computeValue() {
- return COFFFileParser.getParser().parse(fullPathName);
- }
- };
- addr = relocation;
- }
-
- /** This constructor was originally used to fetch the DLL's name out
- of the target process to match it up with the known DLL names,
- before the fetching of the DLL names and bases was folded into
- one command. It is no longer used. If it is used, getName() will
- return null and getSize() will return 0. */
- DLL(Address base) throws COFFException {
- this.addr = base;
- file = new MemoizedObject() {
- public Object computeValue() {
- return COFFFileParser.getParser().parse(new AddressDataSource(addr));
- }
- };
- }
-
- /** Indicates whether this is really a DLL or actually a .EXE
- file. */
- boolean isDLL() {
- return getFile().getHeader().hasCharacteristic(Characteristics.IMAGE_FILE_DLL);
- }
-
- /** Look up a symbol; returns absolute address or null if symbol was
- not found. */
- Address lookupSymbol(String symbol) throws COFFException {
- if (!isDLL()) {
- return null;
- }
- ExportDirectoryTable exports = getExportDirectoryTable();
- return lookupSymbol(symbol, exports,
- 0, exports.getNumberOfNamePointers() - 1);
- }
-
- public Address getBase() {
- return addr;
- }
-
- /** Returns the full path name of this DLL/EXE, or null if this DLL
- object was created by parsing the target process's address
- space. */
- public String getName() {
- return fullPathName;
- }
-
- public long getSize() {
- return size;
- }
-
- public CDebugInfoDataBase getDebugInfoDataBase() throws DebuggerException {
- if (db != null) {
- return db;
- }
-
- // Try to parse
- if (dbg == null) {
- return null; // Need Win32Debugger
- }
-
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(fullPathName != null, "Need full path name to build debug info database");
- }
-
- db = new Win32CDebugInfoBuilder(dbg).buildDataBase(fullPathName, addr);
- return db;
- }
-
- public BlockSym debugInfoForPC(Address pc) throws DebuggerException {
- CDebugInfoDataBase db = getDebugInfoDataBase();
- if (db == null) {
- return null;
- }
- return db.debugInfoForPC(pc);
- }
-
- public ClosestSymbol closestSymbolToPC(Address pcAsAddr) throws DebuggerException {
- ExportDirectoryTable exports = getExportDirectoryTable();
- if (exports == null) {
- return null;
- }
- String name = null;
- long pc = dbg.getAddressValue(pcAsAddr);
- long diff = Long.MAX_VALUE;
- long base = dbg.getAddressValue(addr);
- for (int i = 0; i < exports.getNumberOfNamePointers(); i++) {
- if (!exports.isExportAddressForwarder(exports.getExportOrdinal(i))) {
- long tmp = base + (exports.getExportAddress(exports.getExportOrdinal(i)) & 0xFFFFFFFF);
- if ((tmp <= pc) && ((pc - tmp) < diff)) {
- diff = pc - tmp;
- name = exports.getExportName(i);
- }
- }
- }
- if (name == null) {
- return null;
- }
- return new ClosestSymbol(name, diff);
- }
-
- public LineNumberInfo lineNumberForPC(Address pc) throws DebuggerException {
- CDebugInfoDataBase db = getDebugInfoDataBase();
- if (db == null) {
- return null;
- }
- return db.lineNumberForPC(pc);
- }
-
- void close() {
- getFile().close();
- file = null;
- }
-
- //----------------------------------------------------------------------
- // Internals only below this point
- //
-
- private COFFFile getFile() {
- return (COFFFile) file.getValue();
- }
-
- private Address lookupSymbol(String symbol, ExportDirectoryTable exports,
- int loIdx, int hiIdx) {
- do {
- int curIdx = ((loIdx + hiIdx) >> 1);
- String cur = exports.getExportName(curIdx);
- if (symbol.equals(cur)) {
- return addr.addOffsetTo(
- ((long) exports.getExportAddress(exports.getExportOrdinal(curIdx))) & 0xFFFFFFFFL
- );
- }
- if (symbol.compareTo(cur) < 0) {
- if (hiIdx == curIdx) {
- hiIdx = curIdx - 1;
- } else {
- hiIdx = curIdx;
- }
- } else {
- if (loIdx == curIdx) {
- loIdx = curIdx + 1;
- } else {
- loIdx = curIdx;
- }
- }
- } while (loIdx <= hiIdx);
-
- return null;
- }
-
- private ExportDirectoryTable getExportDirectoryTable() {
- return
- getFile().getHeader().getOptionalHeader().getDataDirectories().getExportDirectoryTable();
- }
-
- private Win32Debugger dbg;
- private String fullPathName;
- private long size;
- // MemoizedObject contains a COFFFile
- private MemoizedObject file;
- // Base address of module in target process
- private Address addr;
- // Debug info database for this DLL
- private CDebugInfoDataBase db;
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/TestDebugger.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-
-public class TestDebugger {
- private static void usage() {
- System.out.println("usage: java TestDebugger [pid]");
- System.exit(1);
- }
-
- public static void main(String[] args) {
- try {
- if (args.length != 1) {
- usage();
- }
-
- int pid = 0;
- try {
- pid = Integer.parseInt(args[0]);
- }
- catch (NumberFormatException e) {
- usage();
- }
-
- JVMDebugger debugger = new Win32DebuggerLocal(new MachineDescriptionIntelX86(), true);
- System.err.println("Process list: ");
- List processes = debugger.getProcessList();
- for (Iterator iter = processes.iterator(); iter.hasNext(); ) {
- ProcessInfo info = (ProcessInfo) iter.next();
- System.err.println(info.getPid() + " " + info.getName());
- }
- System.err.println("Trying to attach...");
- debugger.attach(pid);
- System.err.println("Attach succeeded.");
- System.err.println("Trying to detach...");
- if (!debugger.detach()) {
- System.err.println("ERROR: detach failed.");
- System.exit(0);
- }
- System.err.println("Detach succeeded.");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/TestHelloWorld.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-
-/** Tests to see whether we can find the "Hello, World" string in a
- target process */
-
-public class TestHelloWorld {
- private static void usage() {
- System.out.println("usage: java TestHelloWorld [pid]");
- System.out.println("pid must be the process ID of the HelloWorldDLL programs");
- System.exit(1);
- }
-
- public static void main(String[] args) {
- try {
- if (args.length != 1) {
- usage();
- }
-
- int pid = 0;
- try {
- pid = Integer.parseInt(args[0]);
- }
- catch (NumberFormatException e) {
- usage();
- }
-
- JVMDebugger debugger = new Win32DebuggerLocal(new MachineDescriptionIntelX86(), true);
- System.err.println("Trying to attach...");
- debugger.attach(pid);
- System.err.println("Attach succeeded.");
- Address addr = debugger.lookup("helloworld.dll", "helloWorldString");
- System.err.println("helloWorldString address = " + addr);
- System.err.println("Trying to detach...");
- if (!debugger.detach()) {
- System.err.println("ERROR: detach failed.");
- System.exit(0);
- }
- System.err.println("Detach succeeded.");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Address.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,403 +0,0 @@
-/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import sun.jvm.hotspot.debugger.*;
-
-class Win32Address implements Address {
- protected Win32Debugger debugger;
- protected long addr;
-
- Win32Address(Win32Debugger debugger, long addr) {
- this.debugger = debugger;
- this.addr = addr;
- }
-
- //
- // Basic Java routines
- //
-
- public boolean equals(Object arg) {
- if (arg == null) {
- return false;
- }
-
- if (!(arg instanceof Win32Address)) {
- return false;
- }
-
- return (addr == ((Win32Address) arg).addr);
- }
-
- public int hashCode() {
- // FIXME: suggestions on a better hash code?
- return (int) addr;
- }
-
- public String toString() {
- return debugger.addressValueToString(addr);
- }
-
- //
- // C/C++-related routines
- //
-
- public long getCIntegerAt(long offset, long numBytes, boolean isUnsigned) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readCInteger(addr + offset, numBytes, isUnsigned);
- }
-
- public Address getAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readAddress(addr + offset);
- }
-
- public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readCompOopAddress(addr + offset);
- }
-
- //
- // Java-related routines
- //
-
- public boolean getJBooleanAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJBoolean(addr + offset);
- }
-
- public byte getJByteAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJByte(addr + offset);
- }
-
- public char getJCharAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJChar(addr + offset);
- }
-
- public double getJDoubleAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJDouble(addr + offset);
- }
-
- public float getJFloatAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJFloat(addr + offset);
- }
-
- public int getJIntAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJInt(addr + offset);
- }
-
- public long getJLongAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJLong(addr + offset);
- }
-
- public short getJShortAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
- return debugger.readJShort(addr + offset);
- }
-
- public OopHandle getOopHandleAt(long offset)
- throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
- return debugger.readOopHandle(addr + offset);
- }
- public OopHandle getCompOopHandleAt(long offset)
- throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
- return debugger.readCompOopHandle(addr + offset);
- }
-
- //
- // C/C++-related mutators
- //
-
- public void setCIntegerAt(long offset, long numBytes, long value) {
- debugger.writeCInteger(addr + offset, numBytes, value);
- }
- public void setAddressAt(long offset, Address value) {
- debugger.writeAddress(addr + offset, (Win32Address) value);
- }
-
- //
- // Java-related mutators
- //
-
- public void setJBooleanAt (long offset, boolean value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJBoolean(addr + offset, value);
- }
- public void setJByteAt (long offset, byte value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJByte(addr + offset, value);
- }
- public void setJCharAt (long offset, char value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJChar(addr + offset, value);
- }
- public void setJDoubleAt (long offset, double value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJDouble(addr + offset, value);
- }
- public void setJFloatAt (long offset, float value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJFloat(addr + offset, value);
- }
- public void setJIntAt (long offset, int value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJInt(addr + offset, value);
- }
- public void setJLongAt (long offset, long value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJLong(addr + offset, value);
- }
- public void setJShortAt (long offset, short value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeJShort(addr + offset, value);
- }
- public void setOopHandleAt (long offset, OopHandle value)
- throws UnmappedAddressException, UnalignedAddressException {
- debugger.writeOopHandle(addr + offset, (Win32OopHandle) value);
- }
-
- //
- // Arithmetic operations -- necessary evil.
- //
-
- public Address addOffsetTo (long offset) throws UnsupportedOperationException {
- long value = addr + offset;
- if (value == 0) {
- return null;
- }
- return new Win32Address(debugger, value);
- }
-
- public OopHandle addOffsetToAsOopHandle(long offset) throws UnsupportedOperationException {
- long value = addr + offset;
- if (value == 0) {
- return null;
- }
- return new Win32OopHandle(debugger, value);
- }
-
- /** (FIXME: any signed/unsigned issues? Should this work for
- OopHandles?) */
- public long minus(Address arg) {
- if (arg == null) {
- return addr;
- }
- return addr - ((Win32Address) arg).addr;
- }
-
- // Two's complement representation.
- // All negative numbers are larger than positive numbers.
- // Numbers with the same sign can be compared normally.
- // Test harness is below in main().
-
- public boolean lessThan (Address a) {
- if (a == null) {
- return false;
- }
- Win32Address arg = (Win32Address) a;
- if ((addr >= 0) && (arg.addr < 0)) {
- return true;
- }
- if ((addr < 0) && (arg.addr >= 0)) {
- return false;
- }
- return (addr < arg.addr);
- }
-
- public boolean lessThanOrEqual (Address a) {
- if (a == null) {
- return false;
- }
- Win32Address arg = (Win32Address) a;
- if ((addr >= 0) && (arg.addr < 0)) {
- return true;
- }
- if ((addr < 0) && (arg.addr >= 0)) {
- return false;
- }
- return (addr <= arg.addr);
- }
-
- public boolean greaterThan (Address a) {
- if (a == null) {
- return true;
- }
- Win32Address arg = (Win32Address) a;
- if ((addr >= 0) && (arg.addr < 0)) {
- return false;
- }
- if ((addr < 0) && (arg.addr >= 0)) {
- return true;
- }
- return (addr > arg.addr);
- }
-
- public boolean greaterThanOrEqual(Address a) {
- if (a == null) {
- return true;
- }
- Win32Address arg = (Win32Address) a;
- if ((addr >= 0) && (arg.addr < 0)) {
- return false;
- }
- if ((addr < 0) && (arg.addr >= 0)) {
- return true;
- }
- return (addr >= arg.addr);
- }
-
- public Address andWithMask(long mask) throws UnsupportedOperationException {
- long value = addr & mask;
- if (value == 0) {
- return null;
- }
- return new Win32Address(debugger, value);
- }
-
- public Address orWithMask(long mask) throws UnsupportedOperationException {
- long value = addr | mask;
- if (value == 0) {
- return null;
- }
- return new Win32Address(debugger, value);
- }
-
- public Address xorWithMask(long mask) throws UnsupportedOperationException {
- long value = addr ^ mask;
- if (value == 0) {
- return null;
- }
- return new Win32Address(debugger, value);
- }
-
-
- //--------------------------------------------------------------------------------
- // Internals only below this point
- //
-
- long getValue() {
- return addr;
- }
-
-
- private static void check(boolean arg, String failMessage) {
- if (!arg) {
- System.err.println(failMessage + ": FAILED");
- System.exit(1);
- }
- }
-
- // Test harness
- public static void main(String[] args) {
- // p/n indicates whether the interior address is really positive
- // or negative. In unsigned terms, p1 < p2 < n1 < n2.
-
- Win32Address p1 = new Win32Address(null, 0x7FFFFFFFFFFFFFF0L);
- Win32Address p2 = (Win32Address) p1.addOffsetTo(10);
- Win32Address n1 = (Win32Address) p2.addOffsetTo(10);
- Win32Address n2 = (Win32Address) n1.addOffsetTo(10);
-
- // lessThan positive tests
- check(p1.lessThan(p2), "lessThan 1");
- check(p1.lessThan(n1), "lessThan 2");
- check(p1.lessThan(n2), "lessThan 3");
- check(p2.lessThan(n1), "lessThan 4");
- check(p2.lessThan(n2), "lessThan 5");
- check(n1.lessThan(n2), "lessThan 6");
-
- // lessThan negative tests
- check(!p1.lessThan(p1), "lessThan 7");
- check(!p2.lessThan(p2), "lessThan 8");
- check(!n1.lessThan(n1), "lessThan 9");
- check(!n2.lessThan(n2), "lessThan 10");
-
- check(!p2.lessThan(p1), "lessThan 11");
- check(!n1.lessThan(p1), "lessThan 12");
- check(!n2.lessThan(p1), "lessThan 13");
- check(!n1.lessThan(p2), "lessThan 14");
- check(!n2.lessThan(p2), "lessThan 15");
- check(!n2.lessThan(n1), "lessThan 16");
-
- // lessThanOrEqual positive tests
- check(p1.lessThanOrEqual(p1), "lessThanOrEqual 1");
- check(p2.lessThanOrEqual(p2), "lessThanOrEqual 2");
- check(n1.lessThanOrEqual(n1), "lessThanOrEqual 3");
- check(n2.lessThanOrEqual(n2), "lessThanOrEqual 4");
-
- check(p1.lessThanOrEqual(p2), "lessThanOrEqual 5");
- check(p1.lessThanOrEqual(n1), "lessThanOrEqual 6");
- check(p1.lessThanOrEqual(n2), "lessThanOrEqual 7");
- check(p2.lessThanOrEqual(n1), "lessThanOrEqual 8");
- check(p2.lessThanOrEqual(n2), "lessThanOrEqual 9");
- check(n1.lessThanOrEqual(n2), "lessThanOrEqual 10");
-
- // lessThanOrEqual negative tests
- check(!p2.lessThanOrEqual(p1), "lessThanOrEqual 11");
- check(!n1.lessThanOrEqual(p1), "lessThanOrEqual 12");
- check(!n2.lessThanOrEqual(p1), "lessThanOrEqual 13");
- check(!n1.lessThanOrEqual(p2), "lessThanOrEqual 14");
- check(!n2.lessThanOrEqual(p2), "lessThanOrEqual 15");
- check(!n2.lessThanOrEqual(n1), "lessThanOrEqual 16");
-
- // greaterThan positive tests
- check(n2.greaterThan(p1), "greaterThan 1");
- check(n2.greaterThan(p2), "greaterThan 2");
- check(n2.greaterThan(n1), "greaterThan 3");
- check(n1.greaterThan(p1), "greaterThan 4");
- check(n1.greaterThan(p2), "greaterThan 5");
- check(p2.greaterThan(p1), "greaterThan 6");
-
- // greaterThan negative tests
- check(!p1.greaterThan(p1), "greaterThan 7");
- check(!p2.greaterThan(p2), "greaterThan 8");
- check(!n1.greaterThan(n1), "greaterThan 9");
- check(!n2.greaterThan(n2), "greaterThan 10");
-
- check(!p1.greaterThan(n2), "greaterThan 11");
- check(!p2.greaterThan(n2), "greaterThan 12");
- check(!n1.greaterThan(n2), "greaterThan 13");
- check(!p1.greaterThan(n1), "greaterThan 14");
- check(!p2.greaterThan(n1), "greaterThan 15");
- check(!p1.greaterThan(p2), "greaterThan 16");
-
- // greaterThanOrEqual positive tests
- check(p1.greaterThanOrEqual(p1), "greaterThanOrEqual 1");
- check(p2.greaterThanOrEqual(p2), "greaterThanOrEqual 2");
- check(n1.greaterThanOrEqual(n1), "greaterThanOrEqual 3");
- check(n2.greaterThanOrEqual(n2), "greaterThanOrEqual 4");
-
- check(n2.greaterThanOrEqual(p1), "greaterThanOrEqual 5");
- check(n2.greaterThanOrEqual(p2), "greaterThanOrEqual 6");
- check(n2.greaterThanOrEqual(n1), "greaterThanOrEqual 7");
- check(n1.greaterThanOrEqual(p1), "greaterThanOrEqual 8");
- check(n1.greaterThanOrEqual(p2), "greaterThanOrEqual 9");
- check(p2.greaterThanOrEqual(p1), "greaterThanOrEqual 10");
-
- // greaterThanOrEqual negative tests
- check(!p1.greaterThanOrEqual(n2), "greaterThanOrEqual 11");
- check(!p2.greaterThanOrEqual(n2), "greaterThanOrEqual 12");
- check(!n1.greaterThanOrEqual(n2), "greaterThanOrEqual 13");
- check(!p1.greaterThanOrEqual(n1), "greaterThanOrEqual 14");
- check(!p2.greaterThanOrEqual(n1), "greaterThanOrEqual 15");
- check(!p1.greaterThanOrEqual(p2), "greaterThanOrEqual 16");
-
- System.err.println("Win32Address: all tests passed successfully.");
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32CDebugInfoBuilder.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,824 +0,0 @@
-/*
- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.util.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.win32.coff.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.cdbg.basic.*;
-import sun.jvm.hotspot.utilities.Assert;
-
-class Win32CDebugInfoBuilder
- implements DebugVC50SubsectionTypes, DebugVC50TypeLeafIndices, DebugVC50TypeEnums, DebugVC50SymbolTypes, DebugVC50MemberAttributes, CVAttributes, AccessControl {
- private Win32Debugger dbg;
- private Address base;
-
- private DebugVC50 vc50;
- private BasicCDebugInfoDataBase db;
- private DebugVC50TypeIterator iter;
-
- private DebugVC50SymbolIterator symIter;
-
- // Logical->physical segment mapping
- private COFFFile file;
- private DebugVC50SSSegMap segMap;
-
- // Canonicalization of primitive types
- private Map primIndexToTypeMap;
-
- // Global unnamed enumeration
- // (FIXME: must figure out how to handle nested type descriptions)
- private BasicEnumType unnamedEnum;
-
- private Stack blockStack;
- private int endsToSkip;
-
- private static final int POINTER_SIZE = 4;
-
- Win32CDebugInfoBuilder(Win32Debugger dbg) {
- this.dbg = dbg;
- }
-
- CDebugInfoDataBase buildDataBase(String dllName, Address base) {
- this.base = base;
- file = COFFFileParser.getParser().parse(dllName);
- vc50 = getDebugVC50(file);
-
- if (vc50 == null) return null;
-
- segMap = getSegMap();
-
- primIndexToTypeMap = new HashMap();
- blockStack = new Stack();
- endsToSkip = 0;
-
- db = new BasicCDebugInfoDataBase();
- db.beginConstruction();
-
- // Get global types and add them to the database
- DebugVC50SSGlobalTypes types = getGlobalTypes();
- for (iter = types.getTypeIterator(); !iter.done(); iter.next()) {
- while (!iter.typeStringDone()) {
- switch (iter.typeStringLeaf()) {
- case LF_MODIFIER: {
- int idx = iter.getModifierIndex();
- BasicType target = getTypeByIndex(idx);
- short windowsMods = iter.getModifierAttribute();
- short mods = 0;
- if ((windowsMods & MODIFIER_CONST_MASK) != 0) mods |= CONST;
- if ((windowsMods & MODIFIER_VOLATILE_MASK) != 0) mods |= VOLATILE;
- putType(target.getCVVariant(mods));
- break;
- }
- case LF_POINTER: {
- int idx = iter.getPointerType();
- BasicType target = getTypeByIndex(idx);
- short windowsMods = iter.getModifierAttribute();
- short mods = 0;
- if ((windowsMods & POINTER_CONST_MASK) != 0) mods |= CONST;
- if ((windowsMods & POINTER_VOLATILE_MASK) != 0) mods |= VOLATILE;
- BasicPointerType ptrType = new BasicPointerType(POINTER_SIZE, target);
- if (mods != 0) {
- ptrType = (BasicPointerType) ptrType.getCVVariant(mods);
- }
-
- putType(ptrType);
- break;
- }
- case LF_ARRAY: {
- BasicType elemType = getTypeByIndex(iter.getArrayElementType());
- putType(new BasicArrayType(iter.getArrayName(), elemType, iter.getArrayLength()));
- break;
- }
- case LF_CLASS:
- case LF_STRUCTURE: {
- CompoundTypeKind kind = ((iter.typeStringLeaf() == LF_CLASS) ? CompoundTypeKind.CLASS
- : CompoundTypeKind.STRUCT);
- BasicCompoundType type = new BasicCompoundType(iter.getClassName(),
- iter.getClassSize(),
- kind);
- // Skip parsing of forward references to types
- // FIXME: do we have to resolve these later?
- if ((iter.getClassProperty() & PROPERTY_FWDREF) == 0) {
- DebugVC50TypeIterator fieldIter = iter.getClassFieldListIterator();
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(fieldIter.typeStringLeaf() == LF_FIELDLIST, "Expected field list");
- }
- boolean advance = false;
- while (!fieldIter.typeStringDone()) {
- advance = true;
- switch (fieldIter.typeStringLeaf()) {
- case LF_FIELDLIST: break;
- case LF_BCLASS: {
- int accessControl = memberAttributeToAccessControl(fieldIter.getBClassAttribute());
- Type baseType = getTypeByIndex(fieldIter.getBClassType());
- // FIXME: take offset into account
- type.addBaseClass(new BasicBaseClass(accessControl, false, baseType));
- break;
- }
- case LF_VBCLASS: {
- int accessControl = memberAttributeToAccessControl(fieldIter.getVBClassAttribute());
- Type baseType = getTypeByIndex(fieldIter.getVBClassBaseClassType());
- // FIXME: take offset and virtual base offset into account
- type.addBaseClass(new BasicBaseClass(accessControl, true, baseType));
- break;
- }
- // I don't think we need to handle indirect virtual base
- // classes since they should be handled indirectly through
- // the modeling of the type hierarchy
- case LF_IVBCLASS: break;
- case LF_INDEX: {
- fieldIter = fieldIter.getIndexIterator();
- advance = false;
- break;
- }
- case LF_MEMBER: {
- BasicField field = new BasicField(fieldIter.getMemberName(),
- getTypeByIndex(fieldIter.getMemberType()),
- memberAttributeToAccessControl(fieldIter.getMemberAttribute()),
- false);
- field.setOffset(fieldIter.getMemberOffset());
- type.addField(field);
- break;
- }
- case LF_STMEMBER: {
- BasicField field = new BasicField(fieldIter.getStaticName(),
- getTypeByIndex(fieldIter.getStaticType()),
- memberAttributeToAccessControl(fieldIter.getStaticAttribute()),
- true);
- // The field's address will be found during resolution
- // of the debug info database
- type.addField(field);
- break;
- }
- // FIXME: handle methods
- case LF_METHOD: break;
- case LF_ONEMETHOD: break;
- // FIXME: handle nested types
- case LF_NESTTYPE: break;
- case LF_NESTTYPEEX: break;
- // NOTE: virtual functions not needed/handled yet for
- // this debugging system (because we are not planning to
- // handle calling methods in the target process at
- // runtime)
- case LF_VFUNCTAB: break;
- case LF_FRIENDCLS: break;
- case LF_VFUNCOFF: break;
- case LF_MEMBERMODIFY: break;
- case LF_PAD0: case LF_PAD1: case LF_PAD2: case LF_PAD3:
- case LF_PAD4: case LF_PAD5: case LF_PAD6: case LF_PAD7:
- case LF_PAD8: case LF_PAD9: case LF_PAD10: case LF_PAD11:
- case LF_PAD12: case LF_PAD13: case LF_PAD14: case LF_PAD15: break;
- default: System.err.println("WARNING: unexpected leaf index " +
- fieldIter.typeStringLeaf() +
- " in field list for type " + iter.getTypeIndex());
- }
- if (advance) {
- fieldIter.typeStringNext();
- }
- }
- }
- putType(type);
- break;
- }
- case LF_UNION: {
- BasicCompoundType type = new BasicCompoundType(iter.getUnionName(),
- iter.getUnionSize(),
- CompoundTypeKind.UNION);
- // Skip parsing of forward references to types
- // FIXME: do we have to resolve these later?
- if ((iter.getClassProperty() & PROPERTY_FWDREF) == 0) {
- DebugVC50TypeIterator fieldIter = iter.getUnionFieldListIterator();
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(fieldIter.typeStringLeaf() == LF_FIELDLIST, "Expected field list");
- }
- boolean advance = false;
- while (!fieldIter.typeStringDone()) {
- advance = true;
- switch (fieldIter.typeStringLeaf()) {
- case LF_FIELDLIST: break;
- case LF_BCLASS: break;
- case LF_VBCLASS: break;
- case LF_IVBCLASS: break;
- case LF_INDEX: {
- fieldIter = fieldIter.getIndexIterator();
- advance = false;
- break;
- }
- case LF_MEMBER: {
- BasicField field = new BasicField(fieldIter.getMemberName(),
- getTypeByIndex(fieldIter.getMemberType()),
- memberAttributeToAccessControl(fieldIter.getMemberAttribute()),
- false);
- field.setOffset(fieldIter.getMemberOffset());
- type.addField(field);
- break;
- }
- case LF_STMEMBER: {
- System.err.println("WARNING: I didn't think unions could contain static fields...");
- BasicField field = new BasicField(fieldIter.getStaticName(),
- getTypeByIndex(fieldIter.getStaticType()),
- memberAttributeToAccessControl(fieldIter.getStaticAttribute()),
- true);
- // The field's address will be found during resolution
- // of the debug info database
- type.addField(field);
- break;
- }
- case LF_METHOD: break;
- case LF_ONEMETHOD: break;
- // FIXME: handle nested types
- case LF_NESTTYPE: break;
- case LF_NESTTYPEEX: break;
- case LF_VFUNCTAB: break;
- case LF_FRIENDCLS: break;
- case LF_VFUNCOFF: break;
- case LF_MEMBERMODIFY: break;
- case LF_PAD0: case LF_PAD1: case LF_PAD2: case LF_PAD3:
- case LF_PAD4: case LF_PAD5: case LF_PAD6: case LF_PAD7:
- case LF_PAD8: case LF_PAD9: case LF_PAD10: case LF_PAD11:
- case LF_PAD12: case LF_PAD13: case LF_PAD14: case LF_PAD15: break;
-
- default: System.err.println("WARNING: unexpected leaf index " +
- fieldIter.typeStringLeaf() +
- " in field list for union of type " + iter.getTypeIndex());
- }
- if (advance) {
- fieldIter.typeStringNext();
- }
- }
- }
- putType(type);
- break;
- }
- case LF_ENUM: {
- String name = iter.getEnumName();
- BasicEnumType enumType = null;
- if ((name == null) || (name.equals(""))) {
- if (unnamedEnum == null) {
- unnamedEnum = new BasicEnumType(null, getTypeByIndex(iter.getEnumType()));
- }
- enumType = unnamedEnum;
- } else {
- enumType = new BasicEnumType(name, getTypeByIndex(iter.getEnumType()));
- }
- DebugVC50TypeIterator fieldIter = iter.getEnumFieldListIterator();
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(fieldIter.typeStringLeaf() == LF_FIELDLIST, "Expected field list");
- }
- boolean advance = false;
- while (!fieldIter.typeStringDone()) {
- advance = true;
- switch (fieldIter.typeStringLeaf()) {
- case LF_FIELDLIST: break;
- case LF_ENUMERATE: {
- String enumName = fieldIter.getEnumerateName();
- long enumVal = fieldIter.getEnumerateValue();
- enumType.addEnum(enumName, enumVal);
- break;
- }
- case LF_INDEX: {
- fieldIter = fieldIter.getIndexIterator();
- advance = false;
- break;
- }
-
- case LF_PAD0: case LF_PAD1: case LF_PAD2: case LF_PAD3:
- case LF_PAD4: case LF_PAD5: case LF_PAD6: case LF_PAD7:
- case LF_PAD8: case LF_PAD9: case LF_PAD10: case LF_PAD11:
- case LF_PAD12: case LF_PAD13: case LF_PAD14: case LF_PAD15: break;
-
- default: System.err.println("WARNING: unexpected leaf index " +
- fieldIter.typeStringLeaf() +
- " in field list for enum of type " + iter.getTypeIndex());
- }
-
- if (advance) {
- fieldIter.typeStringNext();
- }
- }
-
- putType(enumType);
- break;
- }
- case LF_PROCEDURE: {
- Type retType = getTypeByIndex(iter.getProcedureReturnType());
- BasicFunctionType func = new BasicFunctionType(null, POINTER_SIZE, retType);
- DebugVC50TypeIterator argIter = iter.getProcedureArgumentListIterator();
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(argIter.typeStringLeaf() == LF_ARGLIST, "Expected argument list");
- }
- for (int i = 0; i < argIter.getArgListCount(); i++) {
- func.addArgumentType(getTypeByIndex(argIter.getArgListType(i)));
- }
- putType(func);
- break;
- }
- case LF_MFUNCTION: {
- Type retType = getTypeByIndex(iter.getMFunctionReturnType());
- Type container = getTypeByIndex(iter.getMFunctionContainingClass());
- Type thisType = getTypeByIndex(iter.getMFunctionThis());
- long thisAdjust = iter.getMFunctionThisAdjust();
- BasicMemberFunctionType func = new BasicMemberFunctionType(null,
- POINTER_SIZE,
- retType,
- container,
- thisType,
- thisAdjust);
- DebugVC50TypeIterator argIter = iter.getMFunctionArgumentListIterator();
- for (int i = 0; i < argIter.getArgListCount(); i++) {
- func.addArgumentType(getTypeByIndex(argIter.getArgListType(i)));
- }
- putType(func);
- break;
- }
- // FIXME: handle virtual function table shape description
- case LF_VTSHAPE: break;
- case LF_BARRAY: System.err.println("FIXME: don't know what to do with LF_BARRAY leaves (convert to pointers?"); break;
- case LF_LABEL: break;
- case LF_NULL: break; // FIXME: do we need to handle this? With what?
- case LF_DIMARRAY: System.err.println("FIXME: don't know what to do with LF_DIMARRAY leaves yet"); break;
- case LF_VFTPATH: break;
- case LF_PRECOMP: break;
- case LF_ENDPRECOMP: break;
- case LF_OEM: break;
- case LF_TYPESERVER: break;
-
- // Type records referenced from other type records
-
- case LF_SKIP: break;
- case LF_ARGLIST: skipTypeRecord(); break;
- case LF_DEFARG: System.err.println("FIXME: handle default arguments (dereference the type)"); break;
- case LF_FIELDLIST: skipTypeRecord(); break;
- case LF_DERIVED: break;
- case LF_BITFIELD: {
- Type underlyingType = getTypeByIndex(iter.getBitfieldFieldType());
- BasicBitType bit = new BasicBitType(underlyingType,
- (iter.getBitfieldLength() & 0xFF),
- (iter.getBitfieldPosition() & 0xFF));
- putType(bit);
- break;
- }
- case LF_METHODLIST: break;
- case LF_DIMCONU:
- case LF_DIMCONLU:
- case LF_DIMVARU:
- case LF_DIMVARLU: break;
- case LF_REFSYM: break;
-
- case LF_PAD0: case LF_PAD1: case LF_PAD2: case LF_PAD3:
- case LF_PAD4: case LF_PAD5: case LF_PAD6: case LF_PAD7:
- case LF_PAD8: case LF_PAD9: case LF_PAD10: case LF_PAD11:
- case LF_PAD12: case LF_PAD13: case LF_PAD14: case LF_PAD15: break;
-
- default: {
- System.err.println("Unexpected leaf index " +
- iter.typeStringLeaf() + " at offset 0x" +
- Integer.toHexString(iter.typeStringOffset()));
- break;
- }
- }
-
-
- if (!iter.typeStringDone()) {
- iter.typeStringNext();
- }
- }
- }
-
- // Add all symbol directories to debug info
- // (FIXME: must figure out how to handle module-by-module
- // arrangement of at least the static symbols to have proper
- // lookup -- should probably also take advantage of the PROCREF
- // and UDT references to understand how to build the global
- // database vs. the module-by-module one)
- DebugVC50SubsectionDirectory dir = vc50.getSubsectionDirectory();
- int moduleNumber = 0; // Debugging
- for (int i = 0; i < dir.getNumEntries(); i++) {
- DebugVC50Subsection ss = dir.getSubsection(i);
- int ssType = ss.getSubsectionType();
- boolean process = false;
-
- if ((ssType == SST_GLOBAL_SYM) ||
- (ssType == SST_GLOBAL_PUB) ||
- (ssType == SST_STATIC_SYM)) {
- DebugVC50SSSymbolBase syms = (DebugVC50SSSymbolBase) ss;
- symIter = syms.getSymbolIterator();
- process = true;
- }
-
- if (ssType == SST_ALIGN_SYM) {
- DebugVC50SSAlignSym syms = (DebugVC50SSAlignSym) ss;
- symIter = syms.getSymbolIterator();
- process = true;
- }
-
- if (process) {
- for (; !symIter.done(); symIter.next()) {
- switch (symIter.getType()) {
- case S_COMPILE: break;
- case S_SSEARCH: break; // FIXME: may need this later
- case S_END: {
- try {
- // FIXME: workaround for warnings until we figure out
- // what to do with THUNK32 symbols
- if (endsToSkip == 0) {
- blockStack.pop();
- } else {
- --endsToSkip;
- }
- } catch (EmptyStackException e) {
- System.err.println("WARNING: mismatched block begins/ends in debug information");
- }
- break;
- }
- case S_SKIP: break;
- case S_CVRESERVE: break;
- case S_OBJNAME: break; // FIXME: may need this later
- case S_ENDARG: break;
- case S_COBOLUDT: break;
- case S_MANYREG: break; // FIXME: may need to add support for this
- case S_RETURN: break; // NOTE: would need this if adding support for calling functions
- case S_ENTRYTHIS: break; // FIXME: may need to add support for this
- case S_REGISTER: break; // FIXME: may need to add support for this
- case S_CONSTANT: break; // FIXME: will need to add support for this
- case S_UDT: break; // FIXME: need to see how these are used; are
- // they redundant, or are they used to describe
- // global variables as opposed to types?
- case S_COBOLUDT2: break;
- case S_MANYREG2: break;
- case S_BPREL32: {
- LocalSym sym = new BasicLocalSym(symIter.getBPRelName(),
- getTypeByIndex(symIter.getBPRelType()),
- symIter.getBPRelOffset());
- addLocalToCurBlock(sym);
- break;
- }
- case S_LDATA32:
- case S_GDATA32: {
- // FIXME: must handle these separately from global data (have
- // module scoping and only add these at the module level)
- boolean isModuleLocal = (symIter.getType() == S_LDATA32);
-
- GlobalSym sym = new BasicGlobalSym(symIter.getLGDataName(),
- getTypeByIndex(symIter.getLGDataType()),
- newAddress(symIter.getLGDataOffset(), symIter.getLGDataSegment()),
- isModuleLocal);
- // FIXME: must handle module-local symbols differently
- addGlobalSym(sym);
- break;
- }
- case S_PUB32: break; // FIXME: figure out how these differ from
- // above and how they are used
- case S_LPROC32:
- case S_GPROC32: {
- BasicFunctionSym sym = new BasicFunctionSym(newLazyBlockSym(symIter.getLGProcParentOffset()),
- symIter.getLGProcLength(),
- newAddress(symIter.getLGProcOffset(), symIter.getLGProcSegment()),
- symIter.getLGProcName(),
- getTypeByIndex(symIter.getLGProcType()),
- (symIter.getType() == S_LPROC32));
-
- // FIXME: have to handle local procedures differently (have
- // notion of modules and only add those procedures to the
- // module they are defined in)
- addBlock(sym);
- break;
- }
- case S_THUNK32: {
- // FIXME: see whether we need to handle these
- skipEnd();
- break;
- }
- case S_BLOCK32: {
- BasicBlockSym sym = new BasicBlockSym(newLazyBlockSym(symIter.getBlockParentOffset()),
- symIter.getBlockLength(),
- newAddress(symIter.getBlockOffset(), symIter.getBlockSegment()),
- symIter.getBlockName());
- addBlock(sym);
- break;
- }
- case S_WITH32: break;
- case S_LABEL32: break;
- case S_CEXMODEL32: break;
- case S_VFTTABLE32: break; // FIXME: may need to handle this
- // (most likely for run-time type determination)
- case S_REGREL32: break; // FIXME: may need to add support for this
- case S_LTHREAD32: break;
- case S_GTHREAD32: break; // FIXME: may need to add support for these
- case S_PROCREF: break;
- case S_DATAREF: break;
- case S_ALIGN: break;
- default:
- // These two unknown symbol types show up very frequently.
- // Symbol type 0 appears to always be a no-op symbol of
- // length 2 (i.e., length just covers the symbol type.)
- // Symbol type 4115 appears to be a copyright notice for
- // the Microsoft linker.
- if ((symIter.getType() != 0) && (symIter.getType() != 4115)) {
- System.err.println(" NOTE: Unexpected symbol of type " +
- symIter.getType() + " at offset 0x" +
- Integer.toHexString(symIter.getOffset()));
- }
- break;
- }
- }
- }
- }
-
- // Add line number information for all modules
- for (int i = 0; i < dir.getNumEntries(); i++) {
- DebugVC50Subsection ss = dir.getSubsection(i);
- if (ss.getSubsectionType() == SST_SRC_MODULE) {
- DebugVC50SSSrcModule srcMod = (DebugVC50SSSrcModule) ss;
- for (int sf = 0; sf < srcMod.getNumSourceFiles(); sf++) {
- DebugVC50SrcModFileDesc desc = srcMod.getSourceFileDesc(sf);
- // Uniquify these to save space
- String name = desc.getSourceFileName().intern();
- for (int cs = 0; cs < desc.getNumCodeSegments(); cs++) {
- DebugVC50SrcModLineNumberMap map = desc.getLineNumberMap(cs);
- SectionHeader seg = file.getHeader().getSectionHeader(map.getSegment());
- for (int lp = 0; lp < map.getNumSourceLinePairs(); lp++) {
- Address startPC = base.addOffsetTo(seg.getVirtualAddress() + map.getCodeOffset(lp));
- // Fake address for endPC -- will be filled in by BasicLineNumberMapping
- Address endPC = base.addOffsetTo(seg.getSize());
- db.addLineNumberInfo(new BasicLineNumberInfo(name, map.getLineNumber(lp), startPC, endPC));
- }
- }
- }
- }
- }
-
- // Finish assembly of database
- db.resolve(new ResolveListener() {
- public void resolveFailed(Type containingType, LazyType failedResolve, String detail) {
- System.err.println("WARNING: failed to resolve type of index " +
- ((Integer) failedResolve.getKey()).intValue() +
- " in type " + containingType.getName() + " (class " +
- containingType.getClass().getName() + ") while " + detail);
- }
-
- public void resolveFailed(Type containingType, String staticFieldName) {
- System.err.println("WARNING: failed to resolve address of static field \"" +
- staticFieldName + "\" in type " + containingType.getName());
- }
-
- public void resolveFailed(Sym containingSymbol, LazyType failedResolve, String detail) {
- System.err.println("WARNING: failed to resolve type of index " +
- ((Integer) failedResolve.getKey()).intValue() +
- " in symbol of type " + containingSymbol.getClass().getName() +
- " while " + detail);
- }
-
- public void resolveFailed(Sym containingSymbol, LazyBlockSym failedResolve, String detail) {
- System.err.println("WARNING: failed to resolve block at offset 0x" +
- Integer.toHexString(((Integer) failedResolve.getKey()).intValue()) +
- " in symbol of type " + containingSymbol.getClass().getName() +
- " while " + detail);
- }
- });
-
- db.endConstruction();
-
- return db;
- }
-
-
- //----------------------------------------------------------------------
- // Internals only below this point
- //
-
- private static DebugVC50 getDebugVC50(COFFFile file) {
- COFFHeader header = file.getHeader();
- OptionalHeader opt = header.getOptionalHeader();
- if (opt == null) {
- // Optional header not found
- return null;
- }
- OptionalHeaderDataDirectories dd = opt.getDataDirectories();
- if (dd == null) {
- // Optional header data directories not found
- return null;
- }
- DebugDirectory debug = dd.getDebugDirectory();
- if (debug == null) {
- // Debug directory not found
- return null;
- }
- for (int i = 0; i < debug.getNumEntries(); i++) {
- DebugDirectoryEntry entry = debug.getEntry(i);
- if (entry.getType() == DebugTypes.IMAGE_DEBUG_TYPE_CODEVIEW) {
- return entry.getDebugVC50();
- }
- }
-
- // CodeView information not found in debug directory
- return null;
- }
-
- private DebugVC50SSSegMap getSegMap() {
- return (DebugVC50SSSegMap) findSubsection(SST_SEG_MAP);
- }
-
- private DebugVC50SSGlobalTypes getGlobalTypes() {
- return (DebugVC50SSGlobalTypes) findSubsection(SST_GLOBAL_TYPES);
- }
-
- private DebugVC50SSGlobalSym getGlobalSymbols() {
- return (DebugVC50SSGlobalSym) findSubsection(SST_GLOBAL_SYM);
- }
-
- private DebugVC50Subsection findSubsection(short ssType) {
- DebugVC50SubsectionDirectory dir = vc50.getSubsectionDirectory();
- for (int i = 0; i < dir.getNumEntries(); i++) {
- DebugVC50Subsection ss = dir.getSubsection(i);
- if (ss.getSubsectionType() == ssType) {
- return ss;
- }
- }
- throw new DebuggerException("Unable to find subsection of type " + ssType);
- }
-
- private void putType(Type t) {
- db.addType(new Integer(iter.getTypeIndex()), t);
- }
-
- private Address newAddress(int offset, short segment) {
- int seg = segment & 0xFFFF;
- // NOTE: it isn't clear how to use the segMap to map from logical
- // to physical segments. It seems it would make more sense if the
- // SegDescs contained a physical segment number in addition to the
- // offset within the physical segment of the logical one.
-
- // Get the section header corresponding to this segment
- SectionHeader section = file.getHeader().getSectionHeader(seg);
-
- // Result is relative to image base
- return base.addOffsetTo(section.getVirtualAddress() + offset);
- }
-
- private BasicType getTypeByIndex(int intIndex) {
- Integer index = new Integer(intIndex);
-
- // Handle primitive types here.
- if (intIndex <= 0x0FFF) {
- BasicType type = (BasicType) primIndexToTypeMap.get(index);
- if (type != null) {
- return type;
- }
- // Construct appropriate new primitive type
- int primMode = intIndex & RESERVED_MODE_MASK;
- if (primMode == RESERVED_MODE_DIRECT) {
- int primType = intIndex & RESERVED_TYPE_MASK;
- switch (primType) {
- case RESERVED_TYPE_SIGNED_INT:
- case RESERVED_TYPE_UNSIGNED_INT: {
- boolean unsigned = (primType == RESERVED_TYPE_UNSIGNED_INT);
- int size = 0;
- String name = null;
- switch (intIndex & RESERVED_SIZE_MASK) {
- case RESERVED_SIZE_INT_1_BYTE: size = 1; name = "char"; break;
- case RESERVED_SIZE_INT_2_BYTE: size = 2; name = "short"; break;
- case RESERVED_SIZE_INT_4_BYTE: size = 4; name = "int"; break;
- case RESERVED_SIZE_INT_8_BYTE: size = 8; name = "__int64"; break;
- default: throw new DebuggerException("Illegal size of integer type " + intIndex);
- }
- type = new BasicIntType(name, size, unsigned);
- break;
- }
- case RESERVED_TYPE_BOOLEAN: {
- int size = 0;
- switch (intIndex & RESERVED_SIZE_MASK) {
- case RESERVED_SIZE_INT_1_BYTE: size = 1; break;
- case RESERVED_SIZE_INT_2_BYTE: size = 2; break;
- case RESERVED_SIZE_INT_4_BYTE: size = 4; break;
- case RESERVED_SIZE_INT_8_BYTE: size = 8; break;
- default: throw new DebuggerException("Illegal size of boolean type " + intIndex);
- }
- type = new BasicIntType("bool", size, false);
- break;
- }
- case RESERVED_TYPE_REAL: {
- switch (intIndex & RESERVED_SIZE_MASK) {
- case RESERVED_SIZE_REAL_32_BIT:
- type = new BasicFloatType("float", 4);
- break;
- case RESERVED_SIZE_REAL_64_BIT:
- type = new BasicDoubleType("double", 8);
- break;
- default:
- throw new DebuggerException("Unsupported floating-point size in type " + intIndex);
- }
- break;
- }
- case RESERVED_TYPE_REALLY_INT: {
- switch (intIndex & RESERVED_SIZE_MASK) {
- case RESERVED_SIZE_REALLY_INT_CHAR: type = new BasicIntType("char", 1, false); break;
- case RESERVED_SIZE_REALLY_INT_WCHAR: type = new BasicIntType("wchar", 2, false); break;
- case RESERVED_SIZE_REALLY_INT_2_BYTE: type = new BasicIntType("short", 2, false); break;
- case RESERVED_SIZE_REALLY_INT_2_BYTE_U: type = new BasicIntType("short", 2, true); break;
- case RESERVED_SIZE_REALLY_INT_4_BYTE: type = new BasicIntType("int", 4, false); break;
- case RESERVED_SIZE_REALLY_INT_4_BYTE_U: type = new BasicIntType("int", 4, true); break;
- case RESERVED_SIZE_REALLY_INT_8_BYTE: type = new BasicIntType("__int64", 8, false); break;
- case RESERVED_SIZE_REALLY_INT_8_BYTE_U: type = new BasicIntType("__int64", 8, true); break;
- default: throw new DebuggerException("Illegal REALLY_INT size in type " + intIndex);
- }
- break;
- }
- case RESERVED_TYPE_SPECIAL: {
- switch (intIndex & RESERVED_SIZE_MASK) {
- case RESERVED_SIZE_SPECIAL_NO_TYPE:
- case RESERVED_SIZE_SPECIAL_VOID: type = new BasicVoidType(); break;
- default: throw new DebuggerException("Don't know how to handle reserved special type " + intIndex);
- }
- break;
- }
-
- default:
- throw new DebuggerException("Don't know how to handle reserved type " + intIndex);
- }
- } else {
- // Fold all pointer types together since we only support
- // flat-mode addressing anyway
- Type targetType = getTypeByIndex(intIndex & (~RESERVED_MODE_MASK));
-
- type = new BasicPointerType(POINTER_SIZE, targetType);
- }
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(type != null, "Got null Type for primitive type " + intIndex);
- }
- primIndexToTypeMap.put(index, type);
- return type;
- }
-
- // Not primitive type. Construct lazy reference to target type.
- // (Is it worth canonicalizing these as well to save space?)
- return new LazyType(index);
- }
-
- private void addBlock(BlockSym block) {
- db.addBlock(new Integer(symIter.getOffset()), block);
- blockStack.push(block);
- }
-
- private void skipEnd() {
- ++endsToSkip;
- }
-
- private BlockSym newLazyBlockSym(int offset) {
- if (offset == 0) {
- return null;
- }
-
- return new LazyBlockSym(new Integer(offset));
- }
-
- private int memberAttributeToAccessControl(short memberAttribute) {
- int acc = memberAttribute & MEMATTR_ACCESS_MASK;
- switch (acc) {
- case MEMATTR_ACCESS_NO_PROTECTION: return NO_PROTECTION;
- case MEMATTR_ACCESS_PRIVATE: return PRIVATE;
- case MEMATTR_ACCESS_PROTECTED: return PROTECTED;
- case MEMATTR_ACCESS_PUBLIC: return PUBLIC;
- default: throw new RuntimeException("Should not reach here");
- }
- }
-
- private void addLocalToCurBlock(LocalSym local) {
- ((BasicBlockSym) blockStack.peek()).addLocal(local);
- }
-
- private void addGlobalSym(GlobalSym sym) {
- db.addGlobalSym(sym);
- }
-
- private void skipTypeRecord() {
- while (!iter.typeStringDone()) {
- iter.typeStringNext();
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32CDebugger.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.io.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.cdbg.basic.x86.*;
-import sun.jvm.hotspot.debugger.x86.*;
-import sun.jvm.hotspot.utilities.AddressOps;
-
-class Win32CDebugger implements CDebugger, ProcessControl {
- // FIXME: think about how to make this work in a remote debugging
- // scenario; who should keep open DLLs? Need local copies of these
- // DLLs on the debugging machine?
- private Win32Debugger dbg;
-
- Win32CDebugger(Win32Debugger dbg) {
- this.dbg = dbg;
- }
-
- public List getThreadList() throws DebuggerException {
- return dbg.getThreadList();
- }
-
- public List/*<LoadObject>*/ getLoadObjectList() throws DebuggerException{
- return dbg.getLoadObjectList();
- }
-
- public LoadObject loadObjectContainingPC(Address pc) throws DebuggerException {
- // FIXME: could keep sorted list of these to be able to do binary
- // searches, for better scalability
- if (pc == null) {
- return null;
- }
- List objs = getLoadObjectList();
- for (Iterator iter = objs.iterator(); iter.hasNext(); ) {
- LoadObject obj = (LoadObject) iter.next();
- if (AddressOps.lte(obj.getBase(), pc) && (pc.minus(obj.getBase()) < obj.getSize())) {
- return obj;
- }
- }
- return null;
- }
-
- public CFrame topFrameForThread(ThreadProxy thread) throws DebuggerException {
- X86ThreadContext context = (X86ThreadContext) thread.getContext();
- Address ebp = context.getRegisterAsAddress(X86ThreadContext.EBP);
- if (ebp == null) return null;
- Address pc = context.getRegisterAsAddress(X86ThreadContext.EIP);
- if (pc == null) return null;
- return new X86CFrame(this, ebp, pc);
- }
-
- public String getNameOfFile(String fileName) {
- return new File(fileName).getName();
- }
-
- public ProcessControl getProcessControl() throws DebuggerException {
- return this;
- }
-
- // C++ name demangling
- public boolean canDemangle() {
- return false;
- }
-
- public String demangle(String sym) {
- throw new UnsupportedOperationException();
- }
-
- //
- // Support for ProcessControl interface
- //
-
- public void suspend() throws DebuggerException {
- dbg.suspend();
- }
- public void resume() throws DebuggerException {
- dbg.resume();
- }
- public boolean isSuspended() throws DebuggerException {
- return dbg.isSuspended();
- }
- public void setBreakpoint(Address addr) throws DebuggerException {
- dbg.setBreakpoint(addr);
- }
- public void clearBreakpoint(Address addr) throws DebuggerException {
- dbg.clearBreakpoint(addr);
- }
- public boolean isBreakpointSet(Address addr) throws DebuggerException {
- return dbg.isBreakpointSet(addr);
- }
- public DebugEvent debugEventPoll() throws DebuggerException {
- return dbg.debugEventPoll();
- }
- public void debugEventContinue() throws DebuggerException {
- dbg.debugEventContinue();
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Debugger.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.util.List;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-
-/** An extension of the JVMDebugger interface with a few additions to
- support 32-bit vs. 64-bit debugging as well as features required
- by the architecture-specific subpackages. */
-
-public interface Win32Debugger extends JVMDebugger {
- public String addressValueToString(long address) throws DebuggerException;
- public boolean readJBoolean(long address) throws DebuggerException;
- public byte readJByte(long address) throws DebuggerException;
- public char readJChar(long address) throws DebuggerException;
- public double readJDouble(long address) throws DebuggerException;
- public float readJFloat(long address) throws DebuggerException;
- public int readJInt(long address) throws DebuggerException;
- public long readJLong(long address) throws DebuggerException;
- public short readJShort(long address) throws DebuggerException;
- public long readCInteger(long address, long numBytes, boolean isUnsigned)
- throws DebuggerException;
- public Win32Address readAddress(long address) throws DebuggerException;
- public Win32Address readCompOopAddress(long address) throws DebuggerException;
- public Win32OopHandle readOopHandle(long address) throws DebuggerException;
- public Win32OopHandle readCompOopHandle(long address) throws DebuggerException;
- public void writeJBoolean(long address, boolean value) throws DebuggerException;
- public void writeJByte(long address, byte value) throws DebuggerException;
- public void writeJChar(long address, char value) throws DebuggerException;
- public void writeJDouble(long address, double value) throws DebuggerException;
- public void writeJFloat(long address, float value) throws DebuggerException;
- public void writeJInt(long address, int value) throws DebuggerException;
- public void writeJLong(long address, long value) throws DebuggerException;
- public void writeJShort(long address, short value) throws DebuggerException;
- public void writeCInteger(long address, long numBytes, long value) throws DebuggerException;
- public void writeAddress(long address, Win32Address value) throws DebuggerException;
- public void writeOopHandle(long address, Win32OopHandle value) throws DebuggerException;
-
- // On Windows the int is actually the value of a HANDLE which
- // currently must be read from the target process; that is, the
- // target process must maintain its own thread list, each element of
- // which holds a HANDLE to its underlying OS thread. FIXME: should
- // add access to the OS-level thread list, but there are too many
- // limitations imposed by Windows to usefully do so; see
- // src/os/win32/agent/README-commands.txt, command "duphandle".
- //
- // The returned array of register contents is guaranteed to be in
- // the same order as in the DbxDebugger for Solaris/x86; that is,
- // the indices match those in debugger/x86/X86ThreadContext.java.
- public long[] getThreadIntegerRegisterSet(int threadHandleValue,
- boolean mustDuplicateHandle) throws DebuggerException;
- // Implmentation of setContext
- public void setThreadIntegerRegisterSet(int threadHandleValue,
- boolean mustDuplicateHandle,
- long[] contents) throws DebuggerException;
-
- public Address newAddress(long value) throws DebuggerException;
-
- // Routine supporting the ThreadProxy implementation, in particular
- // the ability to get a thread ID from a thread handle via
- // examination of the Thread Information Block. Fetch the LDT entry
- // for a given selector.
- public Win32LDTEntry getThreadSelectorEntry(int threadHandleValue,
- boolean mustDuplicateHandle,
- int selector) throws DebuggerException;
-
- // Support for the CDebugger interface. Retrieves the thread list of
- // the target process as a List of ThreadProxy objects.
- public List/*<ThreadProxy>*/ getThreadList() throws DebuggerException;
-
- // Support for the CDebugger interface. Retrieves a List of the
- // loadobjects in the target process.
- public List/*<LoadObject>*/ getLoadObjectList() throws DebuggerException;
-
- // Support for the ProcessControl interface
- public void writeBytesToProcess(long startAddress, long numBytes, byte[] data) throws UnmappedAddressException, DebuggerException;
- public void suspend() throws DebuggerException;
- public void resume() throws DebuggerException;
- public boolean isSuspended() throws DebuggerException;
- public void setBreakpoint(Address addr) throws DebuggerException;
- public void clearBreakpoint(Address addr) throws DebuggerException;
- public boolean isBreakpointSet(Address addr) throws DebuggerException;
- // FIXME: do not want to expose complicated data structures (like
- // the DebugEvent) in this interface due to serialization issues
- public DebugEvent debugEventPoll() throws DebuggerException;
- public void debugEventContinue() throws DebuggerException;
-
- // NOTE: this interface implicitly contains the following methods:
- // From the Debugger interface via JVMDebugger
- // public void attach(int processID) throws DebuggerException;
- // public void attach(String executableName, String coreFileName) throws DebuggerException;
- // public boolean detach();
- // public Address parseAddress(String addressString) throws NumberFormatException;
- // public long getAddressValue(Address addr) throws DebuggerException;
- // public String getOS();
- // public String getCPU();
- // From the SymbolLookup interface via Debugger and JVMDebugger
- // public Address lookup(String objectName, String symbol);
- // public OopHandle lookupOop(String objectName, String symbol);
- // From the JVMDebugger interface
- // public void configureJavaPrimitiveTypeSizes(long jbooleanSize,
- // long jbyteSize,
- // long jcharSize,
- // long jdoubleSize,
- // long jfloatSize,
- // long jintSize,
- // long jlongSize,
- // long jshortSize);
- // From the ThreadAccess interface via Debugger and JVMDebugger
- // public ThreadProxy getThreadForIdentifierAddress(Address addr);
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32DebuggerLocal.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1083 +0,0 @@
-/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.x86.*;
-import sun.jvm.hotspot.debugger.win32.coff.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.cdbg.basic.BasicDebugEvent;
-import sun.jvm.hotspot.utilities.*;
-import sun.jvm.hotspot.utilities.memo.*;
-
-/** <P> An implementation of the JVMDebugger interface which talks to
- the Free Windows Debug Server (FwDbgSrv) over a socket to
- implement attach/detach and read from process memory. All DLL and
- symbol table management is done in Java. </P>
-
- <P> <B>NOTE</B> that since we have the notion of fetching "Java
- primitive types" from the remote process (which might have
- different sizes than we expect) we have a bootstrapping
- problem. We need to know the sizes of these types before we can
- fetch them. The current implementation solves this problem by
- requiring that it be configured with these type sizes before they
- can be fetched. The readJ(Type) routines here will throw a
- RuntimeException if they are called before the debugger is
- configured with the Java primitive type sizes. </P> */
-
-public class Win32DebuggerLocal extends DebuggerBase implements Win32Debugger {
- private Socket debuggerSocket;
- private boolean attached;
- // FIXME: update when core files supported
- private long pid;
- // Communication with debug server
- private PrintWriter out;
- private DataOutputStream rawOut;
- private InputLexer in;
- private static final int PORT = 27000;
- private PageCache cache;
- private static final long SHORT_TIMEOUT = 2000;
- private static final long LONG_TIMEOUT = 20000;
-
- // Symbol lookup support
- // This is a map of library names to DLLs
- private Map nameToDllMap;
-
- // C/C++ debugging support
- private List/*<LoadObject>*/ loadObjects;
- private CDebugger cdbg;
-
- // ProcessControl support
- private boolean suspended;
- // Maps Long objects (addresses) to Byte objects (original instructions)
- // (Longs used instead of Addresses to properly represent breakpoints at 0x0 if needed)
- private Map breakpoints;
- // Current debug event, if any
- private DebugEvent curDebugEvent;
-
- //--------------------------------------------------------------------------------
- // Implementation of Debugger interface
- //
-
- /** <P> machDesc may not be null. </P>
-
- <P> useCache should be set to true if debugging is being done
- locally, and to false if the debugger is being created for the
- purpose of supporting remote debugging. </P> */
- public Win32DebuggerLocal(MachineDescription machDesc,
- boolean useCache) throws DebuggerException {
- this.machDesc = machDesc;
- utils = new DebuggerUtilities(machDesc.getAddressSize(), machDesc.isBigEndian());
- if (useCache) {
- // Cache portion of the remote process's address space.
- // Fetching data over the socket connection to dbx is slow.
- // Might be faster if we were using a binary protocol to talk to
- // dbx, but would have to test. For now, this cache works best
- // if it covers the entire heap of the remote process. FIXME: at
- // least should make this tunable from the outside, i.e., via
- // the UI. This is a cache of 4096 4K pages, or 16 MB. The page
- // size must be adjusted to be the hardware's page size.
- // (FIXME: should pick this up from the debugger.)
- initCache(4096, parseCacheNumPagesProperty(4096));
- }
- // FIXME: add instantiation of thread factory
-
- try {
- connectToDebugServer();
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- /** From the Debugger interface via JVMDebugger */
- public boolean hasProcessList() throws DebuggerException {
- return true;
- }
-
- /** From the Debugger interface via JVMDebugger */
- public List getProcessList() throws DebuggerException {
- List processes = new ArrayList();
-
- try {
- printlnToOutput("proclist");
- int num = in.parseInt();
- for (int i = 0; i < num; i++) {
- int pid = in.parseInt();
- String name = parseString();
- // NOTE: Win32 hack
- if (name.equals("")) {
- name = "System Idle Process";
- }
- processes.add(new ProcessInfo(name, pid));
- }
- return processes;
- }
- catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- /** From the Debugger interface via JVMDebugger */
- public synchronized void attach(int processID) throws DebuggerException {
- if (attached) {
- // FIXME: update when core files supported
- throw new DebuggerException("Already attached to process " + pid);
- }
-
- try {
- printlnToOutput("attach " + processID);
- if (!in.parseBoolean()) {
- throw new DebuggerException("Error attaching to process, or no such process");
- }
-
- attached = true;
- pid = processID;
- suspended = true;
- breakpoints = new HashMap();
- curDebugEvent = null;
- nameToDllMap = null;
- loadObjects = null;
- }
- catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- /** From the Debugger interface via JVMDebugger */
- public synchronized void attach(String executableName, String coreFileName) throws DebuggerException {
- throw new DebuggerException("Core files not yet supported on Win32");
- }
-
- /** From the Debugger interface via JVMDebugger */
- public synchronized boolean detach() {
- if (!attached) {
- return false;
- }
-
- attached = false;
- suspended = false;
- breakpoints = null;
-
- // Close all open DLLs
- if (nameToDllMap != null) {
- for (Iterator iter = nameToDllMap.values().iterator(); iter.hasNext(); ) {
- DLL dll = (DLL) iter.next();
- dll.close();
- }
- nameToDllMap = null;
- loadObjects = null;
- }
-
- cdbg = null;
- clearCache();
-
- try {
- printlnToOutput("detach");
- return in.parseBoolean();
- }
- catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- /** From the Debugger interface via JVMDebugger */
- public Address parseAddress(String addressString) throws NumberFormatException {
- return newAddress(utils.scanAddress(addressString));
- }
-
- /** From the Debugger interface via JVMDebugger */
- public String getOS() {
- return PlatformInfo.getOS();
- }
-
- /** From the Debugger interface via JVMDebugger */
- public String getCPU() {
- return PlatformInfo.getCPU();
- }
-
- public boolean hasConsole() throws DebuggerException {
- return false;
- }
-
- public String consoleExecuteCommand(String cmd) throws DebuggerException {
- throw new DebuggerException("No debugger console available on Win32");
- }
-
- public String getConsolePrompt() throws DebuggerException {
- return null;
- }
-
- public CDebugger getCDebugger() throws DebuggerException {
- if (cdbg == null) {
- cdbg = new Win32CDebugger(this);
- }
- return cdbg;
- }
-
- /** From the SymbolLookup interface via Debugger and JVMDebugger */
- public synchronized Address lookup(String objectName, String symbol) {
- if (!attached) {
- return null;
- }
- return newAddress(lookupInProcess(objectName, symbol));
- }
-
- /** From the SymbolLookup interface via Debugger and JVMDebugger */
- public synchronized OopHandle lookupOop(String objectName, String symbol) {
- Address addr = lookup(objectName, symbol);
- if (addr == null) {
- return null;
- }
- return addr.addOffsetToAsOopHandle(0);
- }
-
- /** From the Debugger interface */
- public MachineDescription getMachineDescription() {
- return machDesc;
- }
-
- //--------------------------------------------------------------------------------
- // Implementation of ThreadAccess interface
- //
-
- /** From the ThreadAccess interface via Debugger and JVMDebugger */
- public ThreadProxy getThreadForIdentifierAddress(Address addr) {
- return new Win32Thread(this, addr);
- }
-
- public ThreadProxy getThreadForThreadId(long handle) {
- return new Win32Thread(this, handle);
- }
-
- //----------------------------------------------------------------------
- // Overridden from DebuggerBase because we need to relax alignment
- // constraints on x86
-
- public long readJLong(long address)
- throws UnmappedAddressException, UnalignedAddressException {
- checkJavaConfigured();
- // FIXME: allow this to be configurable. Undesirable to add a
- // dependency on the runtime package here, though, since this
- // package should be strictly underneath it.
- // utils.checkAlignment(address, jlongSize);
- utils.checkAlignment(address, jintSize);
- byte[] data = readBytes(address, jlongSize);
- return utils.dataToJLong(data, jlongSize);
- }
-
- //--------------------------------------------------------------------------------
- // Internal routines (for implementation of Win32Address).
- // These must not be called until the MachineDescription has been set up.
- //
-
- /** From the Win32Debugger interface */
- public String addressValueToString(long address) {
- return utils.addressValueToString(address);
- }
-
- /** From the Win32Debugger interface */
- public Win32Address readAddress(long address)
- throws UnmappedAddressException, UnalignedAddressException {
- return (Win32Address) newAddress(readAddressValue(address));
- }
-
- public Win32Address readCompOopAddress(long address)
- throws UnmappedAddressException, UnalignedAddressException {
- return (Win32Address) newAddress(readCompOopAddressValue(address));
- }
-
- /** From the Win32Debugger interface */
- public Win32OopHandle readOopHandle(long address)
- throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
- long value = readAddressValue(address);
- return (value == 0 ? null : new Win32OopHandle(this, value));
- }
- public Win32OopHandle readCompOopHandle(long address)
- throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
- long value = readCompOopAddressValue(address);
- return (value == 0 ? null : new Win32OopHandle(this, value));
- }
-
- /** From the Win32Debugger interface */
- public void writeAddress(long address, Win32Address value) {
- writeAddressValue(address, getAddressValue(value));
- }
-
- /** From the Win32Debugger interface */
- public void writeOopHandle(long address, Win32OopHandle value) {
- writeAddressValue(address, getAddressValue(value));
- }
-
- //--------------------------------------------------------------------------------
- // Thread context access
- //
-
- public synchronized long[] getThreadIntegerRegisterSet(int threadHandleValue,
- boolean mustDuplicateHandle)
- throws DebuggerException {
- if (!suspended) {
- throw new DebuggerException("Process not suspended");
- }
-
- try {
- int handle = threadHandleValue;
- if (mustDuplicateHandle) {
- printlnToOutput("duphandle 0x" + Integer.toHexString(threadHandleValue));
- if (!in.parseBoolean()) {
- throw new DebuggerException("Error duplicating thread handle 0x" + threadHandleValue);
- }
- handle = (int) in.parseAddress(); // Must close to avoid leaks
- }
- printlnToOutput("getcontext 0x" + Integer.toHexString(handle));
- if (!in.parseBoolean()) {
- if (mustDuplicateHandle) {
- printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
- }
- String failMessage = "GetThreadContext failed for thread handle 0x" +
- Integer.toHexString(handle);
- if (mustDuplicateHandle) {
- failMessage = failMessage + ", duplicated from thread handle " +
- Integer.toHexString(threadHandleValue);
- }
- throw new DebuggerException(failMessage);
- }
- // Otherwise, parse all registers. See
- // src/os/win32/agent/README-commands.txt for the format.
- // Note the array we have to return has to match that specified by
- // X86ThreadContext.java.
- int numRegs = 22;
- long[] winRegs = new long[numRegs];
- for (int i = 0; i < numRegs; i++) {
- winRegs[i] = in.parseAddress();
- }
- if (mustDuplicateHandle) {
- // Clean up after ourselves
- printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
- }
- // Now create the real return value
- long[] retval = new long[X86ThreadContext.NPRGREG];
- retval[X86ThreadContext.EAX] = winRegs[0];
- retval[X86ThreadContext.EBX] = winRegs[1];
- retval[X86ThreadContext.ECX] = winRegs[2];
- retval[X86ThreadContext.EDX] = winRegs[3];
- retval[X86ThreadContext.ESI] = winRegs[4];
- retval[X86ThreadContext.EDI] = winRegs[5];
- retval[X86ThreadContext.EBP] = winRegs[6];
- retval[X86ThreadContext.ESP] = winRegs[7];
- retval[X86ThreadContext.EIP] = winRegs[8];
- retval[X86ThreadContext.DS] = winRegs[9];
- retval[X86ThreadContext.ES] = winRegs[10];
- retval[X86ThreadContext.FS] = winRegs[11];
- retval[X86ThreadContext.GS] = winRegs[12];
- retval[X86ThreadContext.CS] = winRegs[13];
- retval[X86ThreadContext.SS] = winRegs[14];
- retval[X86ThreadContext.EFL] = winRegs[15];
- retval[X86ThreadContext.DR0] = winRegs[16];
- retval[X86ThreadContext.DR1] = winRegs[17];
- retval[X86ThreadContext.DR2] = winRegs[18];
- retval[X86ThreadContext.DR3] = winRegs[19];
- retval[X86ThreadContext.DR6] = winRegs[20];
- retval[X86ThreadContext.DR7] = winRegs[21];
- return retval;
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- public synchronized void setThreadIntegerRegisterSet(int threadHandleValue,
- boolean mustDuplicateHandle,
- long[] context)
- throws DebuggerException {
- if (!suspended) {
- throw new DebuggerException("Process not suspended");
- }
-
- try {
- int handle = threadHandleValue;
- if (mustDuplicateHandle) {
- printlnToOutput("duphandle 0x" + Integer.toHexString(threadHandleValue));
- if (!in.parseBoolean()) {
- throw new DebuggerException("Error duplicating thread handle 0x" + threadHandleValue);
- }
- handle = (int) in.parseAddress(); // Must close to avoid leaks
- }
- // Change order of registers to match that of debug server
- long[] winRegs = new long[context.length];
- winRegs[0] = context[X86ThreadContext.EAX];
- winRegs[1] = context[X86ThreadContext.EBX];
- winRegs[2] = context[X86ThreadContext.ECX];
- winRegs[3] = context[X86ThreadContext.EDX];
- winRegs[4] = context[X86ThreadContext.ESI];
- winRegs[5] = context[X86ThreadContext.EDI];
- winRegs[6] = context[X86ThreadContext.EBP];
- winRegs[7] = context[X86ThreadContext.ESP];
- winRegs[8] = context[X86ThreadContext.EIP];
- winRegs[9] = context[X86ThreadContext.DS];
- winRegs[10] = context[X86ThreadContext.ES];
- winRegs[11] = context[X86ThreadContext.FS];
- winRegs[12] = context[X86ThreadContext.GS];
- winRegs[13] = context[X86ThreadContext.CS];
- winRegs[14] = context[X86ThreadContext.SS];
- winRegs[15] = context[X86ThreadContext.EFL];
- winRegs[16] = context[X86ThreadContext.DR0];
- winRegs[17] = context[X86ThreadContext.DR1];
- winRegs[18] = context[X86ThreadContext.DR2];
- winRegs[19] = context[X86ThreadContext.DR3];
- winRegs[20] = context[X86ThreadContext.DR6];
- winRegs[21] = context[X86ThreadContext.DR7];
- StringBuffer cmd = new StringBuffer();
- cmd.append("setcontext 0x");
- cmd.append(Integer.toHexString(threadHandleValue));
- for (int i = 0; i < context.length; i++) {
- cmd.append(" 0x");
- cmd.append(Long.toHexString(winRegs[i]));
- }
- printlnToOutput(cmd.toString());
- boolean res = in.parseBoolean();
- if (mustDuplicateHandle) {
- printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
- }
- if (!res) {
- String failMessage = "SetThreadContext failed for thread handle 0x" +
- Integer.toHexString(handle);
- if (mustDuplicateHandle) {
- failMessage = failMessage + ", duplicated from thread handle " +
- Integer.toHexString(threadHandleValue);
- }
- throw new DebuggerException(failMessage);
- }
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- /** Fetches the Win32 LDT_ENTRY for the given thread and selector.
- This data structure allows the conversion of a segment-relative
- address to a linear virtual address. For example, it allows the
- expression of operations like "mov eax, fs:[18h]", which fetches
- the thread information block, allowing access to the thread
- ID. */
- public synchronized Win32LDTEntry getThreadSelectorEntry(int threadHandleValue,
- boolean mustDuplicateHandle,
- int selector)
- throws DebuggerException {
- try {
- int handle = threadHandleValue;
- if (mustDuplicateHandle) {
- printlnToOutput("duphandle 0x" + Integer.toHexString(threadHandleValue));
- if (!in.parseBoolean()) {
- throw new DebuggerException("Error duplicating thread handle 0x" + threadHandleValue);
- }
- handle = (int) in.parseAddress(); // Must close to avoid leaks
- }
- printlnToOutput("selectorentry 0x" + Integer.toHexString(handle) + " " + selector);
- if (!in.parseBoolean()) {
- if (mustDuplicateHandle) {
- printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
- }
- throw new DebuggerException("GetThreadContext failed for thread handle 0x" + handle +
- ", duplicated from thread handle " + threadHandleValue);
- }
- // Parse result. See
- // src/os/win32/agent/README-commands.txt for the format.
- short limitLow = (short) in.parseAddress();
- short baseLow = (short) in.parseAddress();
- byte baseMid = (byte) in.parseAddress();
- byte flags1 = (byte) in.parseAddress();
- byte flags2 = (byte) in.parseAddress();
- byte baseHi = (byte) in.parseAddress();
- return new Win32LDTEntry(limitLow, baseLow, baseMid, flags1, flags2, baseHi);
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- public synchronized List getThreadList() throws DebuggerException {
- if (!suspended) {
- throw new DebuggerException("Process not suspended");
- }
-
- try {
- printlnToOutput("threadlist");
- List ret = new ArrayList();
- int numThreads = in.parseInt();
- for (int i = 0; i < numThreads; i++) {
- int handle = (int) in.parseAddress();
- ret.add(new Win32Thread(this, handle));
- }
- return ret;
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- public synchronized List getLoadObjectList() throws DebuggerException {
- if (!suspended) {
- throw new DebuggerException("Process not suspended");
- }
-
- try {
- if (loadObjects == null) {
- loadObjects = new ArrayList();
- nameToDllMap = new HashMap();
- // Get list of library names and base addresses
- printlnToOutput("libinfo");
- int numInfo = in.parseInt();
-
- for (int i = 0; i < numInfo; i++) {
- // NOTE: because Win32 is case insensitive, we standardize on
- // lowercase file names.
- String fullPathName = parseString().toLowerCase();
- Address base = newAddress(in.parseAddress());
-
- File file = new File(fullPathName);
- long size = file.length();
- DLL dll = new DLL(this, fullPathName, size, base);
- String name = file.getName();
- nameToDllMap.put(name, dll);
- loadObjects.add(dll);
- }
- }
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
-
- return loadObjects;
- }
-
- //----------------------------------------------------------------------
- // Process control access
- //
-
- public synchronized void writeBytesToProcess(long startAddress, long numBytes, byte[] data)
- throws UnmappedAddressException, DebuggerException {
- try {
- printToOutput("poke 0x" + Long.toHexString(startAddress) +
- " |");
- writeIntToOutput((int) numBytes);
- writeToOutput(data, 0, (int) numBytes);
- printlnToOutput("");
- if (!in.parseBoolean()) {
- throw new UnmappedAddressException(startAddress);
- }
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- public synchronized void suspend() throws DebuggerException {
- try {
- if (suspended) {
- throw new DebuggerException("Process already suspended");
- }
- printlnToOutput("suspend");
- suspended = true;
- enableCache();
- reresolveLoadObjects();
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- public synchronized void resume() throws DebuggerException {
- try {
- if (!suspended) {
- throw new DebuggerException("Process not suspended");
- }
- disableCache();
- printlnToOutput("resume");
- suspended = false;
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- public synchronized boolean isSuspended() throws DebuggerException {
- return suspended;
- }
-
- public synchronized void setBreakpoint(Address addr) throws DebuggerException {
- if (!suspended) {
- throw new DebuggerException("Process not suspended");
- }
-
- long addrVal = getAddressValue(addr);
- Long where = new Long(addrVal);
- if (breakpoints.get(where) != null) {
- throw new DebuggerException("Breakpoint already set at " + addr);
- }
- Byte what = new Byte(readBytes(addrVal, 1)[0]);
- // Now put 0xCC (int 3) at the target address, fail if can not
- writeBytesToProcess(addrVal, 1, new byte[] { (byte) 0xCC });
- // OK, the breakpoint is set.
- breakpoints.put(where, what);
- }
-
- public synchronized void clearBreakpoint(Address addr) throws DebuggerException {
- if (!suspended) {
- throw new DebuggerException("Process not suspended");
- }
-
- long addrVal = getAddressValue(addr);
- Long where = new Long(addrVal);
- Byte what = (Byte) breakpoints.get(where);
- if (what == null) {
- throw new DebuggerException("Breakpoint not set at " + addr);
- }
- // Put original data back at address
- writeBytesToProcess(addrVal, 1, new byte[] { what.byteValue() });
- // OK, breakpoint is cleared
- breakpoints.remove(where);
- }
-
- public synchronized boolean isBreakpointSet(Address addr) throws DebuggerException {
- return (breakpoints.get(new Long(getAddressValue(addr))) != null);
- }
-
- // Following constants taken from winnt.h
- private static final int EXCEPTION_DEBUG_EVENT = 1;
- private static final int LOAD_DLL_DEBUG_EVENT = 6;
- private static final int UNLOAD_DLL_DEBUG_EVENT = 7;
- private static final int EXCEPTION_ACCESS_VIOLATION = 0xC0000005;
- private static final int EXCEPTION_BREAKPOINT = 0x80000003;
- private static final int EXCEPTION_SINGLE_STEP = 0x80000004;
-
- public synchronized DebugEvent debugEventPoll() throws DebuggerException {
- if (curDebugEvent != null) {
- return curDebugEvent;
- }
-
- try {
- printlnToOutput("pollevent");
- if (!in.parseBoolean()) {
- return null;
- }
- // Otherwise, got a debug event. Need to figure out what kind it is.
- int handle = (int) in.parseAddress();
- ThreadProxy thread = new Win32Thread(this, handle);
- int code = in.parseInt();
- DebugEvent ev = null;
- switch (code) {
- case LOAD_DLL_DEBUG_EVENT: {
- Address addr = newAddress(in.parseAddress());
- ev = BasicDebugEvent.newLoadObjectLoadEvent(thread, addr);
- break;
- }
-
- case UNLOAD_DLL_DEBUG_EVENT: {
- Address addr = newAddress(in.parseAddress());
- ev = BasicDebugEvent.newLoadObjectUnloadEvent(thread, addr);
- break;
- }
-
- case EXCEPTION_DEBUG_EVENT: {
- int exceptionCode = in.parseInt();
- Address pc = newAddress(in.parseAddress());
- switch (exceptionCode) {
- case EXCEPTION_ACCESS_VIOLATION:
- boolean wasWrite = in.parseBoolean();
- Address addr = newAddress(in.parseAddress());
- ev = BasicDebugEvent.newAccessViolationEvent(thread, pc, wasWrite, addr);
- break;
-
- case EXCEPTION_BREAKPOINT:
- ev = BasicDebugEvent.newBreakpointEvent(thread, pc);
- break;
-
- case EXCEPTION_SINGLE_STEP:
- ev = BasicDebugEvent.newSingleStepEvent(thread, pc);
- break;
-
- default:
- ev = BasicDebugEvent.newUnknownEvent(thread,
- "Exception 0x" + Integer.toHexString(exceptionCode) +
- " at PC " + pc);
- break;
- }
- break;
- }
-
- default:
- ev = BasicDebugEvent.newUnknownEvent(thread,
- "Debug event " + code + " occurred");
- break;
- }
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(ev != null, "Must have created event");
- }
- curDebugEvent = ev;
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
-
- return curDebugEvent;
- }
-
- public synchronized void debugEventContinue() throws DebuggerException {
- if (curDebugEvent == null) {
- throw new DebuggerException("No debug event pending");
- }
-
- try {
- ///////////////////////////////////////////////////////////////////
- // //
- // FIXME: this **must** be modified to handle breakpoint events
- // properly. Must temporarily remove the breakpoint and enable
- // single-stepping mode (hiding those single-step events from
- // the user unless they have been requested; currently there is
- // no way to request single-step events; and it isn't clear how
- // to enable them or how the hardware and/or OS typically
- // supports them, i.e., are they on a per-process or per-thread
- // level?) until the process steps past the breakpoint, then put
- // the breakpoint back.
- // //
- ///////////////////////////////////////////////////////////////////
-
- DebugEvent.Type t = curDebugEvent.getType();
- boolean shouldPassOn = true;
- if (t == DebugEvent.Type.BREAKPOINT) {
- // FIXME: correct algorithm appears to be as follows:
- //
- // 1. Check to see whether we know about this breakpoint. If
- // not, it's requested by the user's program and we should
- // ignore it (not pass it on to the program).
- //
- // 2. Replace the original opcode.
- //
- // 3. Set single-stepping mode in the debug registers.
- //
- // 4. Back up the PC.
- //
- // 5. In debugEventPoll(), watch for a single-step event on
- // this thread. When we get it, put the breakpoint back. Only
- // deliver that single-step event if the user has requested
- // single-step events (FIXME: must figure out whether they are
- // per-thread or per-process, and also expose a way to turn
- // them on.)
-
- // To make breakpoints work for now, we will just back up the
- // PC, which we have to do in order to not disrupt the program
- // execution in case the user decides to disable the breakpoint.
-
- if (breakpoints.get(new Long(getAddressValue(curDebugEvent.getPC()))) != null) {
- System.err.println("Backing up PC due to breakpoint");
- X86ThreadContext ctx = (X86ThreadContext) curDebugEvent.getThread().getContext();
- ctx.setRegister(X86ThreadContext.EIP, ctx.getRegister(X86ThreadContext.EIP) - 1);
- curDebugEvent.getThread().setContext(ctx);
- } else {
- System.err.println("Skipping back up of PC since I didn't know about this breakpoint");
- System.err.println("Known breakpoints:");
- for (Iterator iter = breakpoints.keySet().iterator(); iter.hasNext(); ) {
- System.err.println(" 0x" + Long.toHexString(((Long) iter.next()).longValue()));
- }
- }
- shouldPassOn = false;
- } else if (t == DebugEvent.Type.SINGLE_STEP) {
- shouldPassOn = false;
- }
- // Other kinds of debug events are either ignored if passed on
- // or probably should be passed on so the program exits
- // FIXME: generate process exiting events (should be easy)
-
- int val = (shouldPassOn ? 1 : 0);
- printlnToOutput("continueevent " + val);
- if (!in.parseBoolean()) {
- throw new DebuggerException("Unknown error while attempting to continue past debug event");
- }
- curDebugEvent = null;
- } catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- //--------------------------------------------------------------------------------
- // Address access
- //
-
- /** From the Debugger interface */
- public long getAddressValue(Address addr) {
- if (addr == null) return 0;
- return ((Win32Address) addr).getValue();
- }
-
- /** From the Win32Debugger interface */
- public Address newAddress(long value) {
- if (value == 0) return null;
- return new Win32Address(this, value);
- }
-
- //--------------------------------------------------------------------------------
- // Internals only below this point
- //
-
- private String parseString() throws IOException {
- int charSize = in.parseInt();
- int numChars = in.parseInt();
- in.skipByte();
- String str;
- if (charSize == 1) {
- str = in.readByteString(numChars);
- } else {
- str = in.readCharString(numChars);
- }
- return str;
- }
-
- /** Looks up an address in the remote process's address space.
- Returns 0 if symbol not found or upon error. Package private to
- allow Win32DebuggerRemoteIntfImpl access. NOTE that this returns
- a long instead of an Address because we do not want to serialize
- Addresses. */
- synchronized long lookupInProcess(String objectName, String symbol) {
- // NOTE: this assumes that process is suspended (which is probably
- // necessary assumption given that DLLs can be loaded/unloaded as
- // process runs). Should update documentation.
- if (nameToDllMap == null) {
- getLoadObjectList();
- }
- DLL dll = (DLL) nameToDllMap.get(objectName);
- // The DLL can be null because we use this to search through known
- // DLLs in HotSpotTypeDataBase (for example)
- if (dll != null) {
- Win32Address addr = (Win32Address) dll.lookupSymbol(symbol);
- if (addr != null) {
- return addr.getValue();
- }
- }
- return 0;
- }
-
- /** This reads bytes from the remote process. */
- public synchronized ReadResult readBytesFromProcess(long address, long numBytes)
- throws UnmappedAddressException, DebuggerException {
- try {
- String cmd = "peek " + utils.addressValueToString(address) + " " + numBytes;
- printlnToOutput(cmd);
- while (in.readByte() != 'B') {
- }
- byte res = in.readByte();
- if (res == 0) {
- System.err.println("Failing command: " + cmd);
- throw new DebuggerException("Read of remote process address space failed");
- }
- // NOTE: must read ALL of the data regardless of whether we need
- // to throw an UnmappedAddressException. Otherwise will corrupt
- // the input stream each time we have a failure. Not good. Do
- // not want to risk "flushing" the input stream in case a huge
- // read has a hangup in the middle and we leave data on the
- // stream.
- byte[] buf = new byte[(int) numBytes];
- boolean bailOut = false;
- long failureAddress = 0;
- while (numBytes > 0) {
- long len = in.readUnsignedInt();
- boolean isMapped = ((in.readByte() == 0) ? false : true);
- if (!isMapped) {
- if (!bailOut) {
- bailOut = true;
- failureAddress = address;
- }
- } else {
- // This won't work if we have unmapped regions, but if we do
- // then we're going to throw an exception anyway
-
- // NOTE: there is a factor of 20 speed difference between
- // these two ways of doing this read.
- in.readBytes(buf, 0, (int) len);
- }
-
- // Do NOT do this:
- // for (int i = 0; i < (int) len; i++) {
- // buf[i] = in.readByte();
- // }
-
- numBytes -= len;
- address += len;
- }
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(numBytes == 0, "Bug in debug server's implementation of peek");
- }
- if (bailOut) {
- return new ReadResult(failureAddress);
- }
- return new ReadResult(buf);
- }
- catch (IOException e) {
- throw new DebuggerException(e);
- }
- }
-
- /** Convenience routines */
- private void printlnToOutput(String s) throws IOException {
- out.println(s);
- if (out.checkError()) {
- throw new IOException("Error occurred while writing to debug server");
- }
- }
-
- private void printToOutput(String s) throws IOException {
- out.print(s);
- if (out.checkError()) {
- throw new IOException("Error occurred while writing to debug server");
- }
- }
-
- private void writeIntToOutput(int val) throws IOException {
- rawOut.writeInt(val);
- rawOut.flush();
- }
-
- private void writeToOutput(byte[] buf, int off, int len) throws IOException {
- rawOut.write(buf, off, len);
- rawOut.flush();
- }
-
- /** Connects to the debug server, setting up out and in streams. */
- private void connectToDebugServer() throws IOException {
- // Try for a short period of time to connect to debug server; time out
- // with failure if didn't succeed
- debuggerSocket = null;
- long endTime = System.currentTimeMillis() + SHORT_TIMEOUT;
-
- while ((debuggerSocket == null) && (System.currentTimeMillis() < endTime)) {
- try {
- // FIXME: this does not work if we are on a DHCP machine which
- // did not get an IP address this session. It appears to use
- // an old cached address and the connection does not actually
- // succeed. Must file a bug.
- // debuggerSocket = new Socket(InetAddress.getLocalHost(), PORT);
- debuggerSocket = new Socket(InetAddress.getByName("127.0.0.1"), PORT);
- debuggerSocket.setTcpNoDelay(true);
- }
- catch (IOException e) {
- // Swallow IO exceptions while attempting connection
- debuggerSocket = null;
- try {
- // Don't swamp the CPU
- Thread.sleep(750);
- }
- catch (InterruptedException ex) {
- }
- }
- }
-
- if (debuggerSocket == null) {
- // Failed to connect because of timeout
- throw new DebuggerException("Timed out while attempting to connect to debug server (please start SwDbgSrv.exe)");
- }
-
- out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(debuggerSocket.getOutputStream(), "US-ASCII")), true);
- rawOut = new DataOutputStream(new BufferedOutputStream(debuggerSocket.getOutputStream()));
- in = new InputLexer(new BufferedInputStream(debuggerSocket.getInputStream()));
- }
-
- private DLL findDLLByName(String fullPathName) {
- for (Iterator iter = loadObjects.iterator(); iter.hasNext(); ) {
- DLL dll = (DLL) iter.next();
- if (dll.getName().equals(fullPathName)) {
- return dll;
- }
- }
- return null;
- }
-
- private void reresolveLoadObjects() throws DebuggerException {
- try {
- // It is too expensive to throw away the loadobject list every
- // time the process is suspended, largely because of debug
- // information re-parsing. When we suspend the target process we
- // instead fetch the list of loaded libraries in the target and
- // see whether any loadobject needs to be thrown away (because it
- // was unloaded) or invalidated (because it was unloaded and
- // reloaded at a different target address). Note that we don't
- // properly handle the case of a loaded DLL being unloaded,
- // recompiled, and reloaded. We could handle this by keeping a
- // time stamp.
-
- if (loadObjects == null) {
- return;
- }
-
- // Need to create new list since have to figure out which ones
- // were unloaded
- List newLoadObjects = new ArrayList();
-
- // Get list of library names and base addresses
- printlnToOutput("libinfo");
- int numInfo = in.parseInt();
-
- for (int i = 0; i < numInfo; i++) {
- // NOTE: because Win32 is case insensitive, we standardize on
- // lowercase file names.
- String fullPathName = parseString().toLowerCase();
- Address base = newAddress(in.parseAddress());
-
- // Look for full path name in DLL list
- DLL dll = findDLLByName(fullPathName);
- boolean mustLoad = true;
- if (dll != null) {
- loadObjects.remove(dll);
-
- // See whether base addresses match; otherwise, need to reload
- if (AddressOps.equal(base, dll.getBase())) {
- mustLoad = false;
- }
- }
-
- if (mustLoad) {
- // Create new DLL
- File file = new File(fullPathName);
- long size = file.length();
- String name = file.getName();
- dll = new DLL(this, fullPathName, size, base);
- nameToDllMap.put(name, dll);
- }
- newLoadObjects.add(dll);
- }
-
- // All remaining entries in loadObjects have to be removed from
- // the nameToDllMap
- for (Iterator dllIter = loadObjects.iterator(); dllIter.hasNext(); ) {
- DLL dll = (DLL) dllIter.next();
- for (Iterator iter = nameToDllMap.keySet().iterator(); iter.hasNext(); ) {
- String name = (String) iter.next();
- if (nameToDllMap.get(name) == dll) {
- nameToDllMap.remove(name);
- break;
- }
- }
- }
-
- loadObjects = newLoadObjects;
- } catch (IOException e) {
- loadObjects = null;
- nameToDllMap = null;
- throw new DebuggerException(e);
- }
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32LDTEntry.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import java.io.Serializable;
-
-/** Describes an LDT entry. (Some of the descriptions are taken
- directly from Microsoft's documentation and are copyrighted by
- Microsoft.) */
-
-class Win32LDTEntry implements Serializable {
- private short limitLow;
- private short baseLow;
- private byte baseMid;
- private byte flags1;
- private byte flags2;
- private byte baseHi;
-
- private Win32LDTEntry() {}
-
- public Win32LDTEntry(short limitLow,
- short baseLow,
- byte baseMid,
- byte flags1,
- byte flags2,
- byte baseHi) {
- this.limitLow = limitLow;
- this.baseLow = baseLow;
- this.baseMid = baseMid;
- this.flags1 = flags1;
- this.flags2 = flags2;
- this.baseHi = baseHi;
- }
-
- /** Returns base address of segment */
- public long getBase() { return ( (baseLow & 0xFFFF) |
- ((baseMid & 0xFF) << 16) |
- ((baseHi & 0xFF) << 24)) & 0xFFFFFFFF; }
-
- public short getLimitLow() { return limitLow; }
- public short getBaseLow() { return baseLow; }
- public byte getBaseMid() { return baseMid; }
- public byte getBaseHi() { return baseHi; }
-
- // FIXME: must verify mask and shift are correct
- /** Describes type of segment. See TYPE_ portion of {@link
- sun.jvm.hotspot.debugger.win32.Win32LDTEntryConstants}. */
- public int getType() { return (flags1 & 0x1F); }
-
- // FIXME: verify mask and shift are correct
- /** Privilege level of descriptor: 0 = most privileged, 3 = least privileged */
- public int getPrivilegeLevel() { return ((flags1 & 0x60) >> 5); }
-
- // FIXME: verify mask is correct
- /** Is segment present in physical memory? */
- public boolean isSegmentPhysical() { return ((flags1 & 0x70) != 0); }
-
- // FIXME: verify mask and shift are correct
- /** High bits (16-19) of the address of the last byte of the segment */
- public int getLimitHi() { return (flags2 & 0x0F); }
-
- // FIXME: verify mask is correct
- /** <P> Size of segment. If the segment is a data segment, this
- member contains 1 if the segment is larger than 64 kilobytes (K)
- or 0 if the segment is smaller than or equal to 64K. </P>
-
- <P> If the segment is a code segment, this member contains 1 if
- the segment is a code segment and runs with the default (native
- mode) instruction set. This member contains 0 if the code
- segment is an 80286 code segment and runs with 16-bit offsets
- and the 80286-compatible instruction set. </P> */
- public boolean isDefaultBig() { return ((flags2 & 0x40) != 0); }
-
- // FIXME: verify mask is correct
- /** Returns true if segment is page granular, false if byte
- granular. */
- public boolean isPageGranular() { return ((flags2 & 0x80) != 0); }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32LDTEntryConstants.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-/** Enumerates flags in Win32LDTEntry */
-
-interface Win32LDTEntryConstants {
- // Types of segments
- public static final int TYPE_READ_ONLY_DATA = 0;
- public static final int TYPE_READ_WRITE_DATA = 1;
- public static final int TYPE_UNUSED = 2;
- public static final int TYPE_READ_WRITE_EXPAND_DOWN_DATA = 3;
- public static final int TYPE_EXECUTE_ONLY_CODE = 4;
- public static final int TYPE_EXECUTABLE_READABLE_CODE = 5;
- public static final int TYPE_EXECUTE_ONLY_CONFORMING_CODE = 6;
- public static final int TYPE_EXECUTABLE_READABLE_CONFORMING_CODE = 7;
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32OopHandle.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import sun.jvm.hotspot.debugger.*;
-
-class Win32OopHandle extends Win32Address implements OopHandle {
- Win32OopHandle(Win32Debugger debugger, long addr) {
- super(debugger, addr);
- }
-
- public boolean equals(Object arg) {
- if (arg == null) {
- return false;
- }
-
- if (!(arg instanceof Win32OopHandle)) {
- return false;
- }
-
- return (addr == ((Win32Address) arg).addr);
- }
-
- public Address addOffsetTo (long offset) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("addOffsetTo not applicable to OopHandles (interior object pointers not allowed)");
- }
-
- public Address andWithMask(long mask) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("andWithMask not applicable to OopHandles (i.e., anything but C addresses)");
- }
-
- public Address orWithMask(long mask) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("orWithMask not applicable to OopHandles (i.e., anything but C addresses)");
- }
-
- public Address xorWithMask(long mask) throws UnsupportedOperationException {
- throw new UnsupportedOperationException("xorWithMask not applicable to OopHandles (i.e., anything but C addresses)");
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Thread.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.x86.*;
-
-class Win32Thread implements ThreadProxy {
- private Win32Debugger debugger;
- private int handle;
- private boolean mustDuplicate;
- private boolean gotID;
- private int id;
-
- /** The address argument must be the address of the HANDLE of the
- desired thread in the target process. */
- Win32Thread(Win32Debugger debugger, Address addr) {
- this.debugger = debugger;
- // FIXME: size of data fetched here should be configurable.
- // However, making it so would produce a dependency on the "types"
- // package from the debugger package, which is not desired.
- this.handle = (int) addr.getCIntegerAt(0, 4, true);
- // Thread handles in the target process must be duplicated before
- // fetching their contexts
- mustDuplicate = true;
- gotID = false;
- }
-
- /** The integer argument must be the value of a HANDLE received from
- the "threadlist" operation. */
- Win32Thread(Win32Debugger debugger, long handle) {
- this.debugger = debugger;
- this.handle = (int) handle;
- mustDuplicate = false;
- gotID = false;
- }
-
- public ThreadContext getContext() throws IllegalThreadStateException {
- if (!debugger.isSuspended()) {
- throw new IllegalThreadStateException("Target process must be suspended");
- }
- long[] data = debugger.getThreadIntegerRegisterSet(handle, mustDuplicate);
- Win32ThreadContext context = new Win32ThreadContext(debugger);
- for (int i = 0; i < data.length; i++) {
- context.setRegister(i, data[i]);
- }
- return context;
- }
-
- public boolean canSetContext() throws DebuggerException {
- return true;
- }
-
- public void setContext(ThreadContext thrCtx)
- throws IllegalThreadStateException, DebuggerException {
- if (!debugger.isSuspended()) {
- throw new IllegalThreadStateException("Target process must be suspended");
- }
- X86ThreadContext context = (X86ThreadContext) thrCtx;
- long[] data = new long[X86ThreadContext.NPRGREG];
- for (int i = 0; i < data.length; i++) {
- data[i] = context.getRegister(i);
- }
- debugger.setThreadIntegerRegisterSet(handle, mustDuplicate, data);
- }
-
- public boolean equals(Object obj) {
- if ((obj == null) || !(obj instanceof Win32Thread)) {
- return false;
- }
-
- return (((Win32Thread) obj).getThreadID() == getThreadID());
- }
-
- public int hashCode() {
- return getThreadID();
- }
-
- public String toString() {
- return Integer.toString(getThreadID());
- }
-
- /** Retrieves the thread ID of this thread by examining the Thread
- Information Block. */
- private int getThreadID() {
- if (!gotID) {
- try {
- // Get thread context
- X86ThreadContext context = (X86ThreadContext) getContext();
- // Get LDT entry for FS register
- Win32LDTEntry ldt =
- debugger.getThreadSelectorEntry(handle,
- mustDuplicate,
- (int) context.getRegister(X86ThreadContext.FS));
- // Get base address of segment = Thread Environment Block (TEB)
- Address teb = debugger.newAddress(ldt.getBase());
- // Thread ID is at offset 0x24
- id = (int) teb.getCIntegerAt(0x24, 4, true);
- gotID = true;
- } catch (AddressException e) {
- throw new DebuggerException(e);
- }
- }
-
- return id;
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32ThreadContext.java Tue Sep 13 20:28:00 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.debugger.win32;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.x86.*;
-
-class Win32ThreadContext extends X86ThreadContext {
- private Win32Debugger debugger;
-
- public Win32ThreadContext(Win32Debugger debugger) {
- super();
- this.debugger = debugger;
- }
-
- public void setRegisterAsAddress(int index, Address value) {
- setRegister(index, debugger.getAddressValue(value));
- }
-
- public Address getRegisterAsAddress(int index) {
- return debugger.newAddress(getRegister(index));
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/SADebugServer.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/SADebugServer.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,14 +51,6 @@
usage();
}
- // By default, SA agent classes prefer dbx debugger to proc debugger
- // and Windows process debugger to windbg debugger. SA expects
- // special properties to be set to choose other debuggers. For SA/JDI,
- // we choose proc, windbg debuggers instead of the defaults.
-
- System.setProperty("sun.jvm.hotspot.debugger.useProcDebugger", "true");
- System.setProperty("sun.jvm.hotspot.debugger.useWindbgDebugger", "true");
-
// delegate to the actual SA debug server.
sun.jvm.hotspot.DebugServer.main(args);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java Thu Sep 15 12:44:09 2011 -0700
@@ -263,14 +263,6 @@
this.hashCode() + "]");
((com.sun.tools.jdi.VirtualMachineManagerImpl)mgr).addVirtualMachine(this);
-
- // By default SA agent classes prefer dbx debugger to proc debugger
- // and Windows process debugger to windbg debugger. SA expects
- // special properties to be set to choose other debuggers. We will set
- // those here before attaching to SA agent.
-
- System.setProperty("sun.jvm.hotspot.debugger.useProcDebugger", "true");
- System.setProperty("sun.jvm.hotspot.debugger.useWindbgDebugger", "true");
}
// we reflectively use newly spec'ed class because our ALT_BOOTDIR
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArrayData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// ArrayData
+//
+// A ArrayData is a base class for accessing profiling data which does
+// not have a statically known size. It consists of an array length
+// and an array start.
+abstract class ArrayData extends ProfileData {
+
+ static final int arrayLenOffSet = 0;
+ static final int arrayStartOffSet = 1;
+
+ int arrayUintAt(int index) {
+ int aindex = index + arrayStartOffSet;
+ return uintAt(aindex);
+ }
+ int arrayIntAt(int index) {
+ int aindex = index + arrayStartOffSet;
+ return intAt(aindex);
+ }
+ Oop arrayOopAt(int index) {
+ int aindex = index + arrayStartOffSet;
+ return oopAt(aindex);
+ }
+
+ // Code generation support for subclasses.
+ static int arrayElementOffset(int index) {
+ return cellOffset(arrayStartOffSet + index);
+ }
+
+ ArrayData(DataLayout layout) {
+ super(layout);
+ }
+
+ static int staticCellCount() {
+ return -1;
+ }
+
+ int arrayLen() {
+ return intAt(arrayLenOffSet);
+ }
+
+ public int cellCount() {
+ return arrayLen() + 1;
+ }
+
+ // Code generation support
+ static int arrayLenOffset() {
+ return cellOffset(arrayLenOffSet);
+ }
+ static int arrayStartOffset() {
+ return cellOffset(arrayStartOffSet);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/BitData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// BitData
+//
+// A BitData holds a flag or two in its header.
+public class BitData extends ProfileData {
+
+ // nullSeen:
+ // saw a null operand (cast/aastore/instanceof)
+ static final int nullSeenFlag = DataLayout.firstFlag + 0;
+ static final int bitCellCount = 0;
+
+ public BitData(DataLayout layout) {
+ super(layout);
+ }
+
+ static int staticCellCount() {
+ return bitCellCount;
+ }
+
+ public int cellCount() {
+ return staticCellCount();
+ }
+
+ // Accessor
+
+ // The nullSeen flag bit is specially known to the interpreter.
+ // Consulting it allows the compiler to avoid setting up nullCheck traps.
+ boolean nullSeen() { return flagAt(nullSeenFlag); }
+
+ // Code generation support
+ // static int nullSeenByteConstant() {
+ // return flagNumberToByteConstant(nullSeenFlag);
+ // }
+
+ static int bitDataSize() {
+ return cellOffset(bitCellCount);
+ }
+
+ public void printDataOn(PrintStream st) {
+ printShared(st, "BitData");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/BranchData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// BranchData
+//
+// A BranchData is used to access profiling data for a two-way branch.
+// It consists of taken and notTaken counts as well as a data displacement
+// for the taken case.
+public class BranchData extends JumpData {
+
+ static final int notTakenOffSet = jumpCellCount;
+ static final int branchCellCount = notTakenOffSet + 1;
+
+ public BranchData(DataLayout layout) {
+ super(layout);
+ //assert(layout.tag() == DataLayout.branchDataTag, "wrong type");
+ }
+
+ static int staticCellCount() {
+ return branchCellCount;
+ }
+
+ public int cellCount() {
+ return staticCellCount();
+ }
+
+ // Direct accessor
+ int notTaken() {
+ return uintAt(notTakenOffSet);
+ }
+
+ // Code generation support
+ static int notTakenOffset() {
+ return cellOffset(notTakenOffSet);
+ }
+ static int branchDataSize() {
+ return cellOffset(branchCellCount);
+ }
+
+ public void printDataOn(PrintStream st) {
+ printShared(st, "BranchData");
+ st.println("taken(" + taken() + ") displacement(" + displacement() + ")");
+ tab(st);
+ st.println("not taken(" + notTaken() + ")");
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CIntField.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CIntField.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,9 @@
public long getValue(Oop obj) {
return obj.getHandle().getCIntegerAt(getOffset(), size, isUnsigned);
}
+ public long getValue(Address addr) {
+ return addr.getCIntegerAt(getOffset(), size, isUnsigned);
+ }
public void setValue(Oop obj, long value) throws MutationException {
// Fix this: set* missing in Address
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/CounterData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// CounterData
+//
+// A CounterData corresponds to a simple counter.
+public class CounterData extends BitData {
+
+ static final int countOff = 0;
+ static final int counterCellCount = 1;
+
+ public CounterData(DataLayout layout) {
+ super(layout);
+ }
+
+ static int staticCellCount() {
+ return counterCellCount;
+ }
+
+ public int cellCount() {
+ return staticCellCount();
+ }
+
+ // Direct accessor
+ int count() {
+ return uintAt(countOff);
+ }
+
+ // Code generation support
+ static int countOffset() {
+ return cellOffset(countOff);
+ }
+ static int counterDataSize() {
+ return cellOffset(counterCellCount);
+ }
+
+ public void printDataOn(PrintStream st) {
+ printShared(st, "CounterData");
+ st.println("count(" + count() + ")");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class DataLayout {
+ public static final int noTag = 0;
+ public static final int bitDataTag = 1;
+ public static final int counterDataTag = 2;
+ public static final int jumpDataTag= 3;
+ public static final int receiverTypeDataTag = 4;
+ public static final int virtualCallDataTag = 5;
+ public static final int retDataTag = 6;
+ public static final int branchDataTag = 7;
+ public static final int multiBranchDataTag = 8;
+
+ // The _struct._flags word is formatted as [trapState:4 | flags:4].
+ // The trap state breaks down further as [recompile:1 | reason:3].
+ // This further breakdown is defined in deoptimization.cpp.
+ // See Deoptimization.trapStateReason for an assert that
+ // trapBits is big enough to hold reasons < reasonRecordedLimit.
+ //
+ // The trapState is collected only if ProfileTraps is true.
+ public static final int trapBits = 1+3; // 3: enough to distinguish [0..reasonRecordedLimit].
+ public static final int trapShift = 8 - trapBits;
+ public static final int trapMask = Bits.rightNBits(trapBits);
+ public static final int trapMaskInPlace = (trapMask << trapShift);
+ public static final int flagLimit = trapShift;
+ public static final int flagMask = Bits.rightNBits(flagLimit);
+ public static final int firstFlag = 0;
+
+ private Address data;
+
+ private int offset;
+
+ private boolean handlized;
+
+ public DataLayout(MethodData d, int o) {
+ data = d.getHandle();
+ offset = o;
+ }
+
+ public DataLayout(Address d, int o) {
+ data = d;
+ offset = o;
+ handlized = true;
+ }
+
+ public int dp() { return offset; }
+
+ private int getU11(int at) {
+ return data.getJByteAt(offset + at) & 0xff;
+ }
+
+ private int getU22(int at) {
+ return data.getJShortAt(offset + at) & 0xffff;
+ }
+
+ int cellAt(int index) {
+ // Cells are intptr_t sized but only contain ints as raw values
+ return (int)data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false);
+ }
+
+ Oop oopAt(int index) {
+ OopHandle handle;
+ if (handlized) {
+ throw new InternalError("unsupported");
+ }
+ handle = data.getOopHandleAt(offset + cellOffset(index));
+ return VM.getVM().getObjectHeap().newOop(handle);
+ }
+
+ public Address addressAt(int index) {
+ OopHandle handle;
+ if (handlized) {
+ return data.getAddressAt(offset + cellOffset(index));
+ } else {
+ return data.getOopHandleAt(offset + cellOffset(index));
+ }
+ }
+
+ // Every data layout begins with a header. This header
+ // contains a tag, which is used to indicate the size/layout
+ // of the data, 4 bits of flags, which can be used in any way,
+ // 4 bits of trap history (none/one reason/many reasons),
+ // and a bci, which is used to tie this piece of data to a
+ // specific bci in the bytecodes.
+ // union {
+ // intptrT _bits;
+ // struct {
+ // u1 _tag;
+ // u1 _flags;
+ // u2 _bci;
+ // } _struct;
+ // } _header;
+
+ // Some types of data layouts need a length field.
+ static boolean needsArrayLen(int tag) {
+ return (tag == multiBranchDataTag);
+ }
+
+ public static final int counterIncrement = 1;
+
+ // Size computation
+ static int headerSizeInBytes() {
+ return MethodData.cellSize;
+ }
+ static int headerSizeInCells() {
+ return 1;
+ }
+
+ static int computeSizeInBytes(int cellCount) {
+ return headerSizeInBytes() + cellCount * MethodData.cellSize;
+ }
+
+ // Initialization
+ // void initialize(int tag, int bci, int cellCount);
+
+ // Accessors
+ public int tag() {
+ return getU11(0);
+ }
+
+ // Return a few bits of trap state. Range is [0..trapMask].
+ // The state tells if traps with zero, one, or many reasons have occurred.
+ // It also tells whether zero or many recompilations have occurred.
+ // The associated trap histogram in the MDO itself tells whether
+ // traps are common or not. If a BCI shows that a trap X has
+ // occurred, and the MDO shows N occurrences of X, we make the
+ // simplifying assumption that all N occurrences can be blamed
+ // on that BCI.
+ int trapState() {
+ return (flags() >> trapShift) & trapMask;
+ }
+
+ int flags() {
+ return getU11(1);
+ }
+
+ int bci() {
+ return getU22(2);
+ }
+
+ boolean flagAt(int flagNumber) {
+ // assert(flagNumber < flagLimit, "oob");
+ return (flags() & (0x1 << flagNumber)) != 0;
+ }
+
+ // Low-level support for code generation.
+ static int headerOffset() {
+ return 0;
+ }
+ static int tagOffset() {
+ return 0;
+ }
+ static int flagsOffset() {
+ return 1;
+ }
+ static int bciOffset() {
+ return 2;
+ }
+ public static int cellOffset(int index) {
+ return MethodData.cellSize + index * MethodData.cellSize;
+ }
+ // // Return a value which, when or-ed as a byte into _flags, sets the flag.
+ // static int flagNumberToByteConstant(int flagNumber) {
+ // assert(0 <= flagNumber && flagNumber < flagLimit, "oob");
+ // DataLayout temp; temp.setHeader(0);
+ // temp.setFlagAt(flagNumber);
+ // return temp._header._struct._flags;
+ // }
+ // // Return a value which, when or-ed as a word into _header, sets the flag.
+ // static intptrT flagMaskToHeaderMask(int byteConstant) {
+ // DataLayout temp; temp.setHeader(0);
+ // temp._header._struct._flags = byteConstant;
+ // return temp._header._bits;
+ // }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Field.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Field.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,28 +39,20 @@
/** Constructor for fields that are named in an InstanceKlass's
fields array (i.e., named, non-VM fields) */
- Field(InstanceKlass holder, int fieldArrayIndex) {
+ Field(InstanceKlass holder, int fieldIndex) {
this.holder = holder;
- this.fieldArrayIndex = fieldArrayIndex;
+ this.fieldIndex = fieldIndex;
+
+ offset = holder.getFieldOffset(fieldIndex);
+ genericSignature = holder.getFieldGenericSignature(fieldIndex);
- ConstantPool cp = holder.getConstants();
- TypeArray fields = holder.getFields();
- short access = fields.getShortAt(fieldArrayIndex + InstanceKlass.ACCESS_FLAGS_OFFSET);
- short nameIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.NAME_INDEX_OFFSET);
- short signatureIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.SIGNATURE_INDEX_OFFSET);
- offset = VM.getVM().buildIntFromShorts(fields.getShortAt(fieldArrayIndex + InstanceKlass.LOW_OFFSET),
- fields.getShortAt(fieldArrayIndex + InstanceKlass.HIGH_OFFSET));
- short genericSignatureIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.GENERIC_SIGNATURE_INDEX_OFFSET);
- Symbol name = cp.getSymbolAt(nameIndex);
+ Symbol name = holder.getFieldName(fieldIndex);
id = new NamedFieldIdentifier(name.asString());
- signature = cp.getSymbolAt(signatureIndex);
- if (genericSignatureIndex != 0) {
- genericSignature = cp.getSymbolAt(genericSignatureIndex);
- } else {
- genericSignature = null;
- }
+ signature = holder.getFieldSignature(fieldIndex);
fieldType = new FieldType(signature);
+
+ short access = holder.getFieldAccessFlags(fieldIndex);
accessFlags = new AccessFlags(access);
}
@@ -73,7 +65,7 @@
private Symbol signature;
private Symbol genericSignature;
private AccessFlags accessFlags;
- private int fieldArrayIndex;
+ private int fieldIndex;
/** Returns the byte offset of the field within the object or klass */
public long getOffset() { return offset; }
@@ -101,8 +93,8 @@
/** (Named, non-VM fields only) Returns the index in the fields
TypeArray for this field. Equivalent to the "index" in the VM's
fieldDescriptors. */
- public int getFieldArrayIndex() {
- return fieldArrayIndex;
+ public int getFieldIndex() {
+ return fieldIndex;
}
/** (Named, non-VM fields only) Retrieves the access flags. */
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/FieldType.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/FieldType.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, 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
@@ -67,6 +67,8 @@
public boolean isObject() { return first == 'L'; }
public boolean isArray() { return first == '['; }
+ public Symbol getSignature() { return signature; }
+
public static class ArrayInfo {
private int dimension;
private int elementBasicType; // See BasicType.java
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Thu Sep 15 12:44:09 2011 -0700
@@ -51,7 +51,7 @@
public static int LOW_OFFSET;
public static int HIGH_OFFSET;
public static int GENERIC_SIGNATURE_INDEX_OFFSET;
- public static int NEXT_OFFSET;
+ public static int FIELD_SLOTS;
public static int IMPLEMENTORS_LIMIT;
// ClassState constants
@@ -78,6 +78,7 @@
implementors[i] = new OopField(type.getOopField("_implementors[0]"), arrayOffset);
}
fields = new OopField(type.getOopField("_fields"), Oop.getHeaderSize());
+ javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), Oop.getHeaderSize());
constants = new OopField(type.getOopField("_constants"), Oop.getHeaderSize());
classLoader = new OopField(type.getOopField("_class_loader"), Oop.getHeaderSize());
protectionDomain = new OopField(type.getOopField("_protection_domain"), Oop.getHeaderSize());
@@ -100,14 +101,14 @@
headerSize = alignObjectOffset(Oop.getHeaderSize() + type.getSize());
// read field offset constants
- ACCESS_FLAGS_OFFSET = db.lookupIntConstant("instanceKlass::access_flags_offset").intValue();
- NAME_INDEX_OFFSET = db.lookupIntConstant("instanceKlass::name_index_offset").intValue();
- SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("instanceKlass::signature_index_offset").intValue();
- INITVAL_INDEX_OFFSET = db.lookupIntConstant("instanceKlass::initval_index_offset").intValue();
- LOW_OFFSET = db.lookupIntConstant("instanceKlass::low_offset").intValue();
- HIGH_OFFSET = db.lookupIntConstant("instanceKlass::high_offset").intValue();
- GENERIC_SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("instanceKlass::generic_signature_offset").intValue();
- NEXT_OFFSET = db.lookupIntConstant("instanceKlass::next_offset").intValue();
+ ACCESS_FLAGS_OFFSET = db.lookupIntConstant("FieldInfo::access_flags_offset").intValue();
+ NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue();
+ SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
+ INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
+ LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
+ HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
+ GENERIC_SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::generic_signature_offset").intValue();
+ FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
// read ClassState constants
CLASS_STATE_UNPARSABLE_BY_GC = db.lookupIntConstant("instanceKlass::unparsable_by_gc").intValue();
CLASS_STATE_ALLOCATED = db.lookupIntConstant("instanceKlass::allocated").intValue();
@@ -131,6 +132,7 @@
private static CIntField nofImplementors;
private static OopField[] implementors;
private static OopField fields;
+ private static CIntField javaFieldsCount;
private static OopField constants;
private static OopField classLoader;
private static OopField protectionDomain;
@@ -172,7 +174,7 @@
private String value;
}
- private int getInitStateAsInt() { return (int) initState.getValue(this); }
+ public int getInitStateAsInt() { return (int) initState.getValue(this); }
public ClassState getInitState() {
int state = getInitStateAsInt();
if (state == CLASS_STATE_UNPARSABLE_BY_GC) {
@@ -247,6 +249,34 @@
public static long getHeaderSize() { return headerSize; }
+ public short getFieldAccessFlags(int index) {
+ return getFields().getShortAt(index * FIELD_SLOTS + ACCESS_FLAGS_OFFSET);
+ }
+
+ public Symbol getFieldName(int index) {
+ int nameIndex = getFields().getShortAt(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
+ return getConstants().getSymbolAt(nameIndex);
+ }
+
+ public Symbol getFieldSignature(int index) {
+ int signatureIndex = getFields().getShortAt(index * FIELD_SLOTS + SIGNATURE_INDEX_OFFSET);
+ return getConstants().getSymbolAt(signatureIndex);
+ }
+
+ public Symbol getFieldGenericSignature(int index) {
+ short genericSignatureIndex = getFields().getShortAt(index * FIELD_SLOTS + GENERIC_SIGNATURE_INDEX_OFFSET);
+ if (genericSignatureIndex != 0) {
+ return getConstants().getSymbolAt(genericSignatureIndex);
+ }
+ return null;
+ }
+
+ public int getFieldOffset(int index) {
+ TypeArray fields = getFields();
+ return VM.getVM().buildIntFromShorts(fields.getShortAt(index * FIELD_SLOTS + LOW_OFFSET),
+ fields.getShortAt(index * FIELD_SLOTS + HIGH_OFFSET));
+ }
+
// Accessors for declared fields
public Klass getArrayKlasses() { return (Klass) arrayKlasses.getValue(this); }
public ObjArray getMethods() { return (ObjArray) methods.getValue(this); }
@@ -257,6 +287,8 @@
public Klass getImplementor() { return (Klass) implementors[0].getValue(this); }
public Klass getImplementor(int i) { return (Klass) implementors[i].getValue(this); }
public TypeArray getFields() { return (TypeArray) fields.getValue(this); }
+ public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
+ public int getAllFieldsCount() { return (int)getFields().getLength(); }
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
public Oop getClassLoader() { return classLoader.getValue(this); }
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
@@ -480,11 +512,10 @@
void iterateStaticFieldsInternal(OopVisitor visitor) {
TypeArray fields = getFields();
- int length = (int) fields.getLength();
- for (int index = 0; index < length; index += NEXT_OFFSET) {
- short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET);
- short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
- FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex));
+ int length = getJavaFieldsCount();
+ for (int index = 0; index < length; index++) {
+ short accessFlags = getFieldAccessFlags(index);
+ FieldType type = new FieldType(getFieldSignature(index));
AccessFlags access = new AccessFlags(accessFlags);
if (access.isStatic()) {
visitField(visitor, type, index);
@@ -496,18 +527,26 @@
return getSuper();
}
+ public static class StaticField {
+ public AccessFlags flags;
+ public Field field;
+
+ StaticField(Field field, AccessFlags flags) {
+ this.field = field;
+ this.flags = flags;
+ }
+ }
+
public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
if (getSuper() != null) {
((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
}
TypeArray fields = getFields();
- int length = (int) fields.getLength();
- for (int index = 0; index < length; index += NEXT_OFFSET) {
- short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET);
- short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
-
- FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex));
+ int length = getJavaFieldsCount();
+ for (int index = 0; index < length; index++) {
+ short accessFlags = getFieldAccessFlags(index);
+ FieldType type = new FieldType(getFieldSignature(index));
AccessFlags access = new AccessFlags(accessFlags);
if (!access.isStatic()) {
visitField(visitor, type, index);
@@ -518,13 +557,11 @@
/** Field access by name. */
public Field findLocalField(Symbol name, Symbol sig) {
TypeArray fields = getFields();
- int n = (int) fields.getLength();
+ int length = (int) fields.getLength();
ConstantPool cp = getConstants();
- for (int i = 0; i < n; i += NEXT_OFFSET) {
- int nameIndex = fields.getShortAt(i + NAME_INDEX_OFFSET);
- int sigIndex = fields.getShortAt(i + SIGNATURE_INDEX_OFFSET);
- Symbol f_name = cp.getSymbolAt(nameIndex);
- Symbol f_sig = cp.getSymbolAt(sigIndex);
+ for (int i = 0; i < length; i++) {
+ Symbol f_name = getFieldName(i);
+ Symbol f_sig = getFieldSignature(i);
if (name.equals(f_name) && sig.equals(f_sig)) {
return newField(i);
}
@@ -599,8 +636,8 @@
/** Get field by its index in the fields array. Only designed for
use in a debugging system. */
- public Field getFieldByIndex(int fieldArrayIndex) {
- return newField(fieldArrayIndex);
+ public Field getFieldByIndex(int fieldIndex) {
+ return newField(fieldIndex);
}
@@ -613,9 +650,9 @@
// not including inherited fields.
TypeArray fields = getFields();
- int length = (int) fields.getLength();
- List immediateFields = new ArrayList(length / NEXT_OFFSET);
- for (int index = 0; index < length; index += NEXT_OFFSET) {
+ int length = getJavaFieldsCount();
+ List immediateFields = new ArrayList(length);
+ for (int index = 0; index < length; index++) {
immediateFields.add(getFieldByIndex(index));
}
@@ -803,8 +840,7 @@
// Creates new field from index in fields TypeArray
private Field newField(int index) {
TypeArray fields = getFields();
- short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
- FieldType type = new FieldType(getConstants().getSymbolAt(signatureIndex));
+ FieldType type = new FieldType(getFieldSignature(index));
if (type.isOop()) {
if (VM.getVM().isCompressedOopsEnabled()) {
return new NarrowOopField(this, index);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/JumpData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// JumpData
+//
+// A JumpData is used to access profiling information for a direct
+// branch. It is a counter, used for counting the number of branches,
+// plus a data displacement, used for realigning the data pointer to
+// the corresponding target bci.
+public class JumpData extends ProfileData {
+ static final int takenOffSet = 0;
+ static final int displacementOffSet = 1;
+ static final int jumpCellCount = 2;
+
+ public JumpData(DataLayout layout) {
+ super(layout);
+ //assert(layout.tag() == DataLayout.jumpDataTag ||
+ // layout.tag() == DataLayout.branchDataTag, "wrong type");
+ }
+
+ static int staticCellCount() {
+ return jumpCellCount;
+ }
+
+ public int cellCount() {
+ return staticCellCount();
+ }
+
+ // Direct accessor
+ int taken() {
+ return uintAt(takenOffSet);
+ }
+
+ int displacement() {
+ return intAt(displacementOffSet);
+ }
+
+ // Code generation support
+ static int takenOffset() {
+ return cellOffset(takenOffSet);
+ }
+
+ static int displacementOffset() {
+ return cellOffset(displacementOffSet);
+ }
+
+ public void printDataOn(PrintStream st) {
+ printShared(st, "JumpData");
+ st.println("taken(" + taken() + ") displacement(" + displacement() + ")");
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Thu Sep 15 12:44:09 2011 -0700
@@ -49,6 +49,7 @@
Type type = db.lookupType("methodOopDesc");
constMethod = new OopField(type.getOopField("_constMethod"), 0);
constants = new OopField(type.getOopField("_constants"), 0);
+ methodData = new OopField(type.getOopField("_method_data"), 0);
methodSize = new CIntField(type.getCIntegerField("_method_size"), 0);
maxStack = new CIntField(type.getCIntegerField("_max_stack"), 0);
maxLocals = new CIntField(type.getCIntegerField("_max_locals"), 0);
@@ -58,9 +59,13 @@
vtableIndex = new CIntField(type.getCIntegerField("_vtable_index"), 0);
if (!VM.getVM().isCore()) {
invocationCounter = new CIntField(type.getCIntegerField("_invocation_counter"), 0);
+ backedgeCounter = new CIntField(type.getCIntegerField("_backedge_counter"), 0);
}
bytecodeOffset = type.getSize();
+ interpreterThrowoutCountField = new CIntField(type.getCIntegerField("_interpreter_throwout_count"), 0);
+ interpreterInvocationCountField = new CIntField(type.getCIntegerField("_interpreter_invocation_count"), 0);
+
/*
interpreterEntry = type.getAddressField("_interpreter_entry");
fromCompiledCodeEntryPoint = type.getAddressField("_from_compiled_code_entry_point");
@@ -79,6 +84,7 @@
// Fields
private static OopField constMethod;
private static OopField constants;
+ private static OopField methodData;
private static CIntField methodSize;
private static CIntField maxStack;
private static CIntField maxLocals;
@@ -86,10 +92,14 @@
private static CIntField accessFlags;
private static CIntField vtableIndex;
private static CIntField invocationCounter;
+ private static CIntField backedgeCounter;
private static long bytecodeOffset;
private static AddressField code;
+ private static CIntField interpreterThrowoutCountField;
+ private static CIntField interpreterInvocationCountField;
+
// constant method names - <init>, <clinit>
// Initialized lazily to avoid initialization ordering dependencies between Method and SymbolTable
private static Symbol objectInitializerName;
@@ -116,6 +126,7 @@
// Accessors for declared fields
public ConstMethod getConstMethod() { return (ConstMethod) constMethod.getValue(this); }
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
+ public MethodData getMethodData() { return (MethodData) methodData.getValue(this); }
public TypeArray getExceptionTable() { return getConstMethod().getExceptionTable(); }
/** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
public long getMethodSize() { return methodSize.getValue(this); }
@@ -134,6 +145,12 @@
}
return invocationCounter.getValue(this);
}
+ public long getBackedgeCounter() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(!VM.getVM().isCore(), "must not be used in core build");
+ }
+ return backedgeCounter.getValue(this);
+ }
// get associated compiled native method, if available, else return null.
public NMethod getNativeMethod() {
@@ -333,4 +350,11 @@
buf.append(")");
return buf.toString().replace('/', '.');
}
+ public int interpreterThrowoutCount() {
+ return (int) interpreterThrowoutCountField.getValue(getHandle());
+ }
+
+ public int interpreterInvocationCount() {
+ return (int) interpreterInvocationCountField.getValue(getHandle());
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,92 @@
// A MethodData provides interpreter profiling information
public class MethodData extends Oop {
+ static int TypeProfileWidth = 2;
+ static int BciProfileWidth = 2;
+ static int CompileThreshold;
+
+ static int Reason_many; // indicates presence of several reasons
+ static int Reason_none; // indicates absence of a relevant deopt.
+ static int Reason_LIMIT;
+ static int Reason_RECORDED_LIMIT; // some are not recorded per bc
+
+ private static String[] trapReasonName;
+
+ static String trapReasonName(int reason) {
+ if (reason == Reason_many) return "many";
+ if (reason < Reason_LIMIT)
+ return trapReasonName[reason];
+ return "reason" + reason;
+ }
+
+
+ static int trapStateReason(int trapState) {
+ // This assert provides the link between the width of DataLayout.trapBits
+ // and the encoding of "recorded" reasons. It ensures there are enough
+ // bits to store all needed reasons in the per-BCI MDO profile.
+ // assert(dsReasonMask >= reasonRecordedLimit, "enough bits");
+ int recompileBit = (trapState & dsRecompileBit);
+ trapState -= recompileBit;
+ if (trapState == dsReasonMask) {
+ return Reason_many;
+ } else {
+ // assert((int)reasonNone == 0, "state=0 => Reason_none");
+ return trapState;
+ }
+ }
+
+
+ static final int dsReasonMask = DataLayout.trapMask >> 1;
+ static final int dsRecompileBit = DataLayout.trapMask - dsReasonMask;
+
+ static boolean trapStateIsRecompiled(int trapState) {
+ return (trapState & dsRecompileBit) != 0;
+ }
+
+ static boolean reasonIsRecordedPerBytecode(int reason) {
+ return reason > Reason_none && reason < Reason_RECORDED_LIMIT;
+ }
+ static int trapStateAddReason(int trapState, int reason) {
+ // assert(reasonIsRecordedPerBytecode((DeoptReason)reason) || reason == reasonMany, "valid reason");
+ int recompileBit = (trapState & dsRecompileBit);
+ trapState -= recompileBit;
+ if (trapState == dsReasonMask) {
+ return trapState + recompileBit; // already at state lattice bottom
+ } else if (trapState == reason) {
+ return trapState + recompileBit; // the condition is already true
+ } else if (trapState == 0) {
+ return reason + recompileBit; // no condition has yet been true
+ } else {
+ return dsReasonMask + recompileBit; // fall to state lattice bottom
+ }
+ }
+ static int trapStateSetRecompiled(int trapState, boolean z) {
+ if (z) return trapState | dsRecompileBit;
+ else return trapState & ~dsRecompileBit;
+ }
+
+ static String formatTrapState(int trapState) {
+ int reason = trapStateReason(trapState);
+ boolean recompFlag = trapStateIsRecompiled(trapState);
+ // Re-encode the state from its decoded components.
+ int decodedState = 0;
+ if (reasonIsRecordedPerBytecode(reason) || reason == Reason_many)
+ decodedState = trapStateAddReason(decodedState, reason);
+ if (recompFlag)
+ decodedState = trapStateSetRecompiled(decodedState, recompFlag);
+ // If the state re-encodes properly, format it symbolically.
+ // Because this routine is used for debugging and diagnostics,
+ // be robust even if the state is a strange value.
+ if (decodedState != trapState) {
+ // Random buggy state that doesn't decode??
+ return "#" + trapState;
+ } else {
+ return trapReasonName(reason) + (recompFlag ? " recompiled" : "");
+ }
+ }
+
+
+
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -48,7 +134,58 @@
size = new CIntField(type.getCIntegerField("_size"), 0);
method = new OopField(type.getOopField("_method"), 0);
- // FIXME: add more fields and accessors
+
+ VM.Flag[] flags = VM.getVM().getCommandLineFlags();
+ for (int f = 0; f < flags.length; f++) {
+ VM.Flag flag = flags[f];
+ if (flag.getName().equals("TypeProfileWidth")) {
+ TypeProfileWidth = (int)flag.getIntx();
+ } else if (flag.getName().equals("BciProfileWidth")) {
+ BciProfileWidth = (int)flag.getIntx();
+ } else if (flag.getName().equals("CompileThreshold")) {
+ CompileThreshold = (int)flag.getIntx();
+ }
+ }
+
+ cellSize = (int)VM.getVM().getAddressSize();
+
+ dataSize = new CIntField(type.getCIntegerField("_data_size"), 0);
+ data = type.getAddressField("_data[0]");
+
+ sizeofMethodDataOopDesc = (int)type.getSize();;
+
+ Reason_many = db.lookupIntConstant("Deoptimization::Reason_many").intValue();
+ Reason_none = db.lookupIntConstant("Deoptimization::Reason_none").intValue();
+ Reason_LIMIT = db.lookupIntConstant("Deoptimization::Reason_LIMIT").intValue();
+ Reason_RECORDED_LIMIT = db.lookupIntConstant("Deoptimization::Reason_RECORDED_LIMIT").intValue();
+
+ trapReasonName = new String[Reason_LIMIT];
+
+ // Find Deopt reasons
+ Iterator i = db.getIntConstants();
+ String prefix = "Deoptimization::Reason_";
+ while (i.hasNext()) {
+ String name = (String)i.next();
+ if (name.startsWith(prefix)) {
+ // Strip prefix
+ if (!name.endsWith("Reason_many") &&
+ !name.endsWith("Reason_LIMIT") &&
+ !name.endsWith("Reason_RECORDED_LIMIT")) {
+ String trimmed = name.substring(prefix.length());
+ int value = db.lookupIntConstant(name).intValue();
+ if (trapReasonName[value] != null) {
+ throw new InternalError("duplicate reasons: " + trapReasonName[value] + " " + trimmed);
+ }
+ trapReasonName[value] = trimmed;
+ }
+ }
+ }
+ for (int index = 0; index < trapReasonName.length; index++) {
+ if (trapReasonName[index] == null) {
+ throw new InternalError("missing reason for " + index);
+ }
+ System.out.println(trapReasonName[index]);
+ }
}
MethodData(OopHandle handle, ObjectHeap heap) {
@@ -60,6 +197,11 @@
private static long baseOffset;
private static CIntField size;
private static OopField method;
+ private static CIntField dataSize;
+ private static AddressField data;
+
+ public static int sizeofMethodDataOopDesc;
+ public static int cellSize;
public long getObjectSize() {
return alignObjectSize(size.getValue(this));
@@ -81,4 +223,119 @@
visitor.doCInt(size, true);
}
}
+
+ int dataSize() {
+ if (dataSize == null) {
+ return 0;
+ } else {
+ return (int)dataSize.getValue(this);
+ }
+ }
+
+ boolean outOfBounds(int dataIndex) {
+ return dataIndex >= dataSize();
+ }
+
+ ProfileData dataAt(int dataIndex) {
+ if (outOfBounds(dataIndex)) {
+ return null;
+ }
+ DataLayout dataLayout = new DataLayout(this, dataIndex + (int)data.getOffset());
+
+ switch (dataLayout.tag()) {
+ case DataLayout.noTag:
+ default:
+ throw new InternalError(dataIndex + " " + dataSize() + " " + dataLayout.tag());
+ case DataLayout.bitDataTag:
+ return new BitData(dataLayout);
+ case DataLayout.counterDataTag:
+ return new CounterData(dataLayout);
+ case DataLayout.jumpDataTag:
+ return new JumpData(dataLayout);
+ case DataLayout.receiverTypeDataTag:
+ return new ReceiverTypeData(dataLayout);
+ case DataLayout.virtualCallDataTag:
+ return new VirtualCallData(dataLayout);
+ case DataLayout.retDataTag:
+ return new RetData(dataLayout);
+ case DataLayout.branchDataTag:
+ return new BranchData(dataLayout);
+ case DataLayout.multiBranchDataTag:
+ return new MultiBranchData(dataLayout);
+ }
+ }
+
+ int dpToDi(int dp) {
+ // this in an offset from the base of the MDO, so convert to offset into _data
+ return dp - (int)data.getOffset();
+ }
+
+ int firstDi() { return 0; }
+ public ProfileData firstData() { return dataAt(firstDi()); }
+ public ProfileData nextData(ProfileData current) {
+ int currentIndex = dpToDi(current.dp());
+ int nextIndex = currentIndex + current.sizeInBytes();
+ return dataAt(nextIndex);
+ }
+ boolean isValid(ProfileData current) { return current != null; }
+
+ public void printDataOn(PrintStream st) {
+ ProfileData data = firstData();
+ for ( ; isValid(data); data = nextData(data)) {
+ st.print(dpToDi(data.dp()));
+ st.print(" ");
+ // st->fillTo(6);
+ data.printDataOn(st);
+ }
+ }
+
+ private byte[] fetchDataAt(Address base, long offset, long size) {
+ byte[] result = new byte[(int)size];
+ for (int i = 0; i < size; i++) {
+ result[i] = base.getJByteAt(offset + i);
+ }
+ return result;
+ }
+
+ public byte[] orig() {
+ // fetch the orig methodDataOopDesc data between header and dataSize
+ return fetchDataAt(this.getHandle(), 0, sizeofMethodDataOopDesc);
+ }
+
+ public long[] data() {
+ // Read the data as an array of intptr_t elements
+ OopHandle base = getHandle();
+ long offset = data.getOffset();
+ int elements = dataSize() / cellSize;
+ long[] result = new long[elements];
+ for (int i = 0; i < elements; i++) {
+ Address value = base.getAddressAt(offset + i * MethodData.cellSize);
+ if (value != null) {
+ result[i] = value.minus(null);
+ }
+ }
+ return result;
+ }
+
+ // Get a measure of how much mileage the method has on it.
+ int mileageOf(Method method) {
+ long mileage = 0;
+ int iic = method.interpreterInvocationCount();
+ if (mileage < iic) mileage = iic;
+
+ long ic = method.getInvocationCounter();
+ long bc = method.getBackedgeCounter();
+
+ long icval = ic >> 3;
+ if ((ic & 4) != 0) icval += CompileThreshold;
+ if (mileage < icval) mileage = icval;
+ long bcval = bc >> 3;
+ if ((bc & 4) != 0) bcval += CompileThreshold;
+ if (mileage < bcval) mileage = bcval;
+ return (int)mileage;
+ }
+
+ public int currentMileage() {
+ return 20000;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MultiBranchData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// MultiBranchData
+//
+// A MultiBranchData is used to access profiling information for
+// a multi-way branch (*switch bytecodes). It consists of a series
+// of (count, displacement) pairs, which count the number of times each
+// case was taken and specify the data displacment for each branch target.
+public class MultiBranchData extends ArrayData {
+ static final int defaultCountOffSet = 0;
+ static final int defaultDisaplacementOffSet = 1;
+ static final int caseArrayStart = 2;
+ static final int relativeCountOffSet = 0;
+ static final int relativeDisplacementOffSet = 1;
+ static final int perCaseCellCount = 2;
+
+ public MultiBranchData(DataLayout layout) {
+ super(layout);
+ //assert(layout.tag() == DataLayout.multiBranchDataTag, "wrong type");
+ }
+
+ // static int computeCellCount(BytecodeStream stream);
+
+ int numberOfCases() {
+ int alen = arrayLen() - 2; // get rid of default case here.
+ //assert(alen % perCaseCellCount == 0, "must be even");
+ return (alen / perCaseCellCount);
+ }
+
+ int defaultCount() {
+ return arrayUintAt(defaultCountOffSet);
+ }
+ int defaultDisplacement() {
+ return arrayIntAt(defaultDisaplacementOffSet);
+ }
+
+ int countAt(int index) {
+ return arrayUintAt(caseArrayStart +
+ index * perCaseCellCount +
+ relativeCountOffSet);
+ }
+ int displacementAt(int index) {
+ return arrayIntAt(caseArrayStart +
+ index * perCaseCellCount +
+ relativeDisplacementOffSet);
+ }
+
+ // Code generation support
+ static int defaultCountOffset() {
+ return arrayElementOffset(defaultCountOffSet);
+ }
+ static int defaultDisplacementOffset() {
+ return arrayElementOffset(defaultDisaplacementOffSet);
+ }
+ static int caseCountOffset(int index) {
+ return caseArrayOffset() +
+ (perCaseSize() * index) +
+ relativeCountOffset();
+ }
+ static int caseArrayOffset() {
+ return arrayElementOffset(caseArrayStart);
+ }
+ static int perCaseSize() {
+ return (perCaseCellCount) * MethodData.cellSize;
+ }
+ static int relativeCountOffset() {
+ return (relativeCountOffSet) * MethodData.cellSize;
+ }
+ static int relativeDisplacementOffset() {
+ return (relativeDisplacementOffSet) * MethodData.cellSize;
+ }
+
+ public void printDataOn(PrintStream st) {
+ printShared(st, "MultiBranchData");
+ st.println("default_count(" + defaultCount() + ") displacement(" + defaultDisplacement() + ")");
+ int cases = numberOfCases();
+ for (int i = 0; i < cases; i++) {
+ tab(st);
+ st.println("count(" + countAt(i) + ") displacement(" + displacementAt(i) + ")");
+ }
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Thu Sep 15 12:44:09 2011 -0700
@@ -112,6 +112,32 @@
return buf.toString();
}
+ public static String escapeString(String s) {
+ StringBuilder sb = null;
+ for (int index = 0; index < s.length(); index++) {
+ char value = s.charAt(index);
+ if (value >= 32 && value < 127 || value == '\'' || value == '\\') {
+ if (sb != null) {
+ sb.append(value);
+ }
+ } else {
+ if (sb == null) {
+ sb = new StringBuilder(s.length() * 2);
+ sb.append(s, 0, index);
+ }
+ sb.append("\\u");
+ if (value < 0x10) sb.append("000");
+ else if (value < 0x100) sb.append("00");
+ else if (value < 0x1000) sb.append("0");
+ sb.append(Integer.toHexString(value));
+ }
+ }
+ if (sb != null) {
+ return sb.toString();
+ }
+ return s;
+ }
+
public static String stringOopToString(Oop stringOop) {
if (offsetField == null) {
InstanceKlass k = (InstanceKlass) stringOop.getKlass();
@@ -129,6 +155,10 @@
countField.getValue(stringOop));
}
+ public static String stringOopToEscapedString(Oop stringOop) {
+ return escapeString(stringOopToString(stringOop));
+ }
+
private static void initThreadGroupFields() {
if (threadGroupParentField == null) {
SystemDictionary sysDict = VM.getVM().getSystemDictionary();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ProfileData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public abstract class ProfileData {
+ // This is a pointer to a section of profiling data.
+ private DataLayout _data;
+
+ public DataLayout data() { return _data; }
+
+ // How many cells are in this?
+ public abstract int cellCount();
+
+
+ // Return the size of this data.
+ public int sizeInBytes() {
+ return DataLayout.computeSizeInBytes(cellCount());
+ }
+
+ public int dp() {
+ return data().dp();
+ }
+
+ // Low-level accessors for underlying data
+ int intptrAt(int index) {
+ //assert(0 <= index && index < cellCount(), "oob");
+ return data().cellAt(index);
+ }
+ int intAt(int index) {
+ return (int)intptrAt(index);
+ }
+ int uintAt(int index) {
+ return (int)intptrAt(index);
+ }
+ Oop oopAt(int index) {
+ return data().oopAt(index);
+ }
+
+ public Address addressAt(int index) {
+ return data().addressAt(index);
+ }
+
+ boolean flagAt(int flagNumber) {
+ return data().flagAt(flagNumber);
+ }
+
+ // two convenient imports for use by subclasses:
+ public static int cellOffset(int index) {
+ return DataLayout.cellOffset(index);
+ }
+
+ public ProfileData(DataLayout data) {
+ _data = data;
+ }
+
+ // Constructor for invalid ProfileData.
+ ProfileData() {
+ _data = null;
+ }
+
+ int bci() {
+ return data().bci();
+ }
+
+ int trapState() {
+ return data().trapState();
+ }
+ public abstract void printDataOn(PrintStream st);
+
+ void tab(PrintStream st) {
+ st.print("\t");
+ }
+
+ void printShared(PrintStream st, String name) {
+ st.print("bci: " + bci());
+ // st.fillTo(tabWidthOne);
+ st.print(" " + name + " ");
+ tab(st);
+ int trap = trapState();
+ if (trap != 0) {
+ st.print("trap(" + MethodData.formatTrapState(trap) + ") ");
+ }
+ int flags = data().flags();
+ if (flags != 0)
+ st.print("flags(" + flags + ") ");
+ }
+
+ public String toString() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ try {
+ printDataOn(ps);
+ } finally {
+ ps.close();
+ }
+ return baos.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// ReceiverTypeData
+//
+// A ReceiverTypeData is used to access profiling information about a
+// dynamic type check. It consists of a counter which counts the total times
+// that the check is reached, and a series of (Klass, count) pairs
+// which are used to store a type profile for the receiver of the check.
+public class ReceiverTypeData extends CounterData {
+ static final int receiver0Offset = counterCellCount;
+ static final int count0Offset = receiver0Offset + 1;
+ static final int receiverTypeRowCellCount = (count0Offset + 1) - receiver0Offset;
+
+ public ReceiverTypeData(DataLayout layout) {
+ super(layout);
+ //assert(layout.tag() == DataLayout.receiverTypeDataTag ||
+ // layout.tag() == DataLayout.virtualCallDataTag, "wrong type");
+ }
+
+ boolean isReceivertypedata() { return true; }
+
+ static int staticCellCount() {
+ return counterCellCount + MethodData.TypeProfileWidth * receiverTypeRowCellCount;
+ }
+
+ public int cellCount() {
+ return staticCellCount();
+ }
+
+ // Direct accessors
+ public static int rowLimit() {
+ return MethodData.TypeProfileWidth;
+ }
+ public static int receiverCellIndex(int row) {
+ return receiver0Offset + row * receiverTypeRowCellCount;
+ }
+ public static int receiverCountCellIndex(int row) {
+ return count0Offset + row * receiverTypeRowCellCount;
+ }
+
+ // Get the receiver at row. The 'unchecked' version is needed by parallel old
+ // gc; it does not assert the receiver is a klass. During compaction of the
+ // perm gen, the klass may already have moved, so the isKlass() predicate
+ // would fail. The 'normal' version should be used whenever possible.
+ Klass receiverUnchecked(int row) {
+ //assert(row < rowLimit(), "oob");
+ Oop recv = oopAt(receiverCellIndex(row));
+ return (Klass)recv;
+ }
+
+ public Klass receiver(int row) {
+ Klass recv = receiverUnchecked(row);
+ //assert(recv == NULL || ((oop)recv).isKlass(), "wrong type");
+ return recv;
+ }
+
+ public int receiverCount(int row) {
+ //assert(row < rowLimit(), "oob");
+ return uintAt(receiverCountCellIndex(row));
+ }
+
+ // Code generation support
+ static int receiverOffset(int row) {
+ return cellOffset(receiverCellIndex(row));
+ }
+ static int receiverCountOffset(int row) {
+ return cellOffset(receiverCountCellIndex(row));
+ }
+ static int receiverTypeDataSize() {
+ return cellOffset(staticCellCount());
+ }
+
+ void printReceiverDataOn(PrintStream st) {
+ int row;
+ int entries = 0;
+ for (row = 0; row < rowLimit(); row++) {
+ if (receiver(row) != null) entries++;
+ }
+ st.println("count(" + count() + ") entries(" + entries + ")");
+ for (row = 0; row < rowLimit(); row++) {
+ if (receiver(row) != null) {
+ tab(st);
+ receiver(row).printValueOn(st);
+ st.println("(" + receiverCount(row) + ")");
+ }
+ }
+ }
+ public void printDataOn(PrintStream st) {
+ printShared(st, "ReceiverTypeData");
+ printReceiverDataOn(st);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/RetData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// RetData
+//
+// A RetData is used to access profiling information for a ret bytecode.
+// It is composed of a count of the number of times that the ret has
+// been executed, followed by a series of triples of the form
+// (bci, count, di) which count the number of times that some bci was the
+// target of the ret and cache a corresponding data displacement.
+public class RetData extends CounterData {
+
+ static final int bci0Offset = counterCellCount;
+ static final int count0Offset = bci0Offset + 1;
+ static final int displacement0Offset = count0Offset + 1;
+ static final int retRowCellCount = (displacement0Offset + 1) - bci0Offset;
+
+ public RetData(DataLayout layout) {
+ super(layout);
+ //assert(layout.tag() == DataLayout.retDataTag, "wrong type");
+ }
+
+ static final int noBci = -1; // value of bci when bci1/2 are not in use.
+
+ static int staticCellCount() {
+ return counterCellCount + MethodData.BciProfileWidth * retRowCellCount;
+ }
+
+ public int cellCount() {
+ return staticCellCount();
+ }
+
+ static int rowLimit() {
+ return MethodData.BciProfileWidth;
+ }
+ static int bciCellIndex(int row) {
+ return bci0Offset + row * retRowCellCount;
+ }
+ static int bciCountCellIndex(int row) {
+ return count0Offset + row * retRowCellCount;
+ }
+ static int bciDisplacementCellIndex(int row) {
+ return displacement0Offset + row * retRowCellCount;
+ }
+
+ // Direct accessors
+ int bci(int row) {
+ return intAt(bciCellIndex(row));
+ }
+ int bciCount(int row) {
+ return uintAt(bciCountCellIndex(row));
+ }
+ int bciDisplacement(int row) {
+ return intAt(bciDisplacementCellIndex(row));
+ }
+
+ // Code generation support
+ static int bciOffset(int row) {
+ return cellOffset(bciCellIndex(row));
+ }
+ static int bciCountOffset(int row) {
+ return cellOffset(bciCountCellIndex(row));
+ }
+ static int bciDisplacementOffset(int row) {
+ return cellOffset(bciDisplacementCellIndex(row));
+ }
+
+ public void printDataOn(PrintStream st) {
+ printShared(st, "RetData");
+ int row;
+ int entries = 0;
+ for (row = 0; row < rowLimit(); row++) {
+ if (bci(row) != noBci) entries++;
+ }
+ st.println("count(" + count() + ") entries(" + entries + ")");
+ for (row = 0; row < rowLimit(); row++) {
+ if (bci(row) != noBci) {
+ tab(st);
+ st.println(" bci(" + bci(row) + ": count(" + bciCount(row) + ") displacement(" + bciDisplacement(row) + "))");
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// VirtualCallData
+//
+// A VirtualCallData is used to access profiling information about a
+// call. For now, it has nothing more than a ReceiverTypeData.
+public class VirtualCallData extends ReceiverTypeData {
+ public VirtualCallData(DataLayout layout) {
+ super(layout);
+ //assert(layout.tag() == DataLayout.virtualCallDataTag, "wrong type");
+ }
+
+ static int staticCellCount() {
+ // At this point we could add more profile state, e.g., for arguments.
+ // But for now it's the same size as the base record type.
+ return ReceiverTypeData.staticCellCount();
+ }
+
+ public int cellCount() {
+ return staticCellCount();
+ }
+
+ // Direct accessors
+ static int virtualCallDataSize() {
+ return cellOffset(staticCellCount());
+ }
+
+ public void printDataOn(PrintStream st) {
+ printShared(st, "VirtualCallData");
+ printReceiverDataOn(st);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/java_lang_Class.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/java_lang_Class.java Thu Sep 15 12:44:09 2011 -0700
@@ -55,13 +55,13 @@
// klass and oop_size are HotSpot magic fields and hence we can't
// find them from InstanceKlass for java.lang.Class.
Type jlc = db.lookupType("java_lang_Class");
- int klassOffset = (int) jlc.getCIntegerField("klass_offset").getValue();
+ int klassOffset = (int) jlc.getCIntegerField("_klass_offset").getValue();
if (VM.getVM().isCompressedOopsEnabled()) {
klassField = new NarrowOopField(new NamedFieldIdentifier("klass"), klassOffset, true);
} else {
klassField = new OopField(new NamedFieldIdentifier("klass"), klassOffset, true);
}
- int oopSizeOffset = (int) jlc.getCIntegerField("oop_size_offset").getValue();
+ int oopSizeOffset = (int) jlc.getCIntegerField("_oop_size_offset").getValue();
oopSizeField = new IntField(new NamedFieldIdentifier("oop_size"), oopSizeOffset, true);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Block.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Block extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Block");
+ nodesField = type.getAddressField("_nodes");
+ succsField = type.getAddressField("_succs");
+ numSuccsField = new CIntField(type.getCIntegerField("_num_succs"), 0);
+ preOrderField = new CIntField(type.getCIntegerField("_pre_order"), 0);
+ domDepthField = new CIntField(type.getCIntegerField("_dom_depth"), 0);
+ idomField = type.getAddressField("_idom");
+ freqField = type.getJFloatField("_freq");
+ }
+
+ private static AddressField nodesField;
+ private static AddressField succsField;
+ private static CIntField numSuccsField;
+ private static CIntField preOrderField;
+ private static CIntField domDepthField;
+ private static AddressField idomField;
+ private static JFloatField freqField;
+
+ public Block(Address addr) {
+ super(addr);
+ }
+
+ public int preOrder() {
+ return (int)preOrderField.getValue(getAddress());
+ }
+
+ public float freq() {
+ return (float)freqField.getValue(getAddress());
+ }
+
+ public Node_List nodes() {
+ return new Node_List(getAddress().addOffsetTo(nodesField.getOffset()));
+ }
+
+ public void dump(PrintStream out) {
+ out.print("B" + preOrder());
+ out.print(" Freq: " + freq());
+ out.println();
+ Node_List nl = nodes();
+ int cnt = nl.size();
+ for( int i=0; i<cnt; i++ )
+ nl.at(i).dump(out);
+ out.print("\n");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Block_Array.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Block_Array extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Block_Array");
+ sizeField = new CIntField(type.getCIntegerField("_size"), 0);
+ blocksField = type.getAddressField("_blocks");
+ arenaField = type.getAddressField("_arena");
+ }
+
+ private static CIntField sizeField;
+ private static AddressField blocksField;
+ private static AddressField arenaField;
+
+ public Block_Array(Address addr) {
+ super(addr);
+ }
+
+ public int Max() {
+ return (int) sizeField.getValue(getAddress());
+ }
+
+ public Block at(int i) {
+ return new Block(blocksField.getValue(getAddress()).getAddressAt(i * (int)VM.getVM().getAddressSize()));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Block_List.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Block_List extends Block_Array {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Block_List");
+ cntField = new CIntField(type.getCIntegerField("_cnt"), 0);
+ }
+
+ private static CIntField cntField;
+
+ public Block_List(Address addr) {
+ super(addr);
+ }
+
+ public int size() {
+ return (int) cntField.getValue(getAddress());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/CallDynamicJavaNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class CallDynamicJavaNode extends CallJavaNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("CallDynamicJavaNode");
+ }
+
+
+ public CallDynamicJavaNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/CallJavaNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.*;
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.ci.*;
+import sun.jvm.hotspot.types.*;
+
+public class CallJavaNode extends CallNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("CallJavaNode");
+ methodField = type.getAddressField("_method");
+ }
+
+ private static AddressField methodField;
+
+ public CallJavaNode(Address addr) {
+ super(addr);
+ }
+
+ public ciMethod method() {
+ return (ciMethod) ciObjectFactory.get(methodField.getValue(getAddress()));
+ }
+
+ public void dumpSpec(PrintStream out) {
+ if (method() != null) {
+ out.print(" " + method().method().externalNameAndSignature());
+ }
+ super.dumpSpec(out);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/CallNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class CallNode extends SafePointNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("CallNode");
+ entryPointField = type.getAddressField("_entry_point");
+ }
+
+ private static AddressField entryPointField;
+
+ public Address entryPoint() {
+ return entryPointField.getValue(getAddress());
+ }
+
+ public CallNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream out) {
+ out.print(" ");
+ // tf()->dumpOn(st);
+ // if (_cnt != countUnknown) st->print(" C=%f",_cnt);
+ JVMState jvms = jvms();
+ if (jvms != null) jvms.dumpSpec(out);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/CallRuntimeNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.utilities.CStringUtilities;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class CallRuntimeNode extends CallNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("CallRuntimeNode");
+ nameField = type.getAddressField("_name");
+ }
+
+ static private AddressField nameField;
+
+ public String name() {
+ return CStringUtilities.getString(nameField.getValue(getAddress()));
+ }
+
+ public CallRuntimeNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream out) {
+ out.print(" #");
+ out.print(name());
+ super.dumpSpec(out);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/CallStaticJavaNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.utilities.CStringUtilities;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class CallStaticJavaNode extends CallJavaNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("CallStaticJavaNode");
+ nameField = type.getAddressField("_name");
+ }
+
+ static private AddressField nameField;
+
+ public String name() {
+ return CStringUtilities.getString(nameField.getValue(getAddress()));
+ }
+
+ public CallStaticJavaNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream out) {
+ out.print(" Static ");
+ String name = name();
+ if (name != null) {
+ out.print(name);
+ // int trapReq = uncommonTrapRequest();
+ // if (trapReq != 0) {
+ // char buf[100];
+ // st->print("(%s)",
+ // Deoptimization::formatTrapRequest(buf, sizeof(buf),
+ // trapReq));
+ // }
+ out.print(" ");
+ }
+ super.dumpSpec(out);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Compile.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.ci.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Compile extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Compile");
+ rootField = type.getAddressField("_root");
+ uniqueField = new CIntField(type.getCIntegerField("_unique"), 0);
+ entryBciField = new CIntField(type.getCIntegerField("_entry_bci"), 0);
+ topField = type.getAddressField("_top");
+ cfgField = type.getAddressField("_cfg");
+ regallocField = type.getAddressField("_regalloc");
+ methodField = type.getAddressField("_method");
+ iltField = type.getAddressField("_ilt");
+ }
+
+ private static AddressField rootField;
+ private static CIntField uniqueField;
+ private static CIntField entryBciField;
+ private static AddressField topField;
+ private static AddressField cfgField;
+ private static AddressField regallocField;
+ private static AddressField methodField;
+ private static AddressField iltField;
+
+ public Compile(Address addr) {
+ super(addr);
+ }
+
+ public Node root() {
+ return new RootNode(rootField.getValue(this.getAddress()));
+ }
+
+ public int entryBci() {
+ return (int)entryBciField.getValue(getAddress());
+ }
+
+ public ciMethod method() {
+ return (ciMethod) ciObjectFactory.get(methodField.getValue(getAddress()));
+ }
+
+ public PhaseCFG cfg() {
+ Address a = cfgField.getValue(this.getAddress());
+ if (a != null) {
+ return new PhaseCFG(a);
+ }
+ return null;
+ }
+
+ public InlineTree ilt() {
+ Address a = iltField.getValue(this.getAddress());
+ if (a != null) {
+ return new InlineTree(a);
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/HaltNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class HaltNode extends Node {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("HaltNode");
+ }
+
+
+ public HaltNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/InlineTree.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.ci.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.utilities.GrowableArray;
+import sun.jvm.hotspot.types.*;
+
+public class InlineTree extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("InlineTree");
+ callerJvmsField = type.getAddressField("_caller_jvms");
+ methodField = type.getAddressField("_method");
+ callerTreeField = type.getAddressField("_caller_tree");
+ subtreesField = type.getAddressField("_subtrees");
+ }
+
+ private static AddressField callerJvmsField;
+ private static AddressField methodField;
+ private static AddressField callerTreeField;
+ private static AddressField subtreesField;
+
+ private static StaticBaseConstructor inlineTreeConstructor = new StaticBaseConstructor<InlineTree>(InlineTree.class);
+
+ public InlineTree(Address addr) {
+ super(addr);
+ }
+
+ public InlineTree callerTree() {
+ Address addr = callerTreeField.getValue(getAddress());
+ if (addr == null) return null;
+
+ return new InlineTree(addr);
+ }
+
+ public ciMethod method() {
+ return (ciMethod) ciObjectFactory.get(methodField.getValue(getAddress()));
+ }
+
+ public JVMState callerJvms() {
+ return JVMState.create(callerJvmsField.getValue(getAddress()));
+ }
+
+ public int callerBci() {
+ JVMState jvms = callerJvms();
+ return (jvms != null) ? jvms.bci() : -1;
+ }
+
+ public GrowableArray<InlineTree> subtrees() {
+ Address addr = getAddress().addOffsetTo(subtreesField.getOffset());
+
+ return GrowableArray.create(addr, inlineTreeConstructor);
+ }
+
+ public void printImpl(PrintStream st, int indent) {
+ for (int i = 0; i < indent; i++) st.print(" ");
+ st.printf(" @ %d ", callerBci());
+ method().printShortName(st);
+ st.println();
+
+ GrowableArray<InlineTree> subt = subtrees();
+ for (int i = 0 ; i < subt.length(); i++) {
+ subt.at(i).printImpl(st, indent + 2);
+ }
+ }
+ public void print(PrintStream st) {
+ printImpl(st, 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/JVMState.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.ci.*;
+import sun.jvm.hotspot.types.*;
+
+public class JVMState extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("JVMState");
+ mapField = type.getAddressField("_map");
+ methodField = type.getAddressField("_method");
+ bciField = new CIntField(type.getCIntegerField("_bci"), 0);
+ spField = new CIntField(type.getCIntegerField("_sp"), 0);
+ endoffField = new CIntField(type.getCIntegerField("_endoff"), 0);
+ try {
+ scloffField = new CIntField(type.getCIntegerField("_scloff"), 0);
+ } catch (Exception e) {
+ }
+ monoffField = new CIntField(type.getCIntegerField("_monoff"), 0);
+ stkoffField = new CIntField(type.getCIntegerField("_stkoff"), 0);
+ locoffField = new CIntField(type.getCIntegerField("_locoff"), 0);
+ depthField = new CIntField(type.getCIntegerField("_depth"), 0);
+ callerField = type.getAddressField("_caller");
+ }
+
+ private static AddressField mapField;
+ private static AddressField methodField;
+ private static CIntField bciField;
+ private static CIntField spField;
+ private static CIntField endoffField;
+ private static CIntField scloffField;
+ private static CIntField monoffField;
+ private static CIntField stkoffField;
+ private static CIntField locoffField;
+ private static CIntField depthField;
+ private static AddressField callerField;
+
+ public static JVMState create(Address addr) {
+ if (addr == null) return null;
+ return new JVMState(addr);
+ }
+
+ public JVMState(Address addr) {
+ super(addr);
+ }
+
+ public ciMethod method() {
+ return (ciMethod) ciObjectFactory.get(methodField.getValue(getAddress()));
+ }
+
+ public int bci() {
+ return (int)bciField.getValue(getAddress());
+ }
+
+ public JVMState caller() {
+ return create(callerField.getValue(getAddress()));
+ }
+
+ public void dumpSpec(PrintStream out) {
+ ciMethod m = method();
+ if (m != null) {
+ Method meth = m.method();
+ out.print(" " + meth.getMethodHolder().getName().asString().replace('/', '.') + "::" +
+ meth.getName().asString() + " @ bci:" + bci());
+ } else {
+ out.print(" runtime stub");
+ }
+ if (caller() != null) caller().dumpSpec(out);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/LoopNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class LoopNode extends RegionNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("LoopNode");
+ }
+
+
+ public LoopNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallJavaNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.ci.ciMethod;
+import sun.jvm.hotspot.ci.ciObjectFactory;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class MachCallJavaNode extends MachCallNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachCallJavaNode");
+ methodField = type.getAddressField("_method");
+ bciField = new CIntField(type.getCIntegerField("_bci"), 0);
+ }
+
+ private static AddressField methodField;
+ private static CIntField bciField;
+
+ public ciMethod method() {
+ return (ciMethod) ciObjectFactory.get(methodField.getValue(getAddress()));
+ }
+
+ public MachCallJavaNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream st) {
+ ciMethod m = method();
+ if (m != null) {
+ m.printShortName(st);
+ st.print(" ");
+ }
+ super.dumpSpec(st);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class MachCallNode extends MachSafePointNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachCallNode");
+ }
+
+ public MachCallNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream st) {
+ st.print("# ");
+ // tf()->dump_on(st);
+ // if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt);
+ if (jvms() != null) jvms().dumpSpec(st);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallRuntimeNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.CStringUtilities;
+
+public class MachCallRuntimeNode extends MachCallJavaNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachCallRuntimeNode");
+ nameField = type.getAddressField("_name");
+ }
+
+ private static AddressField nameField;
+
+ public String name() {
+ return CStringUtilities.getString(nameField.getValue(getAddress()));
+ }
+
+ public MachCallRuntimeNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream out) {
+ out.printf("%s ", name());
+ super.dumpSpec(out);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachCallStaticJavaNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.CStringUtilities;
+
+public class MachCallStaticJavaNode extends MachCallJavaNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachCallStaticJavaNode");
+ nameField = type.getAddressField("_name");
+ }
+
+ private static AddressField nameField;
+
+ public String name() {
+ return CStringUtilities.getString(nameField.getValue(getAddress()));
+ }
+
+ public MachCallStaticJavaNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream st) {
+ st.print("Static ");
+ String n = name();
+ if (n != null) {
+ st.printf("wrapper for: %s", n);
+ // dump_trap_args(st);
+ st.print(" ");
+ }
+ super.dumpSpec(st);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachIfNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class MachIfNode extends MachNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachIfNode");
+ probField = type.getJFloatField("_prob");
+ fcntField = type.getJFloatField("_fcnt");
+ }
+
+ private static JFloatField probField;
+ private static JFloatField fcntField;
+
+ float prob() {
+ return probField.getValue(getAddress());
+ }
+
+ float cnt() {
+ return fcntField.getValue(getAddress());
+ }
+
+ public MachIfNode(Address addr) {
+ super(addr);
+ }
+
+ public void dumpSpec(PrintStream out) {
+ out.print("P=" + prob() + ", C=" + cnt());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class MachNode extends Node {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachNode");
+ }
+
+ public MachNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachReturnNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class MachReturnNode extends MachNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachReturnNode");
+ }
+
+ public MachReturnNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MachSafePointNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class MachSafePointNode extends MachReturnNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MachSafePointNode");
+ jvmsField = type.getAddressField("_jvms");
+ jvmadjField = new CIntField(type.getCIntegerField("_jvmadj"), 0);
+ }
+
+ private static AddressField jvmsField;
+ private static CIntField jvmadjField;
+
+ public MachSafePointNode(Address addr) {
+ super(addr);
+ }
+
+ public JVMState jvms() {
+ return JVMState.create(jvmsField.getValue(getAddress()));
+ }
+
+ public void dumpSpec(PrintStream out) {
+ try {
+ JVMState jvms = jvms();
+ if (jvms != null) out.print(" !");
+ if (jvms == null) out.print("empty jvms");
+ while (jvms != null) {
+ Method m = jvms.method().method();
+ int bci = jvms.bci();
+ out.print(" " + m.getMethodHolder().getName().asString().replace('/', '.') + "::" + m.getName().asString() + " @ bci:" + bci);
+ jvms = jvms.caller();
+ }
+ } catch (Exception e) {
+ out.print(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/MultiNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class MultiNode extends Node {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MultiNode");
+ }
+
+
+ public MultiNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Node.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.io.*;
+import java.lang.reflect.Constructor;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Node extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Node");
+ outmaxField = new CIntField(type.getCIntegerField("_outmax"), 0);
+ outcntField = new CIntField(type.getCIntegerField("_outcnt"), 0);
+ maxField = new CIntField(type.getCIntegerField("_max"), 0);
+ cntField = new CIntField(type.getCIntegerField("_cnt"), 0);
+ idxField = new CIntField(type.getCIntegerField("_idx"), 0);
+ outField = type.getAddressField("_out");
+ inField = type.getAddressField("_in");
+
+ nodeType = db.lookupType("Node");
+
+ virtualConstructor = new VirtualBaseConstructor(db, nodeType, "sun.jvm.hotspot.opto", Node.class);
+ }
+
+ private static CIntField outmaxField;
+ private static CIntField outcntField;
+ private static CIntField maxField;
+ private static CIntField cntField;
+ private static CIntField idxField;
+ private static AddressField outField;
+ private static AddressField inField;
+
+ private static VirtualBaseConstructor virtualConstructor;
+
+ private static Type nodeType;
+
+ static HashMap nodes = new HashMap();
+
+ static HashMap constructors = new HashMap();
+
+ static abstract class Instantiator {
+ abstract Node create(Address addr);
+ }
+
+ static public Node create(Address addr) {
+ if (addr == null) return null;
+ Node result = (Node)nodes.get(addr);
+ if (result == null) {
+ result = (Node)virtualConstructor.instantiateWrapperFor(addr);
+ nodes.put(addr, result);
+ }
+ return result;
+ }
+
+ public Node(Address addr) {
+ super(addr);
+ }
+
+ public int outcnt() {
+ return (int)outcntField.getValue(this.getAddress());
+ }
+
+ public int req() {
+ return (int)cntField.getValue(this.getAddress());
+ }
+
+ public int len() {
+ return (int)maxField.getValue(this.getAddress());
+ }
+
+ public int idx() {
+ return (int)idxField.getValue(this.getAddress());
+ }
+
+ private Node[] _out;
+ private Node[] _in;
+
+ public Node rawOut(int i) {
+ if (_out == null) {
+ int addressSize = (int)VM.getVM().getAddressSize();
+ _out = new Node[outcnt()];
+ Address ptr = outField.getValue(this.getAddress());
+ for (int j = 0; j < outcnt(); j++) {
+ _out[j] = Node.create(ptr.getAddressAt(j * addressSize));
+ }
+ }
+ return _out[i];
+ }
+
+ public Node in(int i) {
+ if (_in == null) {
+ int addressSize = (int)VM.getVM().getAddressSize();
+ _in = new Node[len()];
+ Address ptr = inField.getValue(this.getAddress());
+ for (int j = 0; j < len(); j++) {
+ _in[j] = Node.create(ptr.getAddressAt(j * addressSize));
+ }
+ }
+ return _in[i];
+ }
+
+ public ArrayList collect(int d, boolean onlyCtrl) {
+ int depth = Math.abs(d);
+ ArrayList nstack = new ArrayList();
+ BitSet set = new BitSet();
+
+ nstack.add(this);
+ set.set(idx());
+ int begin = 0;
+ int end = 0;
+ for (int i = 0; i < depth; i++) {
+ end = nstack.size();
+ for(int j = begin; j < end; j++) {
+ Node tp = (Node)nstack.get(j);
+ int limit = d > 0 ? tp.len() : tp.outcnt();
+ for(int k = 0; k < limit; k++) {
+ Node n = d > 0 ? tp.in(k) : tp.rawOut(k);
+
+ // if (NotANode(n)) continue;
+ if (n == null) continue;
+ // do not recurse through top or the root (would reach unrelated stuff)
+ // if (n.isRoot() || n.isTop()) continue;
+ // if (onlyCtrl && !n.isCfg()) continue;
+
+ if (!set.get(n.idx())) {
+ nstack.add(n);
+ set.set(n.idx());
+ }
+ }
+ }
+ begin = end;
+ }
+ return nstack;
+ }
+
+ protected void dumpNodes(Node s, int d, boolean onlyCtrl, PrintStream out) {
+ if (s == null) return;
+
+ ArrayList nstack = s.collect(d, onlyCtrl);
+ int end = nstack.size();
+ if (d > 0) {
+ for(int j = end-1; j >= 0; j--) {
+ ((Node)nstack.get(j)).dump(out);
+ }
+ } else {
+ for(int j = 0; j < end; j++) {
+ ((Node)nstack.get(j)).dump(out);
+ }
+ }
+ }
+
+ public void dump(int depth, PrintStream out) {
+ dumpNodes(this, depth, false, out);
+ }
+
+ public String Name() {
+ Type t = VM.getVM().getTypeDataBase().findDynamicTypeForAddress(getAddress(), nodeType);
+ String name = null;
+ if (t != null) {
+ name = t.toString();
+ } else {
+ Class c = getClass();
+ if (c == Node.class) {
+ // couldn't identify class type
+ return "UnknownNode<" + getAddress().getAddressAt(0) + ">";
+ }
+ name = getClass().getName();
+ if (name.startsWith("sun.jvm.hotspot.opto.")) {
+ name = name.substring("sun.jvm.hotspot.opto.".length());
+ }
+ }
+ if (name.endsWith("Node")) {
+ return name.substring(0, name.length() - 4);
+ }
+ return name;
+ }
+
+ public void dump(PrintStream out) {
+ out.print(" ");
+ out.print(idx());
+ out.print("\t");
+ out.print(Name());
+ out.print("\t=== ");
+ int i = 0;
+ for (i = 0; i < req(); i++) {
+ Node n = in(i);
+ if (n != null) {
+ out.print(' ');
+ out.print(in(i).idx());
+ } else {
+ out.print("_");
+ }
+ out.print(" ");
+ }
+ if (len() != req()) {
+ int prec = 0;
+ for (; i < len(); i++) {
+ Node n = in(i);
+ if (n != null) {
+ if (prec++ == 0) {
+ out.print("| ");
+ }
+ out.print(in(i).idx());
+ }
+ out.print(" ");
+ }
+ }
+ dumpOut(out);
+ dumpSpec(out);
+ out.println();
+ }
+
+ void dumpOut(PrintStream out) {
+ // Delimit the output edges
+ out.print(" [[");
+ // Dump the output edges
+ for (int i = 0; i < outcnt(); i++) { // For all outputs
+ Node u = rawOut(i);
+ if (u == null) {
+ out.print("_ ");
+ // } else if (NotANode(u)) {
+ // out.print("NotANode ");
+ } else {
+ // out.print("%c%d ", Compile::current()->nodeArena()->contains(u) ? ' ' : 'o', u->_idx);
+ out.print(' ');
+ out.print(u.idx());
+ out.print(' ');
+ }
+ }
+ out.print("]] ");
+ }
+
+ public void dumpSpec(PrintStream out) {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Node_Array.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Node_Array extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Node_Array");
+ maxField = new CIntField(type.getCIntegerField("_max"), 0);
+ nodesField = type.getAddressField("_nodes");
+ aField = type.getAddressField("_a");
+ }
+
+ private static CIntField maxField;
+ private static AddressField nodesField;
+ private static AddressField aField;
+
+ public Node_Array(Address addr) {
+ super(addr);
+ }
+
+ public int Size() {
+ return (int) maxField.getValue(getAddress());
+ }
+
+ public Node at(int i) {
+ return Node.create(nodesField.getValue(getAddress()).getAddressAt(i * (int)VM.getVM().getAddressSize()));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Node_List.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Node_List extends Node_Array {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Node_List");
+ cntField = new CIntField(type.getCIntegerField("_cnt"), 0);
+ }
+
+ private static CIntField cntField;
+
+ public Node_List(Address addr) {
+ super(addr);
+ }
+
+ public int size() {
+ return (int) cntField.getValue(getAddress());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/Phase.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class Phase extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("Phase");
+ }
+
+
+ public Phase(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import java.io.PrintStream;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class PhaseCFG extends Phase {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("PhaseCFG");
+ numBlocksField = new CIntField(type.getCIntegerField("_num_blocks"), 0);
+ blocksField = type.getAddressField("_blocks");
+ bbsField = type.getAddressField("_bbs");
+ brootField = type.getAddressField("_broot");
+ }
+
+ private static CIntField numBlocksField;
+ private static AddressField blocksField;
+ private static AddressField bbsField;
+ private static AddressField brootField;
+
+ public PhaseCFG(Address addr) {
+ super(addr);
+ }
+
+ public void dump(PrintStream out) {
+ int addressSize = (int)VM.getVM().getAddressSize();
+ int numBlocks = (int)numBlocksField.getValue(getAddress());
+ Block_List blocks = new Block_List(getAddress().addOffsetTo(blocksField.getOffset()));
+ int offset = 0;
+ for (int i = 0; i < numBlocks; i++) {
+ blocks.at(i).dump(out);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseRegAlloc.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class PhaseRegAlloc extends Phase {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("PhaseRegAlloc");
+ nodeRegsField = type.getAddressField("_node_regs");
+ nodeRegsMaxIndexField = new CIntField(type.getCIntegerField("_node_regs_max_index"), 0);
+ framesizeField = new CIntField(type.getCIntegerField("_framesize"), 0);
+ maxRegField = new CIntField(type.getCIntegerField("_max_reg"), 0);
+ }
+
+ private static AddressField nodeRegsField;
+ private static CIntField nodeRegsMaxIndexField;
+ private static CIntField framesizeField;
+ private static CIntField maxRegField;
+
+ public PhaseRegAlloc(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/PhiNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class PhiNode extends TypeNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("PhiNode");
+ }
+
+
+ public PhiNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/ProjNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class ProjNode extends Node {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ProjNode");
+ }
+
+
+ public ProjNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/RegionNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class RegionNode extends Node {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("RegionNode");
+ }
+
+
+ public RegionNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/RootNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class RootNode extends LoopNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("RootNode");
+ }
+
+
+ public RootNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/SafePointNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.io.PrintStream;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class SafePointNode extends MultiNode {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("SafePointNode");
+ jvmsField = type.getAddressField("_jvms");
+ }
+
+ private static AddressField jvmsField;
+
+ public SafePointNode(Address addr) {
+ super(addr);
+ }
+
+ public JVMState jvms() {
+ return JVMState.create(jvmsField.getValue(getAddress()));
+ }
+
+ public void dumpSpec(PrintStream out) {
+ JVMState jvms = jvms();
+ if (jvms != null) out.print(" !");
+ while (jvms != null) {
+ Method m = jvms.method().method();
+ int bci = jvms.bci();
+ out.print(" " + m.getMethodHolder().getName().asString().replace('/', '.') + "::" + m.getName().asString() + " @ bci:" + bci);
+ jvms = jvms.caller();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/TypeNode.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.opto;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class TypeNode extends Node {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("TypeNode");
+ }
+
+
+ public TypeNode(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/prims/JvmtiExport.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.prims;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class JvmtiExport {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("JvmtiExport");
+ // XXX
+ // canAccessLocalVariables = type.getCIntegerField("_can_access_local_variables");
+ // canHotswapOrPostBreakpoint = type.getCIntegerField("_can_hotswap_or_post_breakpoint");
+ // canPostOnExceptions = type.getCIntegerField("_can_post_on_exceptions");
+ }
+
+ private static CIntegerField canAccessLocalVariables;
+ private static CIntegerField canHotswapOrPostBreakpoint;
+ private static CIntegerField canPostOnExceptions;
+
+ public static boolean canAccessLocalVariables() {
+ // return canAccessLocalVariables.getValue() != 0;
+ return false;
+ }
+ public static boolean canHotswapOrPostBreakpoint() {
+ // return canHotswapOrPostBreakpoint.getValue() != 0;
+ return false;
+ }
+ public static boolean canPostOnExceptions() {
+ // return canPostOnExceptions.getValue() != 0;
+ return false;
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompilerThread.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompilerThread.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,40 @@
package sun.jvm.hotspot.runtime;
import java.io.*;
+import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.ci.*;
public class CompilerThread extends JavaThread {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static AddressField _env_field;
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("CompilerThread");
+
+ _env_field = type.getAddressField("_env");
+ }
+
+ private ciEnv _env;
+
+ public synchronized ciEnv env() {
+ if (_env == null) {
+ Address v = _env_field.getValue(this.getAddress());
+ if (v != null) {
+ _env = new ciEnv(v);
+ }
+ }
+ return _env;
+ }
+
public CompilerThread(Address addr) {
super(addr);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/InstanceConstructor.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.CDebugger;
+import sun.jvm.hotspot.debugger.cdbg.ClosestSymbol;
+import sun.jvm.hotspot.debugger.cdbg.LoadObject;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.HotSpotTypeDataBase;
+
+/** Given a pointer to some memory return an appropriate wrapper.
+ Various subclasses provide different mechanisms for identifying the
+ appropriate wrapper. */
+
+abstract public class InstanceConstructor<T> {
+ /** Instantiate the most-precisely typed wrapper object available
+ for the type of the given Address. If no type in the mapping
+ matched the type of the Address, throws a WrongTypeException.
+ Returns null for a null address (similar behavior to
+ VMObjectFactory). */
+ abstract public T instantiateWrapperFor(Address addr) throws WrongTypeException;
+
+ protected WrongTypeException newWrongTypeException(Address addr) {
+ String message = "No suitable match for type of address " + addr;
+ CDebugger cdbg = VM.getVM().getDebugger().getCDebugger();
+ if (cdbg != null) {
+ // Most common case: V-table pointer is the first field
+ Address vtblPtr = addr.getAddressAt(0);
+ LoadObject lo = cdbg.loadObjectContainingPC(vtblPtr);
+ if (lo != null) {
+ ClosestSymbol symbol = lo.closestSymbolToPC(vtblPtr);
+ if (symbol != null) {
+ message += " (nearest symbol is " + symbol.getName() + ")";
+ }
+ }
+ }
+
+ return new WrongTypeException(message);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/StaticBaseConstructor.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.CDebugger;
+import sun.jvm.hotspot.debugger.cdbg.ClosestSymbol;
+import sun.jvm.hotspot.debugger.cdbg.LoadObject;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.HotSpotTypeDataBase;
+
+/** Instantiate wrappers for statically typed instances. */
+
+public class StaticBaseConstructor<T> extends InstanceConstructor {
+ private Class staticType;
+
+ public StaticBaseConstructor(Class<T> t) {
+ staticType = t;
+ }
+
+ /** Instantiate a wrapper using staticType */
+ public VMObject instantiateWrapperFor(Address addr) throws WrongTypeException {
+ if (addr == null) {
+ return null;
+ }
+
+ return (VMObject) VMObjectFactory.newObject(staticType, addr);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Thu Sep 15 12:44:09 2011 -0700
@@ -135,12 +135,14 @@
private String name;
private Address addr;
private String kind;
+ private int origin;
- private Flag(String type, String name, Address addr, String kind) {
+ private Flag(String type, String name, Address addr, String kind, int origin) {
this.type = type;
this.name = name;
this.addr = addr;
this.kind = kind;
+ this.origin = origin;
}
public String getType() {
@@ -159,6 +161,10 @@
return kind;
}
+ public int getOrigin() {
+ return origin;
+ }
+
public boolean isBool() {
return type.equals("bool");
}
@@ -304,7 +310,7 @@
usingServerCompiler = false;
} else {
// Determine whether C2 is present
- if (type.getField("_interpreter_invocation_count", false, false) != null) {
+ if (db.lookupType("Matcher", false) != null) {
usingServerCompiler = true;
} else {
usingClientCompiler = true;
@@ -804,42 +810,40 @@
private void readCommandLineFlags() {
// get command line flags
TypeDataBase db = getTypeDataBase();
- try {
- Type flagType = db.lookupType("Flag");
- int numFlags = (int) flagType.getCIntegerField("numFlags").getValue();
- // NOTE: last flag contains null values.
- commandLineFlags = new Flag[numFlags - 1];
+ Type flagType = db.lookupType("Flag");
+ int numFlags = (int) flagType.getCIntegerField("numFlags").getValue();
+ // NOTE: last flag contains null values.
+ commandLineFlags = new Flag[numFlags - 1];
+
+ Address flagAddr = flagType.getAddressField("flags").getValue();
- Address flagAddr = flagType.getAddressField("flags").getValue();
+ AddressField typeFld = flagType.getAddressField("type");
+ AddressField nameFld = flagType.getAddressField("name");
+ AddressField addrFld = flagType.getAddressField("addr");
+ AddressField kindFld = flagType.getAddressField("kind");
+ CIntField originFld = new CIntField(flagType.getCIntegerField("origin"), 0);
- AddressField typeFld = flagType.getAddressField("type");
- AddressField nameFld = flagType.getAddressField("name");
- AddressField addrFld = flagType.getAddressField("addr");
- AddressField kindFld = flagType.getAddressField("kind");
-
- long flagSize = flagType.getSize(); // sizeof(Flag)
+ long flagSize = flagType.getSize(); // sizeof(Flag)
- // NOTE: last flag contains null values.
- for (int f = 0; f < numFlags - 1; f++) {
- String type = CStringUtilities.getString(typeFld.getValue(flagAddr));
- String name = CStringUtilities.getString(nameFld.getValue(flagAddr));
- Address addr = addrFld.getValue(flagAddr);
- String kind = CStringUtilities.getString(kindFld.getValue(flagAddr));
- commandLineFlags[f] = new Flag(type, name, addr, kind);
- flagAddr = flagAddr.addOffsetTo(flagSize);
- }
+ // NOTE: last flag contains null values.
+ for (int f = 0; f < numFlags - 1; f++) {
+ String type = CStringUtilities.getString(typeFld.getValue(flagAddr));
+ String name = CStringUtilities.getString(nameFld.getValue(flagAddr));
+ Address addr = addrFld.getValue(flagAddr);
+ String kind = CStringUtilities.getString(kindFld.getValue(flagAddr));
+ int origin = (int)originFld.getValue(flagAddr);
+ commandLineFlags[f] = new Flag(type, name, addr, kind, origin);
+ flagAddr = flagAddr.addOffsetTo(flagSize);
+ }
- // sort flags by name
- Arrays.sort(commandLineFlags, new Comparator() {
- public int compare(Object o1, Object o2) {
- Flag f1 = (Flag) o1;
- Flag f2 = (Flag) o2;
- return f1.getName().compareTo(f2.getName());
- }
- });
- } catch (Exception exp) {
- // ignore. may be older version. command line flags not available.
- }
+ // sort flags by name
+ Arrays.sort(commandLineFlags, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ Flag f1 = (Flag) o1;
+ Flag f2 = (Flag) o2;
+ return f1.getName().compareTo(f2.getName());
+ }
+ });
}
public String getSystemProperty(String key) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VirtualBaseConstructor.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.CDebugger;
+import sun.jvm.hotspot.debugger.cdbg.ClosestSymbol;
+import sun.jvm.hotspot.debugger.cdbg.LoadObject;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.HotSpotTypeDataBase;
+
+/** This provides a factory to create instances where the base virtual
+ * type is know and the expected subclasses are within a particular
+ * package. */
+
+public class VirtualBaseConstructor<T> extends InstanceConstructor {
+ private TypeDataBase db;
+ private HashMap map; // Map<String, Class>
+ private Type baseType;
+ private Class unknownTypeHandler;
+
+ public VirtualBaseConstructor(TypeDataBase db, Type baseType, String packageName, Class unknownTypeHandler) {
+ this.db = (HotSpotTypeDataBase)db;
+ map = new HashMap();
+ this.baseType = baseType;
+ this.unknownTypeHandler = unknownTypeHandler;
+ // Try to find mirror types for each of the types. If there isn't
+ // a direct mirror then try to find an instantiable superclass and
+ // treat it as that.
+ for (Iterator iter = db.getTypes(); iter.hasNext(); ) {
+ Type t = (Type) iter.next();
+ Type superType = t;
+ while (superType != null && superType != baseType) {
+ superType = superType.getSuperclass();
+ }
+ if (superType == baseType) {
+ superType = t;
+ Class c = null;
+ while (c == null && superType != null) {
+ try {
+ c = Class.forName(packageName + "." + superType.getName());
+ } catch (Exception e) {
+ }
+ if (c == null) superType = superType.getSuperclass();
+ }
+ if (c == null) {
+ c = unknownTypeHandler;
+ }
+ map.put(t.getName(), c);
+ }
+ }
+ }
+
+ /** Instantiate the most-precisely typed wrapper object available
+ for the type of the given Address. If no type in the mapping
+ matched the type of the Address, throws a WrongTypeException.
+ Returns null for a null address (similar behavior to
+ VMObjectFactory). */
+ public VMObject instantiateWrapperFor(Address addr) throws WrongTypeException {
+ if (addr == null) {
+ return null;
+ }
+
+ Type type = db.findDynamicTypeForAddress(addr, baseType);
+ if (type != null) {
+ return (VMObject) VMObjectFactory.newObject((Class) map.get(type.getName()), addr);
+ } else if (unknownTypeHandler != null) {
+ return (VMObject) VMObjectFactory.newObject(unknownTypeHandler, addr);
+ }
+
+ throw newWrongTypeException(addr);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VirtualConstructor.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VirtualConstructor.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
import java.util.*;
import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.types.*;
/** This class provides generalized "virtual constructor"
@@ -39,7 +38,7 @@
type "DefNewGeneration" to class
sun.jvm.hotspot.memory.DefNewGeneration has been set up. */
-public class VirtualConstructor {
+public class VirtualConstructor extends InstanceConstructor<VMObject> {
private TypeDataBase db;
private Map map; // Map<String, Class>
@@ -78,20 +77,6 @@
}
}
- String message = "No suitable match for type of address " + addr;
- CDebugger cdbg = VM.getVM().getDebugger().getCDebugger();
- if (cdbg != null) {
- // Most common case: V-table pointer is the first field
- Address vtblPtr = addr.getAddressAt(0);
- LoadObject lo = cdbg.loadObjectContainingPC(vtblPtr);
- if (lo != null) {
- ClosestSymbol symbol = lo.closestSymbolToPC(vtblPtr);
- if (symbol != null) {
- message += " (nearest symbol is " + symbol.getName() + ")";
- }
- }
- }
-
- throw new WrongTypeException(message);
+ throw newWrongTypeException(addr);
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.win32.*;
import sun.jvm.hotspot.debugger.amd64.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.runtime.amd64.*;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.win32.*;
import sun.jvm.hotspot.debugger.x86.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.runtime.x86.*;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,9 @@
package sun.jvm.hotspot.tools.jcore;
import java.io.*;
+import java.util.jar.JarOutputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.Manifest;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.debugger.*;
@@ -34,27 +37,33 @@
public class ClassDump extends Tool {
private ClassFilter classFilter;
private String outputDirectory;
+ private JarOutputStream jarStream;
+
+ public void setClassFilter(ClassFilter cf) {
+ classFilter = cf;
+ }
+
+ public void setOutputDirectory(String od) {
+ outputDirectory = od;
+ if (jarStream != null) {
+ try {
+ jarStream.close();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+ jarStream = null;
+ }
+
+ public void setJarOutput(String jarFileName) throws IOException {
+ jarStream = new JarOutputStream(new FileOutputStream(jarFileName), new Manifest());
+ outputDirectory = null;
+ }
public void run() {
// Ready to go with the database...
try {
- // load class filters
-
- String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter");
- if (filterClassName != null) {
- try {
- Class filterClass = Class.forName(filterClassName);
- classFilter = (ClassFilter) filterClass.newInstance();
- } catch(Exception exp) {
- System.err.println("Warning: Can not create class filter!");
- }
- }
-
- outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir");
- if (outputDirectory == null)
- outputDirectory = ".";
-
// walk through the system dictionary
SystemDictionary dict = VM.getVM().getSystemDictionary();
dict.classesDo(new SystemDictionary.ClassVisitor() {
@@ -75,6 +84,14 @@
+ Long.toHexString(e.getAddress()));
e.printStackTrace();
}
+ if (jarStream != null) {
+ try {
+ jarStream.close();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ jarStream = null;
+ }
}
public String getName() {
@@ -88,26 +105,33 @@
String klassName = kls.getName().asString();
klassName = klassName.replace('/', File.separatorChar);
- int index = klassName.lastIndexOf(File.separatorChar);
- File dir = null;
- if (index != -1) {
- String dirName = klassName.substring(0, index);
- dir = new File(outputDirectory, dirName);
- } else {
- dir = new File(outputDirectory);
- }
+ try {
+ OutputStream os = null;
+ if (jarStream != null) {
+ jarStream.putNextEntry(new JarEntry(klassName + ".class"));
+ os = jarStream;
+ } else {
+ int index = klassName.lastIndexOf(File.separatorChar);
+ File dir = null;
+ if (index != -1) {
+ String dirName = klassName.substring(0, index);
+ dir = new File(outputDirectory, dirName);
+ } else {
+ dir = new File(outputDirectory);
+ }
- dir.mkdirs();
- File f = new File(dir, klassName.substring(klassName.lastIndexOf(File.separatorChar) + 1)
- + ".class");
- try {
- f.createNewFile();
- OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
+ dir.mkdirs();
+ File f = new File(dir, klassName.substring(index + 1) + ".class");
+ f.createNewFile();
+ os = new BufferedOutputStream(new FileOutputStream(f));
+ }
try {
ClassWriter cw = new ClassWriter(kls, os);
cw.write();
} finally {
- os.close();
+ if (os != jarStream) {
+ os.close();
+ }
}
} catch(IOException exp) {
exp.printStackTrace();
@@ -115,7 +139,26 @@
}
public static void main(String[] args) {
+ // load class filters
+ ClassFilter classFilter = null;
+ String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter");
+ if (filterClassName != null) {
+ try {
+ Class filterClass = Class.forName(filterClassName);
+ classFilter = (ClassFilter) filterClass.newInstance();
+ } catch(Exception exp) {
+ System.err.println("Warning: Can not create class filter!");
+ }
+ }
+
+ String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir");
+ if (outputDirectory == null)
+ outputDirectory = ".";
+
+
ClassDump cd = new ClassDump();
+ cd.setClassFilter(classFilter);
+ cd.setOutputDirectory(outputDirectory);
cd.start(args);
cd.stop();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Thu Sep 15 12:44:09 2011 -0700
@@ -380,15 +380,15 @@
protected void writeFields() throws IOException {
TypeArray fields = klass.getFields();
- final int length = (int) fields.getLength();
+ final int length = klass.getJavaFieldsCount();
// write number of fields
- dos.writeShort((short) (length / InstanceKlass.NEXT_OFFSET) );
+ dos.writeShort((short) (length / InstanceKlass.FIELD_SLOTS) );
if (DEBUG) debugMessage("number of fields = "
- + length/InstanceKlass.NEXT_OFFSET);
+ + length/InstanceKlass.FIELD_SLOTS);
- for (int index = 0; index < length; index += InstanceKlass.NEXT_OFFSET) {
+ for (int index = 0; index < length; index += InstanceKlass.FIELD_SLOTS) {
short accessFlags = fields.getShortAt(index + InstanceKlass.ACCESS_FLAGS_OFFSET);
dos.writeShort(accessFlags & (short) JVM_RECOGNIZED_FIELD_MODIFIERS);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Thu Sep 15 12:44:09 2011 -0700
@@ -150,16 +150,13 @@
}
// list immediate fields only
- TypeArray fields = klass.getFields();
- int numFields = (int) fields.getLength();
+ int numFields = klass.getJavaFieldsCount();
ConstantPool cp = klass.getConstants();
out.println("fields");
if (numFields != 0) {
- for (int f = 0; f < numFields; f += InstanceKlass.NEXT_OFFSET) {
- int nameIndex = fields.getShortAt(f + InstanceKlass.NAME_INDEX_OFFSET);
- int sigIndex = fields.getShortAt(f + InstanceKlass.SIGNATURE_INDEX_OFFSET);
- Symbol f_name = cp.getSymbolAt(nameIndex);
- Symbol f_sig = cp.getSymbolAt(sigIndex);
+ for (int f = 0; f < numFields; f++){
+ Symbol f_name = klass.getFieldName(f);
+ Symbol f_sig = klass.getFieldSignature(f);
StringBuffer sigBuf = new StringBuffer();
new SignatureConverter(f_sig, sigBuf).dispatchField();
out.print('\t');
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/TypeDataBase.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/TypeDataBase.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, 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
@@ -120,6 +120,11 @@
found. */
public Type guessTypeForAddress(Address addr);
+ /** Helper routine for guessing the most derived type of a
+ polymorphic C++ object. Requires a baseType that must be virtual
+ so that lookup can be performed without false positives */
+ public Type findDynamicTypeForAddress(Address addr, Type baseType);
+
/** Returns an Iterator over the Types in the database. */
public Iterator getTypes();
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, 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
@@ -150,6 +150,19 @@
return VM.getVM().getOopSize();
}
+ static HashMap typeToVtbl = new HashMap();
+
+ private Address vtblForType(Type type) {
+ Address vtblAddr = (Address)typeToVtbl.get(type);
+ if (vtblAddr == null) {
+ vtblAddr = vtblAccess.getVtblForType(type);
+ if (vtblAddr != null) {
+ typeToVtbl.put(type, vtblAddr);
+ }
+ }
+ return vtblAddr;
+ }
+
public boolean addressTypeIsEqualToType(Address addr, Type type) {
if (addr == null) {
return false;
@@ -158,7 +171,7 @@
// This implementation should be suitably platform-independent; we
// search nearby memory for the vtbl value of the given type.
- Address vtblAddr = vtblAccess.getVtblForType(type);
+ Address vtblAddr = vtblForType(type);
if (vtblAddr == null) {
// Type was not polymorphic, or an error occurred during lookup
@@ -251,6 +264,78 @@
return false;
}
+ public Type findDynamicTypeForAddress(Address addr, Type baseType) {
+ // This implementation should be suitably platform-independent; we
+ // search nearby memory for the vtbl value of the given type.
+
+ if (vtblForType(baseType) == null) {
+ // Type was not polymorphic which is an error of some sort
+ throw new InternalError(baseType + " does not appear to be polymorphic");
+ }
+
+ // This is a more restricted version of guessTypeForAddress since
+ // that function has some limitations since it doesn't really know
+ // where in the hierarchy a virtual type starts and just poking
+ // around in memory is likely to trip over some vtable address,
+ // resulting in false positives. Eventually all uses should
+ // switch to this logic but in the interests of stability it will
+ // be separate for the moment.
+
+ // Assuming that the base type is truly the first polymorphic type
+ // then the vtbl for all subclasss should be at several defined
+ // locations so only those locations will be checked. It's also
+ // required that the caller knows that the static type is at least
+ // baseType. See the notes in guessTypeForAddress for the logic of
+ // the locations searched.
+
+ Address loc1 = addr.getAddressAt(0);
+ Address loc2 = null;
+ Address loc3 = null;
+ long offset2 = baseType.getSize();
+ // I don't think this should be misaligned under any
+ // circumstances, but I'm not sure (FIXME: also not sure which
+ // way to go here, up or down -- assuming down)
+ offset2 = offset2 - (offset2 % getAddressSize()) - getAddressSize();
+ if (offset2 > 0) {
+ loc2 = addr.getAddressAt(offset2);
+ }
+ long offset3 = offset2 - getAddressSize();
+ if (offset3 > 0) {
+ loc3 = addr.getAddressAt(offset3);
+ }
+
+ Type loc2Match = null;
+ Type loc3Match = null;
+ for (Iterator iter = getTypes(); iter.hasNext(); ) {
+ Type type = (Type) iter.next();
+ Type superClass = type;
+ while (superClass != baseType && superClass != null) {
+ superClass = superClass.getSuperclass();
+ }
+ if (superClass == null) continue;
+ Address vtblAddr = vtblForType(type);
+ if (vtblAddr == null) {
+ // This occurs sometimes for intermediate types that are never
+ // instantiated.
+ if (DEBUG) {
+ System.err.println("null vtbl for " + type);
+ }
+ continue;
+ }
+ // Prefer loc1 match
+ if (vtblAddr.equals(loc1)) return type;
+ if (loc2 != null && loc2Match == null && vtblAddr.equals(loc2)) {
+ loc2Match = type;
+ }
+ if (loc3 != null && loc3Match == null && vtblAddr.equals(loc3)) {
+ loc3Match = type;
+ }
+ }
+ if (loc2Match != null) return loc2Match;
+ if (loc3Match != null) return loc3Match;
+ return null;
+ }
+
public Type guessTypeForAddress(Address addr) {
for (Iterator iter = getTypes(); iter.hasNext(); ) {
Type t = (Type) iter.next();
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/CommandProcessorPanel.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/CommandProcessorPanel.java Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -88,7 +88,7 @@
public void run() {
beginUpdate();
try {
- commands.executeCommand(ln);
+ commands.executeCommand(ln, true);
commands.printPrompt();
Document d = editor.getDocument();
try {
@@ -149,7 +149,7 @@
public void clear() {
EditableAtEndDocument d = (EditableAtEndDocument) editor.getDocument();
d.clear();
- commands.executeCommand("");
+ commands.executeCommand("", false);
setMark();
editor.requestFocus();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Sep 15 12:44:09 2011 -0700
@@ -1116,20 +1116,15 @@
InstanceKlass kls = (InstanceKlass) obj;
buf.append(" " + kls.getName().asString() + "={");
int flen = ov.fieldsSize();
-
- TypeArray klfields = kls.getFields();
- int klen = (int) klfields.getLength();
-
- ConstantPool cp = kls.getConstants();
+ int klen = kls.getJavaFieldsCount();
int findex = 0;
- for (int index = 0; index < klen; index += kls.NEXT_OFFSET) {
- int accsFlags = klfields.getShortAt(index + kls.ACCESS_FLAGS_OFFSET);
- int nameIndex = klfields.getShortAt(index + kls.NAME_INDEX_OFFSET);
+ for (int index = 0; index < klen; index++) {
+ int accsFlags = kls.getFieldAccessFlags(index);
+ Symbol f_name = kls.getFieldName(index);
AccessFlags access = new AccessFlags(accsFlags);
if (!access.isStatic()) {
ScopeValue svf = ov.getFieldAt(findex++);
String fstr = scopeValueAsString(sd, svf);
- Symbol f_name = cp.getSymbolAt(nameIndex);
buf.append(" [" + f_name.asString() + " :"+ index + "]=(#" + fstr + ")");
}
}
@@ -1819,13 +1814,11 @@
protected String genHTMLListForFields(InstanceKlass klass) {
Formatter buf = new Formatter(genHTML);
- TypeArray fields = klass.getFields();
- int numFields = (int) fields.getLength();
- ConstantPool cp = klass.getConstants();
+ int numFields = klass.getJavaFieldsCount();
if (numFields != 0) {
buf.h3("Fields");
buf.beginList();
- for (int f = 0; f < numFields; f += InstanceKlass.NEXT_OFFSET) {
+ for (int f = 0; f < numFields; f++) {
sun.jvm.hotspot.oops.Field field = klass.getFieldByIndex(f);
String f_name = ((NamedFieldIdentifier)field.getID()).getName();
Symbol f_sig = field.getSignature();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/GenericGrowableArray.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.utilities;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class GenericGrowableArray extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("GenericGrowableArray");
+ _arena_field = type.getAddressField("_arena");
+ _max_field = new CIntField(type.getCIntegerField("_max"), 0);
+ _len_field = new CIntField(type.getCIntegerField("_len"), 0);
+ }
+
+ private static AddressField _arena_field;
+ private static CIntField _max_field;
+ private static CIntField _len_field;
+
+ public int max() {
+ return (int)_max_field.getValue(getAddress());
+ }
+
+ public int length() {
+ return (int)_len_field.getValue(getAddress());
+ }
+
+ public GenericGrowableArray(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package sun.jvm.hotspot.utilities;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+
+public class GrowableArray<T> extends GenericGrowableArray {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("GrowableArray<int>");
+ dataField = type.getAddressField("_data");
+ }
+
+ private static AddressField dataField;
+
+ private InstanceConstructor<T> virtualConstructor;
+
+ public static <S> GrowableArray<S> create(Address addr, InstanceConstructor<S> v) {
+ if (addr == null) return null;
+ return new GrowableArray<S>(addr, v);
+ }
+
+ public T at(int i) {
+ if (i < 0 || i >= length()) throw new ArrayIndexOutOfBoundsException(i);
+ Address data = dataField.getValue(getAddress());
+ Address addr = data.getAddressAt(i * VM.getVM().getAddressSize());
+ if (addr == null) return null;
+ return (T) virtualConstructor.instantiateWrapperFor(addr);
+ }
+
+ private GrowableArray(Address addr, InstanceConstructor<T> v) {
+ super(addr);
+ virtualConstructor = v;
+ }
+}
--- a/hotspot/agent/test/jdi/sasanity.sh Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/agent/test/jdi/sasanity.sh Thu Sep 15 12:44:09 2011 -0700
@@ -76,5 +76,5 @@
sleep 2
done
-$jdk/bin/java -showversion ${OPTIONS} -classpath $javacp SASanityChecker $pid
+$jdk/bin/java -showversion ${OPTIONS} -classpath $javacp $* SASanityChecker $pid
kill -9 $pid
--- a/hotspot/make/sa.files Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/make/sa.files Thu Sep 15 12:44:09 2011 -0700
@@ -46,6 +46,7 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/tree/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/ci/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \
@@ -54,9 +55,6 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/sparc/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dbx/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ia64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \
@@ -75,7 +73,6 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/sparc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/sparc/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/coff/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/amd64/*.java \
@@ -89,7 +86,9 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/jdi/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/livejvm/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/memory/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/opto/*.java \
+$(AGENT_SRC_DIR)/sun/jvm/hotspot/prims/*.java
AGENT_FILES2 = \
@@ -106,9 +105,6 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_sparc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/sparc/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_amd64/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_ia64/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/win32_x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/jcore/*.java \
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -3257,15 +3257,10 @@
Register temp_reg) {
assert_different_registers(vmslots_reg, mh_reg, temp_reg);
// load mh.type.form.vmslots
- if (java_lang_invoke_MethodHandle::vmslots_offset_in_bytes() != 0) {
- // hoist vmslots into every mh to avoid dependent load chain
- ld( Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
- } else {
- Register temp2_reg = vmslots_reg;
- load_heap_oop(Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)), temp2_reg);
- load_heap_oop(Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)), temp2_reg);
- ld( Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
- }
+ Register temp2_reg = vmslots_reg;
+ load_heap_oop(Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)), temp2_reg);
+ load_heap_oop(Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)), temp2_reg);
+ ld( Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
}
@@ -4966,4 +4961,3 @@
cmp_and_brx_short(to, end, Assembler::lessUnsigned, Assembler::pt, small_loop);
nop(); // Separate short branches
}
-
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -839,3 +839,9 @@
}
#endif
+
+intptr_t *frame::initial_deoptimization_info() {
+ // unused... but returns fp() to minimize changes introduced by 7087445
+ return fp();
+}
+
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -436,7 +436,7 @@
#undef __
#define __ masm->
- address generate_throw_exception(const char* name, address runtime_entry, bool restore_saved_exception_pc,
+ address generate_throw_exception(const char* name, address runtime_entry,
Register arg1 = noreg, Register arg2 = noreg) {
#ifdef ASSERT
int insts_size = VerifyThread ? 1 * K : 600;
@@ -462,11 +462,6 @@
int frame_complete = __ offset();
- if (restore_saved_exception_pc) {
- __ ld_ptr(G2_thread, JavaThread::saved_exception_pc_offset(), I7);
- __ sub(I7, frame::pc_return_offset, I7);
- }
-
// Note that we always have a runtime stub frame on the top of stack by this point
Register last_java_sp = SP;
// 64-bit last_java_sp is biased!
@@ -3418,7 +3413,7 @@
StubRoutines::_throw_WrongMethodTypeException_entry =
generate_throw_exception("WrongMethodTypeException throw_exception",
CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException),
- false, G5_method_type, G3_method_handle);
+ G5_method_type, G3_method_handle);
}
@@ -3429,12 +3424,10 @@
// UseZeroBaseCompressedOops which is defined after heap initialization.
StubRoutines::Sparc::_partial_subtype_check = generate_partial_subtype_check();
// These entry points require SharedInfo::stack0 to be set up in non-core builds
- StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError), false);
- StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false);
- StubRoutines::_throw_ArithmeticException_entry = generate_throw_exception("ArithmeticException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_ArithmeticException), true);
- StubRoutines::_throw_NullPointerException_entry = generate_throw_exception("NullPointerException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true);
- StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
- StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
+ StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
+ StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
+ StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
+ StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
StubRoutines::_handler_for_unsafe_access_entry =
generate_handler_for_unsafe_access();
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -8004,15 +8004,10 @@
Register temp_reg) {
assert_different_registers(vmslots_reg, mh_reg, temp_reg);
// load mh.type.form.vmslots
- if (java_lang_invoke_MethodHandle::vmslots_offset_in_bytes() != 0) {
- // hoist vmslots into every mh to avoid dependent load chain
- movl(vmslots_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
- } else {
- Register temp2_reg = vmslots_reg;
- load_heap_oop(temp2_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)));
- load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)));
- movl(vmslots_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
- }
+ Register temp2_reg = vmslots_reg;
+ load_heap_oop(temp2_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)));
+ load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)));
+ movl(vmslots_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
}
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -666,3 +666,9 @@
}
#endif
+
+intptr_t *frame::initial_deoptimization_info() {
+ // used to reset the saved FP
+ return fp();
+}
+
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -624,6 +624,11 @@
// error path for invokeExact (only)
__ bind(invoke_exact_error_path);
+ // ensure that the top of stack is properly aligned.
+ __ mov(rdi, rsp);
+ __ andptr(rsp, -StackAlignmentInBytes); // Align the stack for the ABI
+ __ pushptr(Address(rdi, 0)); // Pick up the return address
+
// Stub wants expected type in rax and the actual type in rcx
__ jump(ExternalAddress(StubRoutines::throw_WrongMethodTypeException_entry()));
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -2471,7 +2471,7 @@
__ movl(counter, rbx);
// Pick up the initial fp we should save
- __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+ __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
// Now adjust the caller's stack to make up for the extra locals
// but record the original sp so that we can save it in the skeletal interpreter
@@ -2691,7 +2691,7 @@
__ movl(counter, rbx);
// Pick up the initial fp we should save
- __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+ __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
// Now adjust the caller's stack to make up for the extra locals
// but record the original sp so that we can save it in the skeletal interpreter
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -2730,7 +2730,7 @@
__ movl(rdx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
// Pick up the initial fp we should save
- __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+ __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
// Now adjust the caller's stack to make up for the extra locals
// but record the original sp so that we can save it in the skeletal interpreter
@@ -2922,7 +2922,7 @@
// Pick up the initial fp we should save
__ movptr(rbp,
Address(rdi,
- Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
+ Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
// Now adjust the caller's stack to make up for the extra locals but
// record the original sp so that we can save it in the skeletal
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -2187,7 +2187,7 @@
// either at call sites or otherwise assume that stack unwinding will be initiated,
// so caller saved registers were assumed volatile in the compiler.
address generate_throw_exception(const char* name, address runtime_entry,
- bool restore_saved_exception_pc, Register arg1 = noreg, Register arg2 = noreg) {
+ Register arg1 = noreg, Register arg2 = noreg) {
int insts_size = 256;
int locs_size = 32;
@@ -2204,10 +2204,6 @@
// differently than the real call_VM
Register java_thread = rbx;
__ get_thread(java_thread);
- if (restore_saved_exception_pc) {
- __ movptr(rax, Address(java_thread, in_bytes(JavaThread::saved_exception_pc_offset())));
- __ push(rax);
- }
__ enter(); // required for proper stackwalking of RuntimeStub frame
@@ -2323,7 +2319,7 @@
StubRoutines::_throw_WrongMethodTypeException_entry =
generate_throw_exception("WrongMethodTypeException throw_exception",
CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException),
- false, rax, rcx);
+ rax, rcx);
}
@@ -2332,12 +2328,10 @@
// These entry points require SharedInfo::stack0 to be set up in non-core builds
// and need to be relocatable, so they each fabricate a RuntimeStub internally.
- StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError), false);
- StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false);
- StubRoutines::_throw_ArithmeticException_entry = generate_throw_exception("ArithmeticException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_ArithmeticException), true);
- StubRoutines::_throw_NullPointerException_entry = generate_throw_exception("NullPointerException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true);
- StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
- StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
+ StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
+ StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
+ StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
+ StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
//------------------------------------------------------------------------------------------------------------------------
// entry points that are platform specific
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -935,6 +935,8 @@
__ pusha(); // push registers
Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
+ // FIXME: this probably needs alignment logic
+
__ subptr(rsp, frame::arg_reg_save_area_bytes);
BLOCK_COMMENT("call handle_unsafe_access");
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
@@ -2934,7 +2936,6 @@
// caller saved registers were assumed volatile in the compiler.
address generate_throw_exception(const char* name,
address runtime_entry,
- bool restore_saved_exception_pc,
Register arg1 = noreg,
Register arg2 = noreg) {
// Information about frame layout at time of blocking runtime call.
@@ -2962,12 +2963,6 @@
// which has the ability to fetch the return PC out of
// thread-local storage and also sets up last_Java_sp slightly
// differently than the real call_VM
- if (restore_saved_exception_pc) {
- __ movptr(rax,
- Address(r15_thread,
- in_bytes(JavaThread::saved_exception_pc_offset())));
- __ push(rax);
- }
__ enter(); // required for proper stackwalking of RuntimeStub frame
@@ -3068,7 +3063,7 @@
StubRoutines::_throw_WrongMethodTypeException_entry =
generate_throw_exception("WrongMethodTypeException throw_exception",
CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException),
- false, rax, rcx);
+ rax, rcx);
}
void generate_all() {
@@ -3081,43 +3076,25 @@
generate_throw_exception("AbstractMethodError throw_exception",
CAST_FROM_FN_PTR(address,
SharedRuntime::
- throw_AbstractMethodError),
- false);
+ throw_AbstractMethodError));
StubRoutines::_throw_IncompatibleClassChangeError_entry =
generate_throw_exception("IncompatibleClassChangeError throw_exception",
CAST_FROM_FN_PTR(address,
SharedRuntime::
- throw_IncompatibleClassChangeError),
- false);
-
- StubRoutines::_throw_ArithmeticException_entry =
- generate_throw_exception("ArithmeticException throw_exception",
- CAST_FROM_FN_PTR(address,
- SharedRuntime::
- throw_ArithmeticException),
- true);
-
- StubRoutines::_throw_NullPointerException_entry =
- generate_throw_exception("NullPointerException throw_exception",
- CAST_FROM_FN_PTR(address,
- SharedRuntime::
- throw_NullPointerException),
- true);
+ throw_IncompatibleClassChangeError));
StubRoutines::_throw_NullPointerException_at_call_entry =
generate_throw_exception("NullPointerException at call throw_exception",
CAST_FROM_FN_PTR(address,
SharedRuntime::
- throw_NullPointerException_at_call),
- false);
+ throw_NullPointerException_at_call));
StubRoutines::_throw_StackOverflowError_entry =
generate_throw_exception("StackOverflowError throw_exception",
CAST_FROM_FN_PTR(address,
SharedRuntime::
- throw_StackOverflowError),
- false);
+ throw_StackOverflowError));
// entry points that are platform specific
StubRoutines::x86::_f2i_fixup = generate_f2i_fixup();
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -425,3 +425,9 @@
}
#endif
+
+intptr_t *frame::initial_deoptimization_info() {
+ // unused... but returns fp() to minimize changes introduced by 7087445
+ return fp();
+}
+
--- a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -215,12 +215,6 @@
StubRoutines::_throw_AbstractMethodError_entry =
ShouldNotCallThisStub();
- StubRoutines::_throw_ArithmeticException_entry =
- ShouldNotCallThisStub();
-
- StubRoutines::_throw_NullPointerException_entry =
- ShouldNotCallThisStub();
-
StubRoutines::_throw_NullPointerException_at_call_entry =
ShouldNotCallThisStub();
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -142,7 +142,8 @@
#endif
#ifdef ARM
assert(disp() == 0 || index()->is_illegal(), "can't have both");
- assert(-4096 < disp() && disp() < 4096, "architecture constraint");
+ // Note: offsets higher than 4096 must not be rejected here. They can
+ // be handled by the back-end or will be rejected if not.
#endif
#ifdef _LP64
assert(base()->is_cpu_register(), "wrong base operand");
--- a/hotspot/src/share/vm/ci/ciArrayKlass.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciArrayKlass.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
// This class, and its subclasses represent klassOops in the
// HotSpot virtual machine whose Klass part is an arrayKlass.
class ciArrayKlass : public ciKlass {
+ CI_PACKAGE_ACCESS
private:
jint _dimension;
--- a/hotspot/src/share/vm/ci/ciClassList.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciClassList.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -77,12 +77,14 @@
// Everyone gives access to ciObjectFactory
#define CI_PACKAGE_ACCESS \
-friend class ciObjectFactory;
+friend class ciObjectFactory; \
+friend class VMStructs;
// These are the packages that have access to ciEnv
// Any more access must be given explicitly.
#define CI_PACKAGE_ACCESS_TO \
friend class ciObjectFactory; \
+friend class VMStructs; \
friend class ciCallSite; \
friend class ciConstantPoolCache; \
friend class ciField; \
--- a/hotspot/src/share/vm/ci/ciConstant.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciConstant.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
//
// This class represents a constant value.
class ciConstant VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
private:
friend class ciEnv;
friend class ciField;
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -31,6 +31,7 @@
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/fieldStreams.hpp"
#include "runtime/fieldDescriptor.hpp"
// ciInstanceKlass
@@ -412,7 +413,7 @@
VM_ENTRY_MARK;
ciEnv* curEnv = ciEnv::current();
instanceKlass* ik = get_instanceKlass();
- int max_n_fields = ik->fields()->length()/instanceKlass::next_offset;
+ int max_n_fields = ik->java_fields_count();
Arena* arena = curEnv->arena();
_non_static_fields =
@@ -476,23 +477,6 @@
// Now sort them by offset, ascending.
// (In principle, they could mix with superclass fields.)
fields->sort(sort_field_by_offset);
-#ifdef ASSERT
- int last_offset = instanceOopDesc::base_offset_in_bytes();
- for (int i = 0; i < fields->length(); i++) {
- ciField* field = fields->at(i);
- int offset = field->offset_in_bytes();
- int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes();
- assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset));
- if (last_offset > (int)sizeof(oopDesc))
- assert((offset - last_offset) < BytesPerLong, "no big holes");
- // Note: Two consecutive T_BYTE fields will be separated by wordSize-1
- // padding bytes if one of them is declared by a superclass.
- // This is a minor inefficiency classFileParser.cpp.
- last_offset = offset + size;
- }
- assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow");
-#endif
-
_nonstatic_fields = fields;
return flen;
}
@@ -505,33 +489,29 @@
int flen = 0;
GrowableArray<ciField*>* fields = NULL;
instanceKlass* k = get_instanceKlass();
- typeArrayOop fields_array = k->fields();
- for (int pass = 0; pass <= 1; pass++) {
- for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) {
- fieldDescriptor fd;
- fd.initialize(k->as_klassOop(), i);
- if (fd.is_static()) continue;
- if (pass == 0) {
- flen += 1;
- } else {
- ciField* field = new (arena) ciField(&fd);
- fields->append(field);
- }
- }
+ for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_static()) continue;
+ flen += 1;
+ }
- // Between passes, allocate the array:
- if (pass == 0) {
- if (flen == 0) {
- return NULL; // return nothing if none are locally declared
- }
- if (super_fields != NULL) {
- flen += super_fields->length();
- }
- fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
- if (super_fields != NULL) {
- fields->appendAll(super_fields);
- }
- }
+ // allocate the array:
+ if (flen == 0) {
+ return NULL; // return nothing if none are locally declared
+ }
+ if (super_fields != NULL) {
+ flen += super_fields->length();
+ }
+ fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
+ if (super_fields != NULL) {
+ fields->appendAll(super_fields);
+ }
+
+ for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_static()) continue;
+ fieldDescriptor fd;
+ fd.initialize(k->as_klassOop(), fs.index());
+ ciField* field = new (arena) ciField(&fd);
+ fields->append(field);
}
assert(fields->length() == flen, "sanity");
return fields;
--- a/hotspot/src/share/vm/ci/ciObjectFactory.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -36,6 +36,9 @@
// which ensures that for each oop, at most one ciObject is created.
// This invariant allows efficient implementation of ciObject.
class ciObjectFactory : public ResourceObj {
+ friend class VMStructs;
+ friend class ciEnv;
+
private:
static volatile bool _initialized;
static GrowableArray<ciObject*>* _shared_ci_objects;
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -36,6 +36,7 @@
#include "memory/oopFactory.hpp"
#include "memory/universe.inline.hpp"
#include "oops/constantPoolOop.hpp"
+#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.inline.hpp"
@@ -991,42 +992,98 @@
STATIC_BYTE, // Boolean, Byte, char
STATIC_SHORT, // shorts
STATIC_WORD, // ints
- STATIC_DOUBLE, // long or double
- STATIC_ALIGNED_DOUBLE,// aligned long or double
+ STATIC_DOUBLE, // aligned long or double
NONSTATIC_OOP,
NONSTATIC_BYTE,
NONSTATIC_SHORT,
NONSTATIC_WORD,
NONSTATIC_DOUBLE,
- NONSTATIC_ALIGNED_DOUBLE
+ MAX_FIELD_ALLOCATION_TYPE,
+ BAD_ALLOCATION_TYPE = -1
};
-
-struct FieldAllocationCount {
- unsigned int static_oop_count;
- unsigned int static_byte_count;
- unsigned int static_short_count;
- unsigned int static_word_count;
- unsigned int static_double_count;
- unsigned int nonstatic_oop_count;
- unsigned int nonstatic_byte_count;
- unsigned int nonstatic_short_count;
- unsigned int nonstatic_word_count;
- unsigned int nonstatic_double_count;
+static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = {
+ BAD_ALLOCATION_TYPE, // 0
+ BAD_ALLOCATION_TYPE, // 1
+ BAD_ALLOCATION_TYPE, // 2
+ BAD_ALLOCATION_TYPE, // 3
+ NONSTATIC_BYTE , // T_BOOLEAN = 4,
+ NONSTATIC_SHORT, // T_CHAR = 5,
+ NONSTATIC_WORD, // T_FLOAT = 6,
+ NONSTATIC_DOUBLE, // T_DOUBLE = 7,
+ NONSTATIC_BYTE, // T_BYTE = 8,
+ NONSTATIC_SHORT, // T_SHORT = 9,
+ NONSTATIC_WORD, // T_INT = 10,
+ NONSTATIC_DOUBLE, // T_LONG = 11,
+ NONSTATIC_OOP, // T_OBJECT = 12,
+ NONSTATIC_OOP, // T_ARRAY = 13,
+ BAD_ALLOCATION_TYPE, // T_VOID = 14,
+ BAD_ALLOCATION_TYPE, // T_ADDRESS = 15,
+ BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16,
+ BAD_ALLOCATION_TYPE, // T_CONFLICT = 17,
+ BAD_ALLOCATION_TYPE, // 0
+ BAD_ALLOCATION_TYPE, // 1
+ BAD_ALLOCATION_TYPE, // 2
+ BAD_ALLOCATION_TYPE, // 3
+ STATIC_BYTE , // T_BOOLEAN = 4,
+ STATIC_SHORT, // T_CHAR = 5,
+ STATIC_WORD, // T_FLOAT = 6,
+ STATIC_DOUBLE, // T_DOUBLE = 7,
+ STATIC_BYTE, // T_BYTE = 8,
+ STATIC_SHORT, // T_SHORT = 9,
+ STATIC_WORD, // T_INT = 10,
+ STATIC_DOUBLE, // T_LONG = 11,
+ STATIC_OOP, // T_OBJECT = 12,
+ STATIC_OOP, // T_ARRAY = 13,
+ BAD_ALLOCATION_TYPE, // T_VOID = 14,
+ BAD_ALLOCATION_TYPE, // T_ADDRESS = 15,
+ BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16,
+ BAD_ALLOCATION_TYPE, // T_CONFLICT = 17,
};
-typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface,
- struct FieldAllocationCount *fac,
- objArrayHandle* fields_annotations, TRAPS) {
+static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) {
+ assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values");
+ FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)];
+ assert(result != BAD_ALLOCATION_TYPE, "bad type");
+ return result;
+}
+
+class FieldAllocationCount: public ResourceObj {
+ public:
+ unsigned int count[MAX_FIELD_ALLOCATION_TYPE];
+
+ FieldAllocationCount() {
+ for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) {
+ count[i] = 0;
+ }
+ }
+
+ FieldAllocationType update(bool is_static, BasicType type) {
+ FieldAllocationType atype = basic_type_to_atype(is_static, type);
+ count[atype]++;
+ return atype;
+ }
+};
+
+
+typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
+ constantPoolHandle cp, bool is_interface,
+ FieldAllocationCount *fac,
+ objArrayHandle* fields_annotations,
+ int* java_fields_count_ptr, TRAPS) {
ClassFileStream* cfs = stream();
typeArrayHandle nullHandle;
cfs->guarantee_more(2, CHECK_(nullHandle)); // length
u2 length = cfs->get_u2_fast();
+ *java_fields_count_ptr = length;
+
+ int num_injected = 0;
+ InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected);
+
// Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index]
- typeArrayOop new_fields = oopFactory::new_permanent_shortArray(length*instanceKlass::next_offset, CHECK_(nullHandle));
+ typeArrayOop new_fields = oopFactory::new_permanent_shortArray((length + num_injected) * FieldInfo::field_slots, CHECK_(nullHandle));
typeArrayHandle fields(THREAD, new_fields);
- int index = 0;
typeArrayHandle field_annotations;
for (int n = 0; n < length; n++) {
cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count
@@ -1077,93 +1134,77 @@
}
}
- fields->short_at_put(index++, access_flags.as_short());
- fields->short_at_put(index++, name_index);
- fields->short_at_put(index++, signature_index);
- fields->short_at_put(index++, constantvalue_index);
+ FieldInfo* field = FieldInfo::from_field_array(fields(), n);
+ field->initialize(access_flags.as_short(),
+ name_index,
+ signature_index,
+ constantvalue_index,
+ generic_signature_index,
+ 0);
+
+ BasicType type = cp->basic_type_for_signature_at(signature_index);
// Remember how many oops we encountered and compute allocation type
- BasicType type = cp->basic_type_for_signature_at(signature_index);
- FieldAllocationType atype;
- if ( is_static ) {
- switch ( type ) {
- case T_BOOLEAN:
- case T_BYTE:
- fac->static_byte_count++;
- atype = STATIC_BYTE;
- break;
- case T_LONG:
- case T_DOUBLE:
- if (Universe::field_type_should_be_aligned(type)) {
- atype = STATIC_ALIGNED_DOUBLE;
- } else {
- atype = STATIC_DOUBLE;
- }
- fac->static_double_count++;
- break;
- case T_CHAR:
- case T_SHORT:
- fac->static_short_count++;
- atype = STATIC_SHORT;
- break;
- case T_FLOAT:
- case T_INT:
- fac->static_word_count++;
- atype = STATIC_WORD;
- break;
- case T_ARRAY:
- case T_OBJECT:
- fac->static_oop_count++;
- atype = STATIC_OOP;
- break;
- case T_ADDRESS:
- case T_VOID:
- default:
- assert(0, "bad field type");
- }
- } else {
- switch ( type ) {
- case T_BOOLEAN:
- case T_BYTE:
- fac->nonstatic_byte_count++;
- atype = NONSTATIC_BYTE;
- break;
- case T_LONG:
- case T_DOUBLE:
- if (Universe::field_type_should_be_aligned(type)) {
- atype = NONSTATIC_ALIGNED_DOUBLE;
- } else {
- atype = NONSTATIC_DOUBLE;
- }
- fac->nonstatic_double_count++;
- break;
- case T_CHAR:
- case T_SHORT:
- fac->nonstatic_short_count++;
- atype = NONSTATIC_SHORT;
- break;
- case T_FLOAT:
- case T_INT:
- fac->nonstatic_word_count++;
- atype = NONSTATIC_WORD;
- break;
- case T_ARRAY:
- case T_OBJECT:
- fac->nonstatic_oop_count++;
- atype = NONSTATIC_OOP;
- break;
- case T_ADDRESS:
- case T_VOID:
- default:
- assert(0, "bad field type");
- }
- }
+ FieldAllocationType atype = fac->update(is_static, type);
// The correct offset is computed later (all oop fields will be located together)
// We temporarily store the allocation type in the offset field
- fields->short_at_put(index++, atype);
- fields->short_at_put(index++, 0); // Clear out high word of byte offset
- fields->short_at_put(index++, generic_signature_index);
+ field->set_offset(atype);
+ }
+
+ if (num_injected != 0) {
+ int index = length;
+ for (int n = 0; n < num_injected; n++) {
+ // Check for duplicates
+ if (injected[n].may_be_java) {
+ Symbol* name = injected[n].name();
+ Symbol* signature = injected[n].signature();
+ bool duplicate = false;
+ for (int i = 0; i < length; i++) {
+ FieldInfo* f = FieldInfo::from_field_array(fields(), i);
+ if (name == cp->symbol_at(f->name_index()) &&
+ signature == cp->symbol_at(f->signature_index())) {
+ // Symbol is desclared in Java so skip this one
+ duplicate = true;
+ break;
+ }
+ }
+ if (duplicate) {
+ // These will be removed from the field array at the end
+ continue;
+ }
+ }
+
+ // Injected field
+ FieldInfo* field = FieldInfo::from_field_array(fields(), index);
+ field->initialize(JVM_ACC_FIELD_INTERNAL,
+ injected[n].name_index,
+ injected[n].signature_index,
+ 0,
+ 0,
+ 0);
+
+ BasicType type = FieldType::basic_type(injected[n].signature());
+
+ // Remember how many oops we encountered and compute allocation type
+ FieldAllocationType atype = fac->update(false, type);
+
+ // The correct offset is computed later (all oop fields will be located together)
+ // We temporarily store the allocation type in the offset field
+ field->set_offset(atype);
+ index++;
+ }
+
+ if (index < length + num_injected) {
+ // sometimes injected fields already exist in the Java source so
+ // the fields array could be too long. In that case trim the
+ // fields array.
+ new_fields = oopFactory::new_permanent_shortArray(index * FieldInfo::field_slots, CHECK_(nullHandle));
+ for (int i = 0; i < index * FieldInfo::field_slots; i++) {
+ new_fields->short_at_put(i, fields->short_at(i));
+ }
+ fields = new_fields;
+ }
}
if (_need_verify && length > 1) {
@@ -1175,11 +1216,9 @@
bool dup = false;
{
debug_only(No_Safepoint_Verifier nsv;)
- for (int i = 0; i < length*instanceKlass::next_offset; i += instanceKlass::next_offset) {
- int name_index = fields->ushort_at(i + instanceKlass::name_index_offset);
- Symbol* name = cp->symbol_at(name_index);
- int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset);
- Symbol* sig = cp->symbol_at(sig_index);
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+ Symbol* name = fs.name();
+ Symbol* sig = fs.signature();
// If no duplicates, add name/signature in hashtable names_and_sigs.
if (!put_after_lookup(name, sig, names_and_sigs)) {
dup = true;
@@ -2592,227 +2631,6 @@
}
-void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
- constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) {
- // This code is for compatibility with earlier jdk's that do not
- // have the "discovered" field in java.lang.ref.Reference. For 1.5
- // the check for the "discovered" field should issue a warning if
- // the field is not found. For 1.6 this code should be issue a
- // fatal error if the "discovered" field is not found.
- //
- // Increment fac.nonstatic_oop_count so that the start of the
- // next type of non-static oops leaves room for the fake oop.
- // Do not increment next_nonstatic_oop_offset so that the
- // fake oop is place after the java.lang.ref.Reference oop
- // fields.
- //
- // Check the fields in java.lang.ref.Reference for the "discovered"
- // field. If it is not present, artifically create a field for it.
- // This allows this VM to run on early JDK where the field is not
- // present.
- int reference_sig_index = 0;
- int reference_name_index = 0;
- int reference_index = 0;
- int extra = java_lang_ref_Reference::number_of_fake_oop_fields;
- const int n = (*fields_ptr)()->length();
- for (int i = 0; i < n; i += instanceKlass::next_offset ) {
- int name_index =
- (*fields_ptr)()->ushort_at(i + instanceKlass::name_index_offset);
- int sig_index =
- (*fields_ptr)()->ushort_at(i + instanceKlass::signature_index_offset);
- Symbol* f_name = cp->symbol_at(name_index);
- Symbol* f_sig = cp->symbol_at(sig_index);
- if (f_sig == vmSymbols::reference_signature() && reference_index == 0) {
- // Save the index for reference signature for later use.
- // The fake discovered field does not entries in the
- // constant pool so the index for its signature cannot
- // be extracted from the constant pool. It will need
- // later, however. It's signature is vmSymbols::reference_signature()
- // so same an index for that signature.
- reference_sig_index = sig_index;
- reference_name_index = name_index;
- reference_index = i;
- }
- if (f_name == vmSymbols::reference_discovered_name() &&
- f_sig == vmSymbols::reference_signature()) {
- // The values below are fake but will force extra
- // non-static oop fields and a corresponding non-static
- // oop map block to be allocated.
- extra = 0;
- break;
- }
- }
- if (extra != 0) {
- fac_ptr->nonstatic_oop_count += extra;
- // Add the additional entry to "fields" so that the klass
- // contains the "discoverd" field and the field will be initialized
- // in instances of the object.
- int fields_with_fix_length = (*fields_ptr)()->length() +
- instanceKlass::next_offset;
- typeArrayOop ff = oopFactory::new_permanent_shortArray(
- fields_with_fix_length, CHECK);
- typeArrayHandle fields_with_fix(THREAD, ff);
-
- // Take everything from the original but the length.
- for (int idx = 0; idx < (*fields_ptr)->length(); idx++) {
- fields_with_fix->ushort_at_put(idx, (*fields_ptr)->ushort_at(idx));
- }
-
- // Add the fake field at the end.
- int i = (*fields_ptr)->length();
- // There is no name index for the fake "discovered" field nor
- // signature but a signature is needed so that the field will
- // be properly initialized. Use one found for
- // one of the other reference fields. Be sure the index for the
- // name is 0. In fieldDescriptor::initialize() the index of the
- // name is checked. That check is by passed for the last nonstatic
- // oop field in a java.lang.ref.Reference which is assumed to be
- // this artificial "discovered" field. An assertion checks that
- // the name index is 0.
- assert(reference_index != 0, "Missing signature for reference");
-
- int j;
- for (j = 0; j < instanceKlass::next_offset; j++) {
- fields_with_fix->ushort_at_put(i + j,
- (*fields_ptr)->ushort_at(reference_index +j));
- }
- // Clear the public access flag and set the private access flag.
- short flags;
- flags =
- fields_with_fix->ushort_at(i + instanceKlass::access_flags_offset);
- assert(!(flags & JVM_RECOGNIZED_FIELD_MODIFIERS), "Unexpected access flags set");
- flags = flags & (~JVM_ACC_PUBLIC);
- flags = flags | JVM_ACC_PRIVATE;
- AccessFlags access_flags;
- access_flags.set_flags(flags);
- assert(!access_flags.is_public(), "Failed to clear public flag");
- assert(access_flags.is_private(), "Failed to set private flag");
- fields_with_fix->ushort_at_put(i + instanceKlass::access_flags_offset,
- flags);
-
- assert(fields_with_fix->ushort_at(i + instanceKlass::name_index_offset)
- == reference_name_index, "The fake reference name is incorrect");
- assert(fields_with_fix->ushort_at(i + instanceKlass::signature_index_offset)
- == reference_sig_index, "The fake reference signature is incorrect");
- // The type of the field is stored in the low_offset entry during
- // parsing.
- assert(fields_with_fix->ushort_at(i + instanceKlass::low_offset) ==
- NONSTATIC_OOP, "The fake reference type is incorrect");
-
- // "fields" is allocated in the permanent generation. Disgard
- // it and let it be collected.
- (*fields_ptr) = fields_with_fix;
- }
- return;
-}
-
-
-void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size,
- FieldAllocationCount *fac_ptr) {
- // Add fake fields for java.lang.Class instances
- //
- // This is not particularly nice. We should consider adding a
- // private transient object field at the Java level to
- // java.lang.Class. Alternatively we could add a subclass of
- // instanceKlass which provides an accessor and size computer for
- // this field, but that appears to be more code than this hack.
- //
- // NOTE that we wedge these in at the beginning rather than the
- // end of the object because the Class layout changed between JDK
- // 1.3 and JDK 1.4 with the new reflection implementation; some
- // nonstatic oop fields were added at the Java level. The offsets
- // of these fake fields can't change between these two JDK
- // versions because when the offsets are computed at bootstrap
- // time we don't know yet which version of the JDK we're running in.
-
- // The values below are fake but will force three non-static oop fields and
- // a corresponding non-static oop map block to be allocated.
- const int extra = java_lang_Class::number_of_fake_oop_fields;
- fac_ptr->nonstatic_oop_count += extra;
-
- // Reserve some leading space for fake ints
- *nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize;
-}
-
-
-void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_ptr) {
- // Cause the extra fake fields in java.lang.Class to show up before
- // the Java fields for layout compatibility between 1.3 and 1.4
- // Incrementing next_nonstatic_oop_offset here advances the
- // location where the real java fields are placed.
- const int extra = java_lang_Class::number_of_fake_oop_fields;
- (*next_nonstatic_oop_offset_ptr) += (extra * heapOopSize);
-}
-
-
-// Force MethodHandle.vmentry to be an unmanaged pointer.
-// There is no way for a classfile to express this, so we must help it.
-void ClassFileParser::java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp,
- typeArrayHandle fields,
- FieldAllocationCount *fac_ptr,
- TRAPS) {
- // Add fake fields for java.lang.invoke.MethodHandle instances
- //
- // This is not particularly nice, but since there is no way to express
- // a native wordSize field in Java, we must do it at this level.
-
- if (!EnableInvokeDynamic) return;
-
- int word_sig_index = 0;
- const int cp_size = cp->length();
- for (int index = 1; index < cp_size; index++) {
- if (cp->tag_at(index).is_utf8() &&
- cp->symbol_at(index) == vmSymbols::machine_word_signature()) {
- word_sig_index = index;
- break;
- }
- }
-
- if (word_sig_index == 0)
- THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
- "missing I or J signature (for vmentry) in java.lang.invoke.MethodHandle");
-
- // Find vmentry field and change the signature.
- bool found_vmentry = false;
- for (int i = 0; i < fields->length(); i += instanceKlass::next_offset) {
- int name_index = fields->ushort_at(i + instanceKlass::name_index_offset);
- int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset);
- int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset);
- Symbol* f_name = cp->symbol_at(name_index);
- Symbol* f_sig = cp->symbol_at(sig_index);
- if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) {
- if (f_sig == vmSymbols::machine_word_signature()) {
- // If the signature of vmentry is already changed, we're done.
- found_vmentry = true;
- break;
- }
- else if (f_sig == vmSymbols::byte_signature()) {
- // Adjust the field type from byte to an unmanaged pointer.
- assert(fac_ptr->nonstatic_byte_count > 0, "");
- fac_ptr->nonstatic_byte_count -= 1;
-
- fields->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index);
- assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64");
- if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1;
- else fac_ptr->nonstatic_word_count += 1;
-
- FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
- assert(atype == NONSTATIC_BYTE, "");
- FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD;
- fields->ushort_at_put(i + instanceKlass::low_offset, new_atype);
-
- found_vmentry = true;
- break;
- }
- }
- }
-
- if (!found_vmentry)
- THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
- "missing vmentry byte field in java.lang.invoke.MethodHandle");
-}
-
-
instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
Handle class_loader,
Handle protection_domain,
@@ -3025,10 +2843,13 @@
local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle));
}
+ int java_fields_count = 0;
// Fields (offsets are filled in later)
- struct FieldAllocationCount fac = {0,0,0,0,0,0,0,0,0,0};
+ FieldAllocationCount fac;
objArrayHandle fields_annotations;
- typeArrayHandle fields = parse_fields(cp, access_flags.is_interface(), &fac, &fields_annotations, CHECK_(nullHandle));
+ typeArrayHandle fields = parse_fields(class_name, cp, access_flags.is_interface(), &fac, &fields_annotations,
+ &java_fields_count,
+ CHECK_(nullHandle));
// Methods
bool has_final_method = false;
AccessFlags promoted_flags;
@@ -3146,51 +2967,33 @@
// Calculate the starting byte offsets
next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields();
next_static_double_offset = next_static_oop_offset +
- (fac.static_oop_count * heapOopSize);
- if ( fac.static_double_count &&
+ (fac.count[STATIC_OOP] * heapOopSize);
+ if ( fac.count[STATIC_DOUBLE] &&
(Universe::field_type_should_be_aligned(T_DOUBLE) ||
Universe::field_type_should_be_aligned(T_LONG)) ) {
next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong);
}
next_static_word_offset = next_static_double_offset +
- (fac.static_double_count * BytesPerLong);
+ (fac.count[STATIC_DOUBLE] * BytesPerLong);
next_static_short_offset = next_static_word_offset +
- (fac.static_word_count * BytesPerInt);
+ (fac.count[STATIC_WORD] * BytesPerInt);
next_static_byte_offset = next_static_short_offset +
- (fac.static_short_count * BytesPerShort);
+ (fac.count[STATIC_SHORT] * BytesPerShort);
next_static_type_offset = align_size_up((next_static_byte_offset +
- fac.static_byte_count ), wordSize );
+ fac.count[STATIC_BYTE] ), wordSize );
static_field_size = (next_static_type_offset -
next_static_oop_offset) / wordSize;
- // Add fake fields for java.lang.Class instances (also see below)
- if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
- java_lang_Class_fix_pre(&nonstatic_field_size, &fac);
- }
-
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
nonstatic_field_size * heapOopSize;
next_nonstatic_field_offset = first_nonstatic_field_offset;
- // adjust the vmentry field declaration in java.lang.invoke.MethodHandle
- if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
- java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
- }
-
- // Add a fake "discovered" field if it is not present
- // for compatibility with earlier jdk's.
- if (class_name == vmSymbols::java_lang_ref_Reference()
- && class_loader.is_null()) {
- java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle));
- }
- // end of "discovered" field compactibility fix
-
- unsigned int nonstatic_double_count = fac.nonstatic_double_count;
- unsigned int nonstatic_word_count = fac.nonstatic_word_count;
- unsigned int nonstatic_short_count = fac.nonstatic_short_count;
- unsigned int nonstatic_byte_count = fac.nonstatic_byte_count;
- unsigned int nonstatic_oop_count = fac.nonstatic_oop_count;
+ unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE];
+ unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD];
+ unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT];
+ unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE];
+ unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP];
bool super_has_nonstatic_fields =
(super_klass() != NULL && super_klass->has_nonstatic_fields());
@@ -3210,20 +3013,7 @@
nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
THREAD, unsigned int, nonstatic_oop_count + 1);
- // Add fake fields for java.lang.Class instances (also see above).
- // FieldsAllocationStyle and CompactFields values will be reset to default.
- if(class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
- java_lang_Class_fix_post(&next_nonstatic_field_offset);
- nonstatic_oop_offsets[0] = first_nonstatic_field_offset;
- const uint fake_oop_count = (next_nonstatic_field_offset -
- first_nonstatic_field_offset) / heapOopSize;
- nonstatic_oop_counts[0] = fake_oop_count;
- nonstatic_oop_map_count = 1;
- nonstatic_oop_count -= fake_oop_count;
- first_nonstatic_oop_offset = first_nonstatic_field_offset;
- } else {
- first_nonstatic_oop_offset = 0; // will be set for first oop field
- }
+ first_nonstatic_oop_offset = 0; // will be set for first oop field
#ifndef PRODUCT
if( PrintCompactFieldsSavings ) {
@@ -3378,10 +3168,9 @@
// Iterate over fields again and compute correct offsets.
// The field allocation type was temporarily stored in the offset slot.
// oop fields are located before non-oop fields (static and non-static).
- int len = fields->length();
- for (int i = 0; i < len; i += instanceKlass::next_offset) {
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
int real_offset;
- FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
+ FieldAllocationType atype = (FieldAllocationType) fs.offset();
switch (atype) {
case STATIC_OOP:
real_offset = next_static_oop_offset;
@@ -3399,7 +3188,6 @@
real_offset = next_static_word_offset;
next_static_word_offset += BytesPerInt;
break;
- case STATIC_ALIGNED_DOUBLE:
case STATIC_DOUBLE:
real_offset = next_static_double_offset;
next_static_double_offset += BytesPerLong;
@@ -3461,7 +3249,6 @@
next_nonstatic_word_offset += BytesPerInt;
}
break;
- case NONSTATIC_ALIGNED_DOUBLE:
case NONSTATIC_DOUBLE:
real_offset = next_nonstatic_double_offset;
next_nonstatic_double_offset += BytesPerLong;
@@ -3469,8 +3256,7 @@
default:
ShouldNotReachHere();
}
- fields->short_at_put(i + instanceKlass::low_offset, extract_low_short_from_int(real_offset));
- fields->short_at_put(i + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
+ fs.set_offset(real_offset);
}
// Size of instances
@@ -3517,12 +3303,12 @@
this_klass->set_class_loader(class_loader());
this_klass->set_nonstatic_field_size(nonstatic_field_size);
this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
- this_klass->set_static_oop_field_count(fac.static_oop_count);
+ this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]);
cp->set_pool_holder(this_klass());
error_handler.set_in_error(false); // turn off error handler for cp
this_klass->set_constants(cp());
this_klass->set_local_interfaces(local_interfaces());
- this_klass->set_fields(fields());
+ this_klass->set_fields(fields(), java_fields_count);
this_klass->set_methods(methods());
if (has_final_method) {
this_klass->set_has_final_method();
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -33,6 +33,9 @@
#include "utilities/accessFlags.hpp"
class TempNewSymbol;
+class FieldAllocationCount;
+
+
// Parser for for .class files
//
// The bytes describing the class file structure is read from a Stream object
@@ -84,9 +87,11 @@
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
typeArrayHandle* field_annotations, TRAPS);
- typeArrayHandle parse_fields(constantPoolHandle cp, bool is_interface,
- struct FieldAllocationCount *fac,
- objArrayHandle* fields_annotations, TRAPS);
+ typeArrayHandle parse_fields(Symbol* class_name,
+ constantPoolHandle cp, bool is_interface,
+ FieldAllocationCount *fac,
+ objArrayHandle* fields_annotations,
+ int* java_fields_count_ptr, TRAPS);
// Method parsing
methodHandle parse_method(constantPoolHandle cp, bool is_interface,
@@ -150,25 +155,6 @@
objArrayHandle compute_transitive_interfaces(instanceKlassHandle super,
objArrayHandle local_ifs, TRAPS);
- // Special handling for certain classes.
- // Add the "discovered" field to java.lang.ref.Reference if
- // it does not exist.
- void java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
- constantPoolHandle cp,
- FieldAllocationCount *fac_ptr, TRAPS);
- // Adjust the field allocation counts for java.lang.Class to add
- // fake fields.
- void java_lang_Class_fix_pre(int* nonstatic_field_size,
- FieldAllocationCount *fac_ptr);
- // Adjust the next_nonstatic_oop_offset to place the fake fields
- // before any Java fields.
- void java_lang_Class_fix_post(int* next_nonstatic_oop_offset);
- // Adjust the field allocation counts for java.lang.invoke.MethodHandle to add
- // a fake address (void*) field.
- void java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp,
- typeArrayHandle fields,
- FieldAllocationCount *fac_ptr, TRAPS);
-
// Format checker methods
void classfile_parse_error(const char* msg, TRAPS);
void classfile_parse_error(const char* msg, int index, TRAPS);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -33,6 +33,7 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
+#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.hpp"
@@ -58,6 +59,49 @@
# include "thread_windows.inline.hpp"
#endif
+#define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \
+ klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum);
+
+#define DECLARE_INJECTED_FIELD(klass, name, signature, may_be_java) \
+ { SystemDictionary::WK_KLASS_ENUM_NAME(klass), vmSymbols::VM_SYMBOL_ENUM_NAME(name##_name), vmSymbols::VM_SYMBOL_ENUM_NAME(signature), may_be_java },
+
+InjectedField JavaClasses::_injected_fields[] = {
+ ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD)
+};
+
+int JavaClasses::compute_injected_offset(InjectedFieldID id) {
+ return _injected_fields[id].compute_offset();
+}
+
+
+InjectedField* JavaClasses::get_injected(Symbol* class_name, int* field_count) {
+ *field_count = 0;
+
+ vmSymbols::SID sid = vmSymbols::find_sid(class_name);
+ if (sid == vmSymbols::NO_SID) {
+ // Only well known classes can inject fields
+ return NULL;
+ }
+
+ int count = 0;
+ int start = -1;
+
+#define LOOKUP_INJECTED_FIELD(klass, name, signature, may_be_java) \
+ if (sid == vmSymbols::VM_SYMBOL_ENUM_NAME(klass)) { \
+ count++; \
+ if (start == -1) start = klass##_##name##_enum; \
+ }
+ ALL_INJECTED_FIELDS(LOOKUP_INJECTED_FIELD);
+#undef LOOKUP_INJECTED_FIELD
+
+ if (start != -1) {
+ *field_count = count;
+ return _injected_fields + start;
+ }
+ return NULL;
+}
+
+
static bool find_field(instanceKlass* ik,
Symbol* name_symbol, Symbol* signature_symbol,
fieldDescriptor* fd,
@@ -428,24 +472,19 @@
}
-// During bootstrap, java.lang.Class wasn't loaded so static field
-// offsets were computed without the size added it. Go back and
-// update all the static field offsets to included the size.
-static void fixup_static_field(fieldDescriptor* fd, TRAPS) {
- if (fd->is_static()) {
- int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields();
- typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields();
- fields->short_at_put(fd->index() + instanceKlass::low_offset, extract_low_short_from_int(real_offset));
- fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
- }
-}
-
void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already");
if (k->oop_is_instance()) {
- // Fixup the offsets
- instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK);
+ // During bootstrap, java.lang.Class wasn't loaded so static field
+ // offsets were computed without the size added it. Go back and
+ // update all the static field offsets to included the size.
+ for (JavaFieldStream fs(instanceKlass::cast(k())); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_static()) {
+ int real_offset = fs.offset() + instanceMirrorKlass::offset_of_static_fields();
+ fs.set_offset(real_offset);
+ }
+ }
}
create_mirror(k, CHECK);
}
@@ -462,7 +501,7 @@
// Allocate mirror (java.lang.Class instance)
Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
// Setup indirections
- mirror->obj_field_put(klass_offset, k());
+ mirror->obj_field_put(_klass_offset, k());
k->set_java_mirror(mirror());
instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass());
@@ -504,25 +543,22 @@
int java_lang_Class::oop_size(oop java_class) {
- assert(oop_size_offset != 0, "must be set");
- return java_class->int_field(oop_size_offset);
+ assert(_oop_size_offset != 0, "must be set");
+ return java_class->int_field(_oop_size_offset);
}
void java_lang_Class::set_oop_size(oop java_class, int size) {
- assert(oop_size_offset != 0, "must be set");
- java_class->int_field_put(oop_size_offset, size);
+ assert(_oop_size_offset != 0, "must be set");
+ java_class->int_field_put(_oop_size_offset, size);
}
int java_lang_Class::static_oop_field_count(oop java_class) {
- assert(static_oop_field_count_offset != 0, "must be set");
- return java_class->int_field(static_oop_field_count_offset);
+ assert(_static_oop_field_count_offset != 0, "must be set");
+ return java_class->int_field(_static_oop_field_count_offset);
}
void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
- assert(static_oop_field_count_offset != 0, "must be set");
- java_class->int_field_put(static_oop_field_count_offset, size);
+ assert(_static_oop_field_count_offset != 0, "must be set");
+ java_class->int_field_put(_static_oop_field_count_offset, size);
}
-
-
-
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
// This should be improved by adding a field at the Java level or by
// introducing a new VM klass (see comment in ClassFileParser)
@@ -542,7 +578,7 @@
klassOop java_lang_Class::as_klassOop(oop java_class) {
//%note memory_2
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
- klassOop k = klassOop(java_class->obj_field(klass_offset));
+ klassOop k = klassOop(java_class->obj_field(_klass_offset));
assert(k == NULL || k->is_klass(), "type check");
return k;
}
@@ -598,7 +634,7 @@
klassOop java_lang_Class::array_klass(oop java_class) {
- klassOop k = klassOop(java_class->obj_field(array_klass_offset));
+ klassOop k = klassOop(java_class->obj_field(_array_klass_offset));
assert(k == NULL || k->is_klass() && Klass::cast(k)->oop_is_javaArray(), "should be array klass");
return k;
}
@@ -606,12 +642,12 @@
void java_lang_Class::set_array_klass(oop java_class, klassOop klass) {
assert(klass->is_klass() && Klass::cast(klass)->oop_is_javaArray(), "should be array klass");
- java_class->obj_field_put(array_klass_offset, klass);
+ java_class->obj_field_put(_array_klass_offset, klass);
}
methodOop java_lang_Class::resolved_constructor(oop java_class) {
- oop constructor = java_class->obj_field(resolved_constructor_offset);
+ oop constructor = java_class->obj_field(_resolved_constructor_offset);
assert(constructor == NULL || constructor->is_method(), "should be method");
return methodOop(constructor);
}
@@ -619,21 +655,21 @@
void java_lang_Class::set_resolved_constructor(oop java_class, methodOop constructor) {
assert(constructor->is_method(), "should be method");
- java_class->obj_field_put(resolved_constructor_offset, constructor);
+ java_class->obj_field_put(_resolved_constructor_offset, constructor);
}
bool java_lang_Class::is_primitive(oop java_class) {
// should assert:
//assert(java_lang_Class::is_instance(java_class), "must be a Class object");
- klassOop k = klassOop(java_class->obj_field(klass_offset));
+ klassOop k = klassOop(java_class->obj_field(_klass_offset));
return k == NULL;
}
BasicType java_lang_Class::primitive_type(oop java_class) {
assert(java_lang_Class::is_primitive(java_class), "just checking");
- klassOop ak = klassOop(java_class->obj_field(array_klass_offset));
+ klassOop ak = klassOop(java_class->obj_field(_array_klass_offset));
BasicType type = T_VOID;
if (ak != NULL) {
// Note: create_basic_type_mirror above initializes ak to a non-null value.
@@ -668,34 +704,18 @@
bool java_lang_Class::offsets_computed = false;
int java_lang_Class::classRedefinedCount_offset = -1;
-int java_lang_Class::parallelCapable_offset = -1;
void java_lang_Class::compute_offsets() {
assert(!offsets_computed, "offsets should be initialized only once");
offsets_computed = true;
- klassOop k = SystemDictionary::Class_klass();
+ klassOop klass_oop = SystemDictionary::Class_klass();
// The classRedefinedCount field is only present starting in 1.5,
// so don't go fatal.
compute_optional_offset(classRedefinedCount_offset,
- k, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature());
-
- // The field indicating parallelCapable (parallelLockMap) is only present starting in 7,
- klassOop k1 = SystemDictionary::ClassLoader_klass();
- compute_optional_offset(parallelCapable_offset,
- k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature());
-}
-
-// For class loader classes, parallelCapable defined
-// based on non-null field
-// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it
-bool java_lang_Class::parallelCapable(oop class_loader) {
- if (!JDK_Version::is_gte_jdk17x_version()
- || parallelCapable_offset == -1) {
- // Default for backward compatibility is false
- return false;
- }
- return (class_loader->obj_field(parallelCapable_offset) != NULL);
+ klass_oop, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature());
+
+ CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
int java_lang_Class::classRedefinedCount(oop the_class_mirror) {
@@ -2308,7 +2328,6 @@
int java_lang_invoke_MethodHandle::_type_offset;
int java_lang_invoke_MethodHandle::_vmtarget_offset;
int java_lang_invoke_MethodHandle::_vmentry_offset;
-int java_lang_invoke_MethodHandle::_vmslots_offset;
int java_lang_invoke_MemberName::_clazz_offset;
int java_lang_invoke_MemberName::_name_offset;
@@ -2327,35 +2346,30 @@
int java_lang_invoke_CountingMethodHandle::_vmcount_offset;
void java_lang_invoke_MethodHandle::compute_offsets() {
- klassOop k = SystemDictionary::MethodHandle_klass();
- if (k != NULL && EnableInvokeDynamic) {
+ klassOop klass_oop = SystemDictionary::MethodHandle_klass();
+ if (klass_oop != NULL && EnableInvokeDynamic) {
bool allow_super = false;
- compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
- compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), allow_super);
- compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), allow_super);
-
- // Note: MH.vmslots (if it is present) is a hoisted copy of MH.type.form.vmslots.
- // It is optional pending experiments to keep or toss.
- compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), allow_super);
+ compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
+ METHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
}
void java_lang_invoke_MemberName::compute_offsets() {
- klassOop k = SystemDictionary::MemberName_klass();
- if (k != NULL && EnableInvokeDynamic) {
- compute_offset(_clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature());
- compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature());
- compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::object_signature());
- compute_offset(_flags_offset, k, vmSymbols::flags_name(), vmSymbols::int_signature());
- compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature());
- compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature());
+ klassOop klass_oop = SystemDictionary::MemberName_klass();
+ if (klass_oop != NULL && EnableInvokeDynamic) {
+ compute_offset(_clazz_offset, klass_oop, vmSymbols::clazz_name(), vmSymbols::class_signature());
+ compute_offset(_name_offset, klass_oop, vmSymbols::name_name(), vmSymbols::string_signature());
+ compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::object_signature());
+ compute_offset(_flags_offset, klass_oop, vmSymbols::flags_name(), vmSymbols::int_signature());
+ compute_offset(_vmindex_offset, klass_oop, vmSymbols::vmindex_name(), vmSymbols::int_signature());
+ MEMBERNAME_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
}
void java_lang_invoke_DirectMethodHandle::compute_offsets() {
klassOop k = SystemDictionary::DirectMethodHandle_klass();
if (k != NULL && EnableInvokeDynamic) {
- compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature(), true);
+ DIRECTMETHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
}
@@ -2399,31 +2413,9 @@
mh->obj_field_put(_type_offset, mtype);
}
-int java_lang_invoke_MethodHandle::vmslots(oop mh) {
- int vmslots_offset = _vmslots_offset;
- if (vmslots_offset != 0) {
-#ifdef ASSERT
- int x = mh->int_field(vmslots_offset);
- int y = compute_vmslots(mh);
- assert(x == y, "correct hoisted value");
-#endif
- return mh->int_field(vmslots_offset);
- } else {
- return compute_vmslots(mh);
- }
-}
-
-// if MH.vmslots exists, hoist into it the value of type.form.vmslots
-void java_lang_invoke_MethodHandle::init_vmslots(oop mh) {
- int vmslots_offset = _vmslots_offset;
- if (vmslots_offset != 0) {
- mh->int_field_put(vmslots_offset, compute_vmslots(mh));
- }
-}
-
// fetch type.form.vmslots, which is the number of JVM stack slots
// required to carry the arguments of this MH
-int java_lang_invoke_MethodHandle::compute_vmslots(oop mh) {
+int java_lang_invoke_MethodHandle::vmslots(oop mh) {
oop mtype = type(mh);
if (mtype == NULL) return 0; // Java code would get NPE
oop form = java_lang_invoke_MethodType::form(mtype);
@@ -2643,6 +2635,7 @@
compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true);
compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true);
if (_genericInvoker_offset == 0) _genericInvoker_offset = -1; // set to explicit "empty" value
+ METHODTYPEFORM_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
}
@@ -2707,14 +2700,6 @@
}
}
-oop java_lang_invoke_CallSite::target(oop site) {
- return site->obj_field(_target_offset);
-}
-
-void java_lang_invoke_CallSite::set_target(oop site, oop target) {
- site->obj_field_put(_target_offset, target);
-}
-
// Support for java_security_AccessControlContext
@@ -2759,6 +2744,18 @@
// Support for java_lang_ClassLoader
+bool java_lang_ClassLoader::offsets_computed = false;
+int java_lang_ClassLoader::parallelCapable_offset = -1;
+
+void java_lang_ClassLoader::compute_offsets() {
+ assert(!offsets_computed, "offsets should be initialized only once");
+ offsets_computed = true;
+
+ // The field indicating parallelCapable (parallelLockMap) is only present starting in 7,
+ klassOop k1 = SystemDictionary::ClassLoader_klass();
+ compute_optional_offset(parallelCapable_offset,
+ k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature());
+}
oop java_lang_ClassLoader::parent(oop loader) {
assert(loader->is_oop(), "loader must be oop");
@@ -2766,6 +2763,18 @@
}
+// For class loader classes, parallelCapable defined
+// based on non-null field
+// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it
+bool java_lang_ClassLoader::parallelCapable(oop class_loader) {
+ if (!JDK_Version::is_gte_jdk17x_version()
+ || parallelCapable_offset == -1) {
+ // Default for backward compatibility is false
+ return false;
+ }
+ return (class_loader->obj_field(parallelCapable_offset) != NULL);
+}
+
bool java_lang_ClassLoader::is_trusted_loader(oop loader) {
// Fix for 4474172; see evaluation for more details
loader = non_reflection_class_loader(loader);
@@ -2815,12 +2824,11 @@
int java_lang_String::offset_offset;
int java_lang_String::count_offset;
int java_lang_String::hash_offset;
-int java_lang_Class::klass_offset;
-int java_lang_Class::array_klass_offset;
-int java_lang_Class::resolved_constructor_offset;
-int java_lang_Class::number_of_fake_oop_fields;
-int java_lang_Class::oop_size_offset;
-int java_lang_Class::static_oop_field_count_offset;
+int java_lang_Class::_klass_offset;
+int java_lang_Class::_array_klass_offset;
+int java_lang_Class::_resolved_constructor_offset;
+int java_lang_Class::_oop_size_offset;
+int java_lang_Class::_static_oop_field_count_offset;
int java_lang_Throwable::backtrace_offset;
int java_lang_Throwable::detailMessage_offset;
int java_lang_Throwable::cause_offset;
@@ -2933,20 +2941,20 @@
void java_nio_Buffer::compute_offsets() {
- klassOop k = SystemDictionary::java_nio_Buffer_klass();
+ klassOop k = SystemDictionary::nio_Buffer_klass();
assert(k != NULL, "must be loaded in 1.4+");
compute_offset(_limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature());
}
// Support for intrinsification of sun.misc.AtomicLongCSImpl.attemptUpdate
int sun_misc_AtomicLongCSImpl::value_offset() {
- assert(SystemDictionary::sun_misc_AtomicLongCSImpl_klass() != NULL, "can't call this");
+ assert(SystemDictionary::AtomicLongCSImpl_klass() != NULL, "can't call this");
return _value_offset;
}
void sun_misc_AtomicLongCSImpl::compute_offsets() {
- klassOop k = SystemDictionary::sun_misc_AtomicLongCSImpl_klass();
+ klassOop k = SystemDictionary::AtomicLongCSImpl_klass();
// If this class is not present, its value field offset won't be referenced.
if (k != NULL) {
compute_offset(_value_offset, k, vmSymbols::value_name(), vmSymbols::long_signature());
@@ -2981,23 +2989,6 @@
java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint);
java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint);
- {
- // Do the Class Class
- int offset = header;
- java_lang_Class::oop_size_offset = header;
- offset += BytesPerInt;
- java_lang_Class::static_oop_field_count_offset = offset;
- offset = align_size_up(offset + BytesPerInt, x);
- java_lang_Class::klass_offset = offset;
- offset += x;
- java_lang_Class::array_klass_offset = offset;
- offset += x;
- java_lang_Class::resolved_constructor_offset = offset;
- }
-
- // This is NOT an offset
- java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields;
-
// Throwable Class
java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header;
java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
@@ -3049,8 +3040,8 @@
// Compute non-hard-coded field offsets of all the classes in this file
void JavaClasses::compute_offsets() {
-
- java_lang_Class::compute_offsets();
+ // java_lang_Class::compute_offsets was called earlier in bootstrap
+ java_lang_ClassLoader::compute_offsets();
java_lang_Thread::compute_offsets();
java_lang_ThreadGroup::compute_offsets();
if (EnableInvokeDynamic) {
@@ -3275,6 +3266,23 @@
#endif // PRODUCT
+int InjectedField::compute_offset() {
+ klassOop klass_oop = klass();
+ for (AllFieldStream fs(instanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+ if (!may_be_java && !fs.access_flags().is_internal()) {
+ // Only look at injected fields
+ continue;
+ }
+ if (fs.name() == name() && fs.signature() == signature()) {
+ return fs.offset();
+ }
+ }
+ ResourceMark rm;
+ tty->print_cr("Invalid layout of %s at %s", instanceKlass::cast(klass_oop)->external_name(), name()->as_C_string());
+ fatal("Invalid layout of preloaded class");
+ return -1;
+}
+
void javaClasses_init() {
JavaClasses::compute_offsets();
JavaClasses::check_offsets();
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -156,30 +156,32 @@
// Interface to java.lang.Class objects
+#define CLASS_INJECTED_FIELDS(macro) \
+ macro(java_lang_Class, klass, object_signature, false) \
+ macro(java_lang_Class, resolved_constructor, object_signature, false) \
+ macro(java_lang_Class, array_klass, object_signature, false) \
+ macro(java_lang_Class, oop_size, int_signature, false) \
+ macro(java_lang_Class, static_oop_field_count, int_signature, false)
+
class java_lang_Class : AllStatic {
- friend class VMStructs;
+ friend class VMStructs;
+
private:
// The fake offsets are added by the class loader when java.lang.Class is loaded
- enum {
- hc_number_of_fake_oop_fields = 3,
- hc_number_of_fake_int_fields = 2
- };
+ static int _klass_offset;
+ static int _resolved_constructor_offset;
+ static int _array_klass_offset;
- static int klass_offset;
- static int resolved_constructor_offset;
- static int array_klass_offset;
- static int number_of_fake_oop_fields;
+ static int _oop_size_offset;
+ static int _static_oop_field_count_offset;
- static int oop_size_offset;
- static int static_oop_field_count_offset;
-
- static void compute_offsets();
static bool offsets_computed;
static int classRedefinedCount_offset;
- static int parallelCapable_offset;
public:
+ static void compute_offsets();
+
// Instance creation
static oop create_mirror(KlassHandle k, TRAPS);
static void fixup_mirror(KlassHandle k, TRAPS);
@@ -209,14 +211,12 @@
static klassOop array_klass(oop java_class);
static void set_array_klass(oop java_class, klassOop klass);
// compiler support for class operations
- static int klass_offset_in_bytes() { return klass_offset; }
- static int resolved_constructor_offset_in_bytes() { return resolved_constructor_offset; }
- static int array_klass_offset_in_bytes() { return array_klass_offset; }
+ static int klass_offset_in_bytes() { return _klass_offset; }
+ static int resolved_constructor_offset_in_bytes() { return _resolved_constructor_offset; }
+ static int array_klass_offset_in_bytes() { return _array_klass_offset; }
// Support for classRedefinedCount field
static int classRedefinedCount(oop the_class_mirror);
static void set_classRedefinedCount(oop the_class_mirror, int value);
- // Support for parallelCapable field
- static bool parallelCapable(oop the_class_mirror);
static int oop_size(oop java_class);
static void set_oop_size(oop java_class, int size);
@@ -771,7 +771,7 @@
ref->obj_field_put(referent_offset, value);
}
static void set_referent_raw(oop ref, oop value) {
- ref->obj_field_raw_put(referent_offset, value);
+ ref->obj_field_put_raw(referent_offset, value);
}
static HeapWord* referent_addr(oop ref) {
return ref->obj_field_addr<HeapWord>(referent_offset);
@@ -783,7 +783,7 @@
ref->obj_field_put(next_offset, value);
}
static void set_next_raw(oop ref, oop value) {
- ref->obj_field_raw_put(next_offset, value);
+ ref->obj_field_put_raw(next_offset, value);
}
static HeapWord* next_addr(oop ref) {
return ref->obj_field_addr<HeapWord>(next_offset);
@@ -795,7 +795,7 @@
ref->obj_field_put(discovered_offset, value);
}
static void set_discovered_raw(oop ref, oop value) {
- ref->obj_field_raw_put(discovered_offset, value);
+ ref->obj_field_put_raw(discovered_offset, value);
}
static HeapWord* discovered_addr(oop ref) {
return ref->obj_field_addr<HeapWord>(discovered_offset);
@@ -834,16 +834,19 @@
// Interface to java.lang.invoke.MethodHandle objects
+#define METHODHANDLE_INJECTED_FIELDS(macro) \
+ macro(java_lang_invoke_MethodHandle, vmentry, intptr_signature, false) \
+ macro(java_lang_invoke_MethodHandle, vmtarget, object_signature, true)
+
class MethodHandleEntry;
class java_lang_invoke_MethodHandle: AllStatic {
friend class JavaClasses;
private:
- static int _vmentry_offset; // assembly code trampoline for MH
- static int _vmtarget_offset; // class-specific target reference
+ static int _vmentry_offset; // assembly code trampoline for MH
+ static int _vmtarget_offset; // class-specific target reference
static int _type_offset; // the MethodType of this MH
- static int _vmslots_offset; // OPTIONAL hoisted type.form.vmslots
static void compute_offsets();
@@ -859,8 +862,6 @@
static void set_vmentry(oop mh, MethodHandleEntry* data);
static int vmslots(oop mh);
- static void init_vmslots(oop mh);
- static int compute_vmslots(oop mh);
// Testers
static bool is_subclass(klassOop klass) {
@@ -874,14 +875,15 @@
static int type_offset_in_bytes() { return _type_offset; }
static int vmtarget_offset_in_bytes() { return _vmtarget_offset; }
static int vmentry_offset_in_bytes() { return _vmentry_offset; }
- static int vmslots_offset_in_bytes() { return _vmslots_offset; }
};
+#define DIRECTMETHODHANDLE_INJECTED_FIELDS(macro) \
+ macro(java_lang_invoke_DirectMethodHandle, vmindex, int_signature, true)
+
class java_lang_invoke_DirectMethodHandle: public java_lang_invoke_MethodHandle {
friend class JavaClasses;
private:
- // _vmtarget_offset; // method or class or interface
static int _vmindex_offset; // negative or vtable idx or itable idx
static void compute_offsets();
@@ -1012,6 +1014,9 @@
// Interface to java.lang.invoke.MemberName objects
// (These are a private interface for Java code to query the class hierarchy.)
+#define MEMBERNAME_INJECTED_FIELDS(macro) \
+ macro(java_lang_invoke_MemberName, vmtarget, object_signature, true)
+
class java_lang_invoke_MemberName: AllStatic {
friend class JavaClasses;
@@ -1121,6 +1126,10 @@
static int form_offset_in_bytes() { return _form_offset; }
};
+#define METHODTYPEFORM_INJECTED_FIELDS(macro) \
+ macro(java_lang_invoke_MethodTypeForm, vmslots, int_signature, true) \
+ macro(java_lang_invoke_MethodTypeForm, vmlayout, object_signature, true)
+
class java_lang_invoke_MethodTypeForm: AllStatic {
friend class JavaClasses;
@@ -1135,6 +1144,8 @@
public:
// Accessors
static int vmslots(oop mtform);
+ static void set_vmslots(oop mtform, int vmslots);
+
static oop erasedType(oop mtform);
static oop genericInvoker(oop mtform);
@@ -1156,21 +1167,16 @@
private:
static int _target_offset;
- static int _caller_method_offset;
- static int _caller_bci_offset;
static void compute_offsets();
public:
// Accessors
- static oop target(oop site);
- static void set_target(oop site, oop target);
+ static oop target( oop site) { return site->obj_field( _target_offset); }
+ static void set_target( oop site, oop target) { site->obj_field_put( _target_offset, target); }
- static oop caller_method(oop site);
- static void set_caller_method(oop site, oop ref);
-
- static jint caller_bci(oop site);
- static void set_caller_bci(oop site, jint bci);
+ static volatile oop target_volatile(oop site) { return site->obj_field_volatile( _target_offset); }
+ static void set_target_volatile(oop site, oop target) { site->obj_field_put_volatile(_target_offset, target); }
// Testers
static bool is_subclass(klassOop klass) {
@@ -1182,8 +1188,6 @@
// Accessors for code generation:
static int target_offset_in_bytes() { return _target_offset; }
- static int caller_method_offset_in_bytes() { return _caller_method_offset; }
- static int caller_bci_offset_in_bytes() { return _caller_bci_offset; }
};
@@ -1214,11 +1218,18 @@
hc_parent_offset = 0
};
+ static bool offsets_computed;
static int parent_offset;
+ static int parallelCapable_offset;
+
+ static void compute_offsets();
public:
static oop parent(oop loader);
+ // Support for parallelCapable field
+ static bool parallelCapable(oop the_class_mirror);
+
static bool is_trusted_loader(oop loader);
// Fix for 4474172
@@ -1340,17 +1351,71 @@
static oop get_owner_threadObj(oop obj);
};
+// Use to declare fields that need to be injected into Java classes
+// for the JVM to use. The name_index and signature_index are
+// declared in vmSymbols. The may_be_java flag is used to declare
+// fields that might already exist in Java but should be injected if
+// they don't. Otherwise the field is unconditionally injected and
+// the JVM uses the injected one. This is to ensure that name
+// collisions don't occur. In general may_be_java should be false
+// unless there's a good reason.
+
+class InjectedField {
+ public:
+ const SystemDictionary::WKID klass_id;
+ const vmSymbols::SID name_index;
+ const vmSymbols::SID signature_index;
+ const bool may_be_java;
+
+
+ klassOop klass() const { return SystemDictionary::well_known_klass(klass_id); }
+ Symbol* name() const { return lookup_symbol(name_index); }
+ Symbol* signature() const { return lookup_symbol(signature_index); }
+
+ int compute_offset();
+
+ // Find the Symbol for this index
+ static Symbol* lookup_symbol(int symbol_index) {
+ return vmSymbols::symbol_at((vmSymbols::SID)symbol_index);
+ }
+};
+
+#define DECLARE_INJECTED_FIELD_ENUM(klass, name, signature, may_be_java) \
+ klass##_##name##_enum,
+
+#define ALL_INJECTED_FIELDS(macro) \
+ CLASS_INJECTED_FIELDS(macro) \
+ METHODHANDLE_INJECTED_FIELDS(macro) \
+ DIRECTMETHODHANDLE_INJECTED_FIELDS(macro) \
+ MEMBERNAME_INJECTED_FIELDS(macro) \
+ METHODTYPEFORM_INJECTED_FIELDS(macro)
+
// Interface to hard-coded offset checking
class JavaClasses : AllStatic {
private:
+
+ static InjectedField _injected_fields[];
+
static bool check_offset(const char *klass_name, int offset, const char *field_name, const char* field_sig) PRODUCT_RETURN0;
static bool check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) PRODUCT_RETURN0;
static bool check_constant(const char *klass_name, int constant, const char *field_name, const char* field_sig) PRODUCT_RETURN0;
+
public:
+ enum InjectedFieldID {
+ ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD_ENUM)
+ MAX_enum
+ };
+
+ static int compute_injected_offset(InjectedFieldID id);
+
static void compute_hard_coded_offsets();
static void compute_offsets();
static void check_offsets() PRODUCT_RETURN;
+
+ static InjectedField* get_injected(Symbol* class_name, int* field_count);
};
+#undef DECLARE_INJECTED_FIELD_ENUM
+
#endif // SHARE_VM_CLASSFILE_JAVACLASSES_HPP
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -125,13 +125,13 @@
bool SystemDictionary::is_parallelCapable(Handle class_loader) {
if (UnsyncloadClass || class_loader.is_null()) return true;
if (AlwaysLockClassLoader) return false;
- return java_lang_Class::parallelCapable(class_loader());
+ return java_lang_ClassLoader::parallelCapable(class_loader());
}
// ----------------------------------------------------------------------------
// ParallelDefineClass flag does not apply to bootclass loader
bool SystemDictionary::is_parallelDefine(Handle class_loader) {
if (class_loader.is_null()) return false;
- if (AllowParallelDefineClass && java_lang_Class::parallelCapable(class_loader())) {
+ if (AllowParallelDefineClass && java_lang_ClassLoader::parallelCapable(class_loader())) {
return true;
}
return false;
@@ -1290,7 +1290,7 @@
Symbol* class_name,
TRAPS) {
- klassOop dlm = SystemDictionary::sun_jkernel_DownloadManager_klass();
+ klassOop dlm = SystemDictionary::DownloadManager_klass();
instanceKlassHandle nk;
// If download manager class isn't loaded just return.
@@ -1953,7 +1953,7 @@
// first do Object, String, Class
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
- debug_only(instanceKlass::verify_class_klass_nonstatic_oop_maps(WK_KLASS(Class_klass)));
+ java_lang_Class::compute_offsets();
// Fixup mirrors for classes loaded before java.lang.Class.
// These calls iterate over the objects currently in the perm gen
@@ -2001,7 +2001,7 @@
//_box_klasses[T_ARRAY] = WK_KLASS(object_klass);
#ifdef KERNEL
- if (sun_jkernel_DownloadManager_klass() == NULL) {
+ if (DownloadManager_klass() == NULL) {
warning("Cannot find sun/jkernel/DownloadManager");
}
#endif // KERNEL
@@ -2736,7 +2736,7 @@
class_size += ik->local_interfaces()->size();
class_size += ik->transitive_interfaces()->size();
// We do not have to count implementors, since we only store one!
- class_size += ik->fields()->size();
+ class_size += ik->all_fields_count() * FieldInfo::field_slots;
}
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -133,15 +133,15 @@
template(reflect_Method_klass, java_lang_reflect_Method, Pre) \
template(reflect_Constructor_klass, java_lang_reflect_Constructor, Pre) \
\
- /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
- /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
- /* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
- template(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt) \
- template(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
- template(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
- template(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt) \
- template(reflect_ConstantPool_klass, sun_reflect_ConstantPool, Opt_Only_JDK15) \
- template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \
+ /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
+ /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
+ /* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
+ template(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt) \
+ template(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
+ template(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
+ template(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt) \
+ template(reflect_ConstantPool_klass, sun_reflect_ConstantPool, Opt_Only_JDK15) \
+ template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \
\
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
template(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292) \
@@ -168,14 +168,14 @@
template(StackTraceElement_klass, java_lang_StackTraceElement, Opt) \
/* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
- template(java_nio_Buffer_klass, java_nio_Buffer, Opt) \
+ template(nio_Buffer_klass, java_nio_Buffer, Opt) \
\
/* If this class isn't present, it won't be referenced. */ \
- template(sun_misc_AtomicLongCSImpl_klass, sun_misc_AtomicLongCSImpl, Opt) \
+ template(AtomicLongCSImpl_klass, sun_misc_AtomicLongCSImpl, Opt) \
\
- template(sun_jkernel_DownloadManager_klass, sun_jkernel_DownloadManager, Opt_Kernel) \
+ template(DownloadManager_klass, sun_jkernel_DownloadManager, Opt_Kernel) \
\
- template(sun_misc_PostVMInitHook_klass, sun_misc_PostVMInitHook, Opt) \
+ template(PostVMInitHook_klass, sun_misc_PostVMInitHook, Opt) \
\
/* Preload boxing klasses */ \
template(Boolean_klass, java_lang_Boolean, Pre) \
@@ -199,7 +199,7 @@
enum WKID {
NO_WKID = 0,
- #define WK_KLASS_ENUM(name, ignore_s, ignore_o) WK_KLASS_ENUM_NAME(name),
+ #define WK_KLASS_ENUM(name, symbol, ignore_o) WK_KLASS_ENUM_NAME(name), WK_KLASS_ENUM_NAME(symbol) = WK_KLASS_ENUM_NAME(name),
WK_KLASSES_DO(WK_KLASS_ENUM)
#undef WK_KLASS_ENUM
@@ -426,11 +426,16 @@
}
public:
- #define WK_KLASS_DECLARE(name, ignore_symbol, option) \
+ #define WK_KLASS_DECLARE(name, symbol, option) \
static klassOop name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); }
WK_KLASSES_DO(WK_KLASS_DECLARE);
#undef WK_KLASS_DECLARE
+ static klassOop well_known_klass(WKID id) {
+ assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
+ return _well_known_klasses[id];
+ }
+
// Local definition for direct access to the private array:
#define WK_KLASS(name) _well_known_klasses[SystemDictionary::WK_KLASS_ENUM_NAME(name)]
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -264,8 +264,8 @@
template(setTargetNormal_name, "setTargetNormal") \
template(setTargetVolatile_name, "setTargetVolatile") \
template(setTarget_signature, "(Ljava/lang/invoke/MethodHandle;)V") \
- NOT_LP64( do_alias(machine_word_signature, int_signature) ) \
- LP64_ONLY( do_alias(machine_word_signature, long_signature) ) \
+ NOT_LP64( do_alias(intptr_signature, int_signature) ) \
+ LP64_ONLY( do_alias(intptr_signature, long_signature) ) \
template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
\
/* common method and field names */ \
@@ -365,6 +365,11 @@
template(erasedType_name, "erasedType") \
template(genericInvoker_name, "genericInvoker") \
template(append_name, "append") \
+ template(klass_name, "klass") \
+ template(resolved_constructor_name, "resolved_constructor") \
+ template(array_klass_name, "array_klass") \
+ template(oop_size_name, "oop_size") \
+ template(static_oop_field_count_name, "static_oop_field_count") \
\
/* non-intrinsic name/signature pairs: */ \
template(register_method_name, "register") \
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -37,6 +37,8 @@
// An entry in the compile queue. It represents a pending or current
// compilation.
class CompileTask : public CHeapObj {
+ friend class VMStructs;
+
private:
Monitor* _lock;
uint _compile_id;
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -984,11 +984,8 @@
// check the access_flags for the field in the klass
instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1()));
- typeArrayOop fields = ik->fields();
int index = cp_entry->field_index();
- assert(index < fields->length(), "holders field index is out of range");
- // bail out if field accesses are not watched
- if ((fields->ushort_at(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return;
+ if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return;
switch(cp_entry->flag_state()) {
case btos: // fall through
@@ -1021,11 +1018,9 @@
// check the access_flags for the field in the klass
instanceKlass* ik = instanceKlass::cast(k);
- typeArrayOop fields = ik->fields();
int index = cp_entry->field_index();
- assert(index < fields->length(), "holders field index is out of range");
// bail out if field modifications are not watched
- if ((fields->ushort_at(index) & JVM_ACC_FIELD_MODIFICATION_WATCHED) == 0) return;
+ if ((ik->field_access_flags(index) & JVM_ACC_FIELD_MODIFICATION_WATCHED) == 0) return;
char sig_type = '\0';
--- a/hotspot/src/share/vm/memory/allocation.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -151,6 +151,8 @@
//------------------------------Chunk------------------------------------------
// Linked list of raw memory chunks
class Chunk: public CHeapObj {
+ friend class VMStructs;
+
protected:
Chunk* _next; // Next Chunk in list
const size_t _len; // Size of this Chunk
@@ -200,6 +202,8 @@
friend class ResourceMark;
friend class HandleMark;
friend class NoHandleMark;
+ friend class VMStructs;
+
Chunk *_first; // First chunk
Chunk *_chunk; // current chunk
char *_hwm, *_max; // High water mark and max in current chunk
--- a/hotspot/src/share/vm/memory/resourceArea.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/memory/resourceArea.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -52,6 +52,7 @@
class ResourceArea: public Arena {
friend class ResourceMark;
friend class DeoptResourceMark;
+ friend class VMStructs;
debug_only(int _nesting;) // current # of nested ResourceMarks
debug_only(static int _warned;) // to suppress multiple warnings
--- a/hotspot/src/share/vm/oops/cpCacheOop.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -128,17 +128,13 @@
void ConstantPoolCacheEntry::set_field(Bytecodes::Code get_code,
Bytecodes::Code put_code,
KlassHandle field_holder,
- int orig_field_index,
+ int field_index,
int field_offset,
TosState field_type,
bool is_final,
bool is_volatile) {
set_f1(field_holder()->java_mirror());
set_f2(field_offset);
- // The field index is used by jvm/ti and is the index into fields() array
- // in holder instanceKlass. This is scaled by instanceKlass::next_offset.
- assert((orig_field_index % instanceKlass::next_offset) == 0, "wierd index");
- const int field_index = orig_field_index / instanceKlass::next_offset;
assert(field_index <= field_index_mask,
"field index does not fit in low flag bits");
set_flags(as_flags(field_type, is_final, false, is_volatile, false, false) |
@@ -149,7 +145,7 @@
}
int ConstantPoolCacheEntry::field_index() const {
- return (_flags & field_index_mask) * instanceKlass::next_offset;
+ return (_flags & field_index_mask);
}
void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/fieldInfo.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_FIELDINFO_HPP
+#define SHARE_VM_OOPS_FIELDINFO_HPP
+
+#include "oops/typeArrayOop.hpp"
+#include "classfile/vmSymbols.hpp"
+
+// This class represents the field information contained in the fields
+// array of an instanceKlass. Currently it's laid on top an array of
+// Java shorts but in the future it could simply be used as a real
+// array type. FieldInfo generally shouldn't be used directly.
+// Fields should be queried either through instanceKlass or through
+// the various FieldStreams.
+class FieldInfo VALUE_OBJ_CLASS_SPEC {
+ friend class fieldDescriptor;
+ friend class JavaFieldStream;
+ friend class ClassFileParser;
+
+ public:
+ // fields
+ // Field info extracted from the class file and stored
+ // as an array of 7 shorts
+ enum FieldOffset {
+ access_flags_offset = 0,
+ name_index_offset = 1,
+ signature_index_offset = 2,
+ initval_index_offset = 3,
+ low_offset = 4,
+ high_offset = 5,
+ generic_signature_offset = 6,
+ field_slots = 7
+ };
+
+ private:
+ u2 _shorts[field_slots];
+
+ void set_name_index(u2 val) { _shorts[name_index_offset] = val; }
+ void set_signature_index(u2 val) { _shorts[signature_index_offset] = val; }
+ void set_initval_index(u2 val) { _shorts[initval_index_offset] = val; }
+ void set_generic_signature_index(u2 val) { _shorts[generic_signature_offset] = val; }
+
+ u2 name_index() const { return _shorts[name_index_offset]; }
+ u2 signature_index() const { return _shorts[signature_index_offset]; }
+ u2 initval_index() const { return _shorts[initval_index_offset]; }
+ u2 generic_signature_index() const { return _shorts[generic_signature_offset]; }
+
+ public:
+ static FieldInfo* from_field_array(typeArrayOop fields, int index) {
+ return ((FieldInfo*)fields->short_at_addr(index * field_slots));
+ }
+
+ void initialize(u2 access_flags,
+ u2 name_index,
+ u2 signature_index,
+ u2 initval_index,
+ u2 generic_signature_index,
+ u4 offset) {
+ _shorts[access_flags_offset] = access_flags;
+ _shorts[name_index_offset] = name_index;
+ _shorts[signature_index_offset] = signature_index;
+ _shorts[initval_index_offset] = initval_index;
+ _shorts[generic_signature_offset] = generic_signature_index;
+ set_offset(offset);
+ }
+
+ u2 access_flags() const { return _shorts[access_flags_offset]; }
+ u4 offset() const { return build_int_from_shorts(_shorts[low_offset], _shorts[high_offset]); }
+
+ Symbol* name(constantPoolHandle cp) const {
+ int index = name_index();
+ if (is_internal()) {
+ return lookup_symbol(index);
+ }
+ return cp->symbol_at(index);
+ }
+
+ Symbol* signature(constantPoolHandle cp) const {
+ int index = signature_index();
+ if (is_internal()) {
+ return lookup_symbol(index);
+ }
+ return cp->symbol_at(index);
+ }
+
+ Symbol* generic_signature(constantPoolHandle cp) const {
+ int index = generic_signature_index();
+ if (index == 0) {
+ return NULL;
+ }
+ return cp->symbol_at(index);
+ }
+
+ void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
+ void set_offset(u4 val) {
+ _shorts[low_offset] = extract_low_short_from_int(val);
+ _shorts[high_offset] = extract_high_short_from_int(val);
+ }
+
+ bool is_internal() const {
+ return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0;
+ }
+
+ Symbol* lookup_symbol(int symbol_index) const {
+ assert(is_internal(), "only internal fields");
+ return vmSymbols::symbol_at((vmSymbols::SID)symbol_index);
+ }
+};
+
+#endif // SHARE_VM_OOPS_FIELDINFO_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/fieldStreams.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_FIELDSTREAMS_HPP
+#define SHARE_VM_OOPS_FIELDSTREAMS_HPP
+
+#include "oops/instanceKlass.hpp"
+#include "oops/fieldInfo.hpp"
+
+// The is the base class for iteration over the fields array
+// describing the declared fields in the class. Several subclasses
+// are provided depending on the kind of iteration required. The
+// JavaFieldStream is for iterating over regular Java fields and it
+// generally the preferred iterator. InternalFieldStream only
+// iterates over fields that have been injected by the JVM.
+// AllFieldStream exposes all fields and should only be used in rare
+// cases.
+class FieldStreamBase : public StackObj {
+ protected:
+ typeArrayHandle _fields;
+ constantPoolHandle _constants;
+ int _index;
+ int _limit;
+
+ FieldInfo* field() const { return FieldInfo::from_field_array(_fields(), _index); }
+
+ FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants, int start, int limit) {
+ _fields = fields;
+ _constants = constants;
+ _index = start;
+ _limit = limit;
+ }
+
+ FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants) {
+ _fields = fields;
+ _constants = constants;
+ _index = 0;
+ _limit = fields->length() / FieldInfo::field_slots;
+ }
+
+ public:
+ FieldStreamBase(instanceKlass* klass) {
+ _fields = klass->fields();
+ _constants = klass->constants();
+ _index = 0;
+ _limit = klass->java_fields_count();
+ }
+ FieldStreamBase(instanceKlassHandle klass) {
+ _fields = klass->fields();
+ _constants = klass->constants();
+ _index = 0;
+ _limit = klass->java_fields_count();
+ }
+
+ // accessors
+ int index() const { return _index; }
+
+ void next() { _index += 1; }
+ bool done() const { return _index >= _limit; }
+
+ // Accessors for current field
+ AccessFlags access_flags() const {
+ AccessFlags flags;
+ flags.set_flags(field()->access_flags());
+ return flags;
+ }
+
+ void set_access_flags(u2 flags) const {
+ field()->set_access_flags(flags);
+ }
+
+ void set_access_flags(AccessFlags flags) const {
+ set_access_flags(flags.as_short());
+ }
+
+ Symbol* name() const {
+ return field()->name(_constants);
+ }
+
+ Symbol* signature() const {
+ return field()->signature(_constants);
+ }
+
+ Symbol* generic_signature() const {
+ return field()->generic_signature(_constants);
+ }
+
+ int offset() const {
+ return field()->offset();
+ }
+
+ void set_offset(int offset) {
+ field()->set_offset(offset);
+ }
+};
+
+// Iterate over only the internal fields
+class JavaFieldStream : public FieldStreamBase {
+ public:
+ JavaFieldStream(instanceKlass* k): FieldStreamBase(k->fields(), k->constants(), 0, k->java_fields_count()) {}
+ JavaFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), 0, k->java_fields_count()) {}
+
+ int name_index() const {
+ assert(!field()->is_internal(), "regular only");
+ return field()->name_index();
+ }
+ void set_name_index(int index) {
+ assert(!field()->is_internal(), "regular only");
+ field()->set_name_index(index);
+ }
+ int signature_index() const {
+ assert(!field()->is_internal(), "regular only");
+ return field()->signature_index();
+ }
+ void set_signature_index(int index) {
+ assert(!field()->is_internal(), "regular only");
+ field()->set_signature_index(index);
+ }
+ int generic_signature_index() const {
+ assert(!field()->is_internal(), "regular only");
+ return field()->generic_signature_index();
+ }
+ void set_generic_signature_index(int index) {
+ assert(!field()->is_internal(), "regular only");
+ field()->set_generic_signature_index(index);
+ }
+ int initval_index() const {
+ assert(!field()->is_internal(), "regular only");
+ return field()->initval_index();
+ }
+ void set_initval_index(int index) {
+ assert(!field()->is_internal(), "regular only");
+ return field()->set_initval_index(index);
+ }
+};
+
+
+// Iterate over only the internal fields
+class InternalFieldStream : public FieldStreamBase {
+ public:
+ InternalFieldStream(instanceKlass* k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
+ InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
+};
+
+
+class AllFieldStream : public FieldStreamBase {
+ public:
+ AllFieldStream(typeArrayHandle fields, constantPoolHandle constants): FieldStreamBase(fields, constants) {}
+ AllFieldStream(instanceKlass* k): FieldStreamBase(k->fields(), k->constants()) {}
+ AllFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants()) {}
+};
+
+#endif // SHARE_VM_OOPS_FIELDSTREAMS_HPP
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -36,6 +36,7 @@
#include "memory/genOopClosures.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/permGen.hpp"
+#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/instanceOop.hpp"
@@ -782,14 +783,11 @@
bool instanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
- const int n = fields()->length();
- for (int i = 0; i < n; i += next_offset ) {
- int name_index = fields()->ushort_at(i + name_index_offset);
- int sig_index = fields()->ushort_at(i + signature_index_offset);
- Symbol* f_name = constants()->symbol_at(name_index);
- Symbol* f_sig = constants()->symbol_at(sig_index);
+ for (JavaFieldStream fs(as_klassOop()); !fs.done(); fs.next()) {
+ Symbol* f_name = fs.name();
+ Symbol* f_sig = fs.signature();
if (f_name == name && f_sig == sig) {
- fd->initialize(as_klassOop(), i);
+ fd->initialize(as_klassOop(), fs.index());
return true;
}
}
@@ -803,11 +801,10 @@
closure->do_symbol(&_source_file_name);
closure->do_symbol(&_source_debug_extension);
- const int n = fields()->length();
- for (int i = 0; i < n; i += next_offset ) {
- int name_index = fields()->ushort_at(i + name_index_offset);
+ for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
+ int name_index = fs.name_index();
closure->do_symbol(constants()->symbol_at_addr(name_index));
- int sig_index = fields()->ushort_at(i + signature_index_offset);
+ int sig_index = fs.signature_index();
closure->do_symbol(constants()->symbol_at_addr(sig_index));
}
}
@@ -872,10 +869,9 @@
bool instanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const {
- int length = fields()->length();
- for (int i = 0; i < length; i += next_offset) {
- if (offset_from_fields( i ) == offset) {
- fd->initialize(as_klassOop(), i);
+ for (JavaFieldStream fs(as_klassOop()); !fs.done(); fs.next()) {
+ if (fs.offset() == offset) {
+ fd->initialize(as_klassOop(), fs.index());
if (fd->is_static() == is_static) return true;
}
}
@@ -906,11 +902,12 @@
void instanceKlass::do_local_static_fields(FieldClosure* cl) {
- fieldDescriptor fd;
- int length = fields()->length();
- for (int i = 0; i < length; i += next_offset) {
- fd.initialize(as_klassOop(), i);
- if (fd.is_static()) cl->do_field(&fd);
+ for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_static()) {
+ fieldDescriptor fd;
+ fd.initialize(as_klassOop(), fs.index());
+ cl->do_field(&fd);
+ }
}
}
@@ -922,11 +919,12 @@
void instanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) {
- fieldDescriptor fd;
- int length = this_oop->fields()->length();
- for (int i = 0; i < length; i += next_offset) {
- fd.initialize(this_oop(), i);
- if (fd.is_static()) { f(&fd, CHECK); } // Do NOT remove {}! (CHECK macro expands into several statements)
+ for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_static()) {
+ fieldDescriptor fd;
+ fd.initialize(this_oop(), fs.index());
+ f(&fd, CHECK);
+ }
}
}
@@ -941,11 +939,11 @@
super->do_nonstatic_fields(cl);
}
fieldDescriptor fd;
- int length = fields()->length();
+ int length = java_fields_count();
// In DebugInfo nonstatic fields are sorted by offset.
int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1));
int j = 0;
- for (int i = 0; i < length; i += next_offset) {
+ for (int i = 0; i < length; i += 1) {
fd.initialize(as_klassOop(), i);
if (!fd.is_static()) {
fields_sorted[j + 0] = fd.offset();
@@ -1374,37 +1372,6 @@
//
-// nmethodBucket is used to record dependent nmethods for
-// deoptimization. nmethod dependencies are actually <klass, method>
-// pairs but we really only care about the klass part for purposes of
-// finding nmethods which might need to be deoptimized. Instead of
-// recording the method, a count of how many times a particular nmethod
-// was recorded is kept. This ensures that any recording errors are
-// noticed since an nmethod should be removed as many times are it's
-// added.
-//
-class nmethodBucket {
- private:
- nmethod* _nmethod;
- int _count;
- nmethodBucket* _next;
-
- public:
- nmethodBucket(nmethod* nmethod, nmethodBucket* next) {
- _nmethod = nmethod;
- _next = next;
- _count = 1;
- }
- int count() { return _count; }
- int increment() { _count += 1; return _count; }
- int decrement() { _count -= 1; assert(_count >= 0, "don't underflow"); return _count; }
- nmethodBucket* next() { return _next; }
- void set_next(nmethodBucket* b) { _next = b; }
- nmethod* get_nmethod() { return _nmethod; }
-};
-
-
-//
// Walk the list of dependent nmethods searching for nmethods which
// are dependent on the changes that were passed in and mark them for
// deoptimization. Returns the number of nmethods found.
@@ -2411,43 +2378,6 @@
oop_oop_iterate(obj, &blk);
}
-#ifndef PRODUCT
-
-void instanceKlass::verify_class_klass_nonstatic_oop_maps(klassOop k) {
- // This verification code is disabled. JDK_Version::is_gte_jdk14x_version()
- // cannot be called since this function is called before the VM is
- // able to determine what JDK version is running with.
- // The check below always is false since 1.4.
- return;
-
- // This verification code temporarily disabled for the 1.4
- // reflection implementation since java.lang.Class now has
- // Java-level instance fields. Should rewrite this to handle this
- // case.
- if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) {
- // Verify that java.lang.Class instances have a fake oop field added.
- instanceKlass* ik = instanceKlass::cast(k);
-
- // Check that we have the right class
- static bool first_time = true;
- guarantee(k == SystemDictionary::Class_klass() && first_time, "Invalid verify of maps");
- first_time = false;
- const int extra = java_lang_Class::number_of_fake_oop_fields;
- guarantee(ik->nonstatic_field_size() == extra, "just checking");
- guarantee(ik->nonstatic_oop_map_count() == 1, "just checking");
- guarantee(ik->size_helper() == align_object_size(instanceOopDesc::header_size() + extra), "just checking");
-
- // Check that the map is (2,extra)
- int offset = java_lang_Class::klass_offset;
-
- OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
- guarantee(map->offset() == offset && map->count() == (unsigned int) extra,
- "sanity");
- }
-}
-
-#endif // ndef PRODUCT
-
// JNIid class for jfieldIDs only
// Note to reviewers:
// These JNI functions are just moved over to column 1 and not changed
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -27,6 +27,7 @@
#include "oops/constMethodOop.hpp"
#include "oops/constantPoolOop.hpp"
+#include "oops/fieldInfo.hpp"
#include "oops/instanceOop.hpp"
#include "oops/klassOop.hpp"
#include "oops/klassVtable.hpp"
@@ -228,6 +229,7 @@
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
int _static_oop_field_count;// number of static oop fields in this klass
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
+ int _java_fields_count; // The number of declared Java fields
bool _is_marked_dependent; // used for marking during flushing and deoptimization
bool _rewritten; // methods rewritten.
bool _has_nonstatic_fields; // for sizing with UseCompressedOops
@@ -307,28 +309,29 @@
objArrayOop transitive_interfaces() const { return _transitive_interfaces; }
void set_transitive_interfaces(objArrayOop a) { oop_store_without_check((oop*) &_transitive_interfaces, (oop) a); }
- // fields
- // Field info extracted from the class file and stored
- // as an array of 7 shorts
- enum FieldOffset {
- access_flags_offset = 0,
- name_index_offset = 1,
- signature_index_offset = 2,
- initval_index_offset = 3,
- low_offset = 4,
- high_offset = 5,
- generic_signature_offset = 6,
- next_offset = 7
- };
+ private:
+ friend class fieldDescriptor;
+ FieldInfo* field(int index) const { return FieldInfo::from_field_array(_fields, index); }
+
+ public:
+ int field_offset (int index) const { return field(index)->offset(); }
+ int field_access_flags(int index) const { return field(index)->access_flags(); }
+ Symbol* field_name (int index) const { return field(index)->name(constants()); }
+ Symbol* field_signature (int index) const { return field(index)->signature(constants()); }
+
+ // Number of Java declared fields
+ int java_fields_count() const { return _java_fields_count; }
+
+ // Number of fields including any injected fields
+ int all_fields_count() const { return _fields->length() / sizeof(FieldInfo::field_slots); }
typeArrayOop fields() const { return _fields; }
- int offset_from_fields( int index ) const {
- return build_int_from_shorts( fields()->ushort_at(index + low_offset),
- fields()->ushort_at(index + high_offset) );
+
+ void set_fields(typeArrayOop f, int java_fields_count) {
+ oop_store_without_check((oop*) &_fields, (oop) f);
+ _java_fields_count = java_fields_count;
}
- void set_fields(typeArrayOop f) { oop_store_without_check((oop*) &_fields, (oop) f); }
-
// inner classes
typeArrayOop inner_classes() const { return _inner_classes; }
void set_inner_classes(typeArrayOop f) { oop_store_without_check((oop*) &_inner_classes, (oop) f); }
@@ -842,10 +845,6 @@
// Verification
const char* internal_name() const;
void oop_verify_on(oop obj, outputStream* st);
-
-#ifndef PRODUCT
- static void verify_class_klass_nonstatic_oop_maps(klassOop k) PRODUCT_RETURN;
-#endif
};
inline methodOop instanceKlass::method_at_vtable(int index) {
@@ -1013,4 +1012,36 @@
PreviousVersionInfo* next_previous_version();
};
+
+//
+// nmethodBucket is used to record dependent nmethods for
+// deoptimization. nmethod dependencies are actually <klass, method>
+// pairs but we really only care about the klass part for purposes of
+// finding nmethods which might need to be deoptimized. Instead of
+// recording the method, a count of how many times a particular nmethod
+// was recorded is kept. This ensures that any recording errors are
+// noticed since an nmethod should be removed as many times are it's
+// added.
+//
+class nmethodBucket: public CHeapObj {
+ friend class VMStructs;
+ private:
+ nmethod* _nmethod;
+ int _count;
+ nmethodBucket* _next;
+
+ public:
+ nmethodBucket(nmethod* nmethod, nmethodBucket* next) {
+ _nmethod = nmethod;
+ _next = next;
+ _count = 1;
+ }
+ int count() { return _count; }
+ int increment() { _count += 1; return _count; }
+ int decrement() { _count -= 1; assert(_count >= 0, "don't underflow"); return _count; }
+ nmethodBucket* next() { return _next; }
+ void set_next(nmethodBucket* b) { _next = b; }
+ nmethod* get_nmethod() { return _nmethod; }
+};
+
#endif // SHARE_VM_OOPS_INSTANCEKLASS_HPP
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -386,7 +386,7 @@
ik->set_local_interfaces(NULL);
ik->set_transitive_interfaces(NULL);
ik->init_implementor();
- ik->set_fields(NULL);
+ ik->set_fields(NULL, 0);
ik->set_constants(NULL);
ik->set_class_loader(NULL);
ik->set_protection_domain(NULL);
--- a/hotspot/src/share/vm/oops/klassOop.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/oops/klassOop.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -53,8 +53,10 @@
private:
// These have no implementation since klassOop should never be accessed in this fashion
oop obj_field(int offset) const;
+ volatile oop obj_field_volatile(int offset) const;
void obj_field_put(int offset, oop value);
- void obj_field_raw_put(int offset, oop value);
+ void obj_field_put_raw(int offset, oop value);
+ void obj_field_put_volatile(int offset, oop value);
jbyte byte_field(int offset) const;
void byte_field_put(int offset, jbyte contents);
--- a/hotspot/src/share/vm/oops/oop.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -214,8 +214,10 @@
// Access to fields in a instanceOop through these methods.
oop obj_field(int offset) const;
+ volatile oop obj_field_volatile(int offset) const;
void obj_field_put(int offset, oop value);
- void obj_field_raw_put(int offset, oop value);
+ void obj_field_put_raw(int offset, oop value);
+ void obj_field_put_volatile(int offset, oop value);
jbyte byte_field(int offset) const;
void byte_field_put(int offset, jbyte contents);
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -321,15 +321,25 @@
load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
load_decode_heap_oop(obj_field_addr<oop>(offset));
}
+inline volatile oop oopDesc::obj_field_volatile(int offset) const {
+ volatile oop value = obj_field(offset);
+ OrderAccess::acquire();
+ return value;
+}
inline void oopDesc::obj_field_put(int offset, oop value) {
UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
oop_store(obj_field_addr<oop>(offset), value);
}
-inline void oopDesc::obj_field_raw_put(int offset, oop value) {
+inline void oopDesc::obj_field_put_raw(int offset, oop value) {
UseCompressedOops ?
encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
encode_store_heap_oop(obj_field_addr<oop>(offset), value);
}
+inline void oopDesc::obj_field_put_volatile(int offset, oop value) {
+ OrderAccess::release();
+ obj_field_put(offset, value);
+ OrderAccess::fence();
+}
inline jbyte oopDesc::byte_field(int offset) const { return (jbyte) *byte_field_addr(offset); }
inline void oopDesc::byte_field_put(int offset, jbyte contents) { *byte_field_addr(offset) = (jint) contents; }
--- a/hotspot/src/share/vm/opto/block.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/block.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -45,6 +45,7 @@
// Note that the constructor just zeros things, and since I use Arena
// allocation I do not need a destructor to reclaim storage.
class Block_Array : public ResourceObj {
+ friend class VMStructs;
uint _size; // allocated size, as opposed to formal limit
debug_only(uint _limit;) // limit to formal domain
protected:
@@ -72,6 +73,7 @@
class Block_List : public Block_Array {
+ friend class VMStructs;
public:
uint _cnt;
Block_List() : Block_Array(Thread::current()->resource_area()), _cnt(0) {}
@@ -87,6 +89,7 @@
class CFGElement : public ResourceObj {
+ friend class VMStructs;
public:
float _freq; // Execution frequency (estimate)
@@ -102,6 +105,7 @@
// Basic blocks are used during the output routines, and are not used during
// any optimization pass. They are created late in the game.
class Block : public CFGElement {
+ friend class VMStructs;
public:
// Nodes in this block, in order
Node_List _nodes;
@@ -341,6 +345,7 @@
//------------------------------PhaseCFG---------------------------------------
// Build an array of Basic Block pointers, one per Node.
class PhaseCFG : public Phase {
+ friend class VMStructs;
private:
// Build a proper looking cfg. Return count of basic blocks
uint build_cfg();
@@ -515,6 +520,7 @@
//------------------------------CFGLoop-------------------------------------------
class CFGLoop : public CFGElement {
+ friend class VMStructs;
int _id;
int _depth;
CFGLoop *_parent; // root of loop tree is the method level "pseudo" loop, it's parent is null
@@ -566,6 +572,7 @@
// A edge between two basic blocks that will be embodied by a branch or a
// fall-through.
class CFGEdge : public ResourceObj {
+ friend class VMStructs;
private:
Block * _from; // Source basic block
Block * _to; // Destination basic block
@@ -702,6 +709,7 @@
//------------------------------PhaseBlockLayout-------------------------------
// Rearrange blocks into some canonical order, based on edges and their frequencies
class PhaseBlockLayout : public Phase {
+ friend class VMStructs;
PhaseCFG &_cfg; // Control flow graph
GrowableArray<CFGEdge *> *edges;
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -610,3 +610,22 @@
}
return iltp;
}
+
+
+
+#ifndef PRODUCT
+void InlineTree::print_impl(outputStream* st, int indent) const {
+ for (int i = 0; i < indent; i++) st->print(" ");
+ st->print(" @ %d ", caller_bci());
+ method()->print_short_name(st);
+ st->cr();
+
+ for (int i = 0 ; i < _subtrees.length(); i++) {
+ _subtrees.at(i)->print_impl(st, indent + 2);
+ }
+}
+
+void InlineTree::print_value_on(outputStream* st) const {
+ print_impl(st, 2);
+}
+#endif
--- a/hotspot/src/share/vm/opto/callnode.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/callnode.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -187,6 +187,7 @@
// This provides a way to map the optimized program back into the interpreter,
// or to let the GC mark the stack.
class JVMState : public ResourceObj {
+ friend class VMStructs;
public:
typedef enum {
Reexecute_Undefined = -1, // not defined -- will be translated into false later
@@ -500,6 +501,7 @@
// Call nodes now subsume the function of debug nodes at callsites, so they
// contain the functionality of a full scope chain of debug nodes.
class CallNode : public SafePointNode {
+ friend class VMStructs;
public:
const TypeFunc *_tf; // Function type
address _entry_point; // Address of method being called
@@ -565,6 +567,7 @@
// convention. (The "Java" calling convention is the compiler's calling
// convention, as opposed to the interpreter's or that of native C.)
class CallJavaNode : public CallNode {
+ friend class VMStructs;
protected:
virtual uint cmp( const Node &n ) const;
virtual uint size_of() const; // Size is bigger
--- a/hotspot/src/share/vm/opto/chaitin.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,7 @@
//------------------------------LRG--------------------------------------------
// Live-RanGe structure.
class LRG : public ResourceObj {
+ friend class VMStructs;
public:
enum { SPILL_REG=29999 }; // Register number of a spilled LRG
@@ -181,6 +182,7 @@
// Map Node indices to Live RanGe indices.
// Array lookup in the optimized case.
class LRG_List : public ResourceObj {
+ friend class VMStructs;
uint _cnt, _max;
uint* _lidxs;
ReallocMark _nesting; // assertion check for reallocations
@@ -211,6 +213,7 @@
// abstract! It needs abstraction so I can fiddle with the implementation to
// get even more speed.
class PhaseIFG : public Phase {
+ friend class VMStructs;
// Current implementation: a triangular adjacency list.
// Array of adjacency-lists, indexed by live-range number
@@ -294,6 +297,7 @@
//------------------------------Chaitin----------------------------------------
// Briggs-Chaitin style allocation, mostly.
class PhaseChaitin : public PhaseRegAlloc {
+ friend class VMStructs;
int _trip_cnt;
int _alternate;
@@ -482,6 +486,7 @@
}
int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
+ int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List ®nd, bool can_change_regs );
int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List ®nd );
bool may_be_copy_of_callee( Node *def ) const;
--- a/hotspot/src/share/vm/opto/compile.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/compile.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -80,6 +80,8 @@
// This class defines a top-level Compiler invocation.
class Compile : public Phase {
+ friend class VMStructs;
+
public:
// Fixed alias indexes. (See also MergeMemNode.)
enum {
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -709,10 +709,13 @@
// Adjust body_size to determine if we unroll or not
uint body_size = _body.size();
+ // Key test to unroll loop in CRC32 java code
+ int xors_in_loop = 0;
// Also count ModL, DivL and MulL which expand mightly
for (uint k = 0; k < _body.size(); k++) {
Node* n = _body.at(k);
switch (n->Opcode()) {
+ case Op_XorI: xors_in_loop++; break; // CRC32 java code
case Op_ModL: body_size += 30; break;
case Op_DivL: body_size += 30; break;
case Op_MulL: body_size += 10; break;
@@ -729,7 +732,8 @@
// Check for being too big
if (body_size > (uint)LoopUnrollLimit) {
- // Normal case: loop too big
+ if (xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true;
+ // Normal case: loop too big
return false;
}
--- a/hotspot/src/share/vm/opto/loopnode.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/loopnode.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -582,20 +582,25 @@
// Build a canonical trip test.
// Clone code, as old values may be in use.
- Node* nphi = PhiNode::make(x, init_trip, TypeInt::INT);
- nphi = _igvn.register_new_node_with_optimizer(nphi);
- set_ctrl(nphi, get_ctrl(phi));
-
incr = incr->clone();
- incr->set_req(1,nphi);
+ incr->set_req(1,phi);
incr->set_req(2,stride);
incr = _igvn.register_new_node_with_optimizer(incr);
set_early_ctrl( incr );
-
- nphi->set_req(LoopNode::LoopBackControl, incr);
- _igvn.replace_node(phi, nphi);
- phi = nphi->as_Phi();
-
+ _igvn.hash_delete(phi);
+ phi->set_req_X( LoopNode::LoopBackControl, incr, &_igvn );
+
+ // If phi type is more restrictive than Int, raise to
+ // Int to prevent (almost) infinite recursion in igvn
+ // which can only handle integer types for constants or minint..maxint.
+ if (!TypeInt::INT->higher_equal(phi->bottom_type())) {
+ Node* nphi = PhiNode::make(phi->in(0), phi->in(LoopNode::EntryControl), TypeInt::INT);
+ nphi->set_req(LoopNode::LoopBackControl, phi->in(LoopNode::LoopBackControl));
+ nphi = _igvn.register_new_node_with_optimizer(nphi);
+ set_ctrl(nphi, get_ctrl(phi));
+ _igvn.replace_node(phi, nphi);
+ phi = nphi->as_Phi();
+ }
cmp = cmp->clone();
cmp->set_req(1,incr);
cmp->set_req(2,limit);
@@ -1618,8 +1623,6 @@
Node *phi = cl->phi();
int stride_con = cl->stride_con();
- PhaseGVN *gvn = &_igvn;
-
// Visit all children, looking for Phis
for (DUIterator i = cl->outs(); cl->has_out(i); i++) {
Node *out = cl->out(i);
@@ -1655,25 +1658,31 @@
int ratio_con = stride_con2/stride_con;
if ((ratio_con * stride_con) == stride_con2) { // Check for exact
+#ifndef PRODUCT
+ if (TraceLoopOpts) {
+ tty->print("Parallel IV: %d ", phi2->_idx);
+ loop->dump_head();
+ }
+#endif
// Convert to using the trip counter. The parallel induction
// variable differs from the trip counter by a loop-invariant
// amount, the difference between their respective initial values.
// It is scaled by the 'ratio_con'.
- // Perform local Ideal transformation since in most cases ratio == 1.
Node* ratio = _igvn.intcon(ratio_con);
set_ctrl(ratio, C->root());
- Node* hook = new (C, 3) Node(3);
- Node* ratio_init = gvn->transform(new (C, 3) MulINode(init, ratio));
- hook->init_req(0, ratio_init);
- Node* diff = gvn->transform(new (C, 3) SubINode(init2, ratio_init));
- hook->init_req(1, diff);
- Node* ratio_idx = gvn->transform(new (C, 3) MulINode(phi, ratio));
- hook->init_req(2, ratio_idx);
- Node* add = gvn->transform(new (C, 3) AddINode(ratio_idx, diff));
- set_subtree_ctrl(add);
+ Node* ratio_init = new (C, 3) MulINode(init, ratio);
+ _igvn.register_new_node_with_optimizer(ratio_init, init);
+ set_early_ctrl(ratio_init);
+ Node* diff = new (C, 3) SubINode(init2, ratio_init);
+ _igvn.register_new_node_with_optimizer(diff, init2);
+ set_early_ctrl(diff);
+ Node* ratio_idx = new (C, 3) MulINode(phi, ratio);
+ _igvn.register_new_node_with_optimizer(ratio_idx, phi);
+ set_ctrl(ratio_idx, cl);
+ Node* add = new (C, 3) AddINode(ratio_idx, diff);
+ _igvn.register_new_node_with_optimizer(add);
+ set_ctrl(add, cl);
_igvn.replace_node( phi2, add );
- // Free up intermediate goo
- _igvn.remove_dead_node(hook);
// Sometimes an induction variable is unused
if (add->outcnt() == 0) {
_igvn.remove_dead_node(add);
--- a/hotspot/src/share/vm/opto/node.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/node.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -184,6 +184,8 @@
// whenever I have phase-specific information.
class Node {
+ friend class VMStructs;
+
// Lots of restrictions on cloning Nodes
Node(const Node&); // not defined; linker error to use these
Node &operator=(const Node &rhs);
@@ -1286,6 +1288,7 @@
// Note that the constructor just zeros things, and since I use Arena
// allocation I do not need a destructor to reclaim storage.
class Node_Array : public ResourceObj {
+ friend class VMStructs;
protected:
Arena *_a; // Arena to allocate in
uint _max;
@@ -1316,6 +1319,7 @@
};
class Node_List : public Node_Array {
+ friend class VMStructs;
uint _cnt;
public:
Node_List() : Node_Array(Thread::current()->resource_area()), _cnt(0) {}
@@ -1339,6 +1343,7 @@
//------------------------------Unique_Node_List-------------------------------
class Unique_Node_List : public Node_List {
+ friend class VMStructs;
VectorSet _in_worklist;
uint _clock_index; // Index in list where to pop from next
public:
@@ -1389,6 +1394,7 @@
//------------------------------Node_Stack-------------------------------------
class Node_Stack {
+ friend class VMStructs;
protected:
struct INode {
Node *node; // Processed node
@@ -1461,6 +1467,7 @@
// Debugging or profiling annotations loosely and sparsely associated
// with some nodes. See Compile::node_notes_at for the accessor.
class Node_Notes VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
JVMState* _jvms;
public:
--- a/hotspot/src/share/vm/opto/optoreg.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/optoreg.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2011, 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
@@ -172,6 +172,7 @@
// and converting that will return OptoReg::Bad losing the identity of the OptoReg.
class OptoRegPair {
+ friend class VMStructs;
private:
short _second;
short _first;
--- a/hotspot/src/share/vm/opto/parse.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/parse.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -41,6 +41,8 @@
//------------------------------InlineTree-------------------------------------
class InlineTree : public ResourceObj {
+ friend class VMStructs;
+
Compile* C; // cache
JVMState* _caller_jvms; // state of caller
ciMethod* _method; // method being called by the caller_jvms
@@ -54,7 +56,8 @@
float compute_callee_frequency( int caller_bci ) const;
GrowableArray<InlineTree*> _subtrees;
- friend class Compile;
+
+ void print_impl(outputStream* stj, int indent) const PRODUCT_RETURN;
protected:
InlineTree(Compile* C,
@@ -121,6 +124,8 @@
uint count_inlines() const { return _count_inlines; };
#endif
GrowableArray<InlineTree*> subtrees() { return _subtrees; }
+
+ void print_value_on(outputStream* st) const PRODUCT_RETURN;
};
--- a/hotspot/src/share/vm/opto/postaloc.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/postaloc.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -72,7 +72,22 @@
return i == limit;
}
-
+//------------------------------yank-----------------------------------
+// Helper function for yank_if_dead
+int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
+ int blk_adjust=0;
+ Block *oldb = _cfg._bbs[old->_idx];
+ oldb->find_remove(old);
+ // Count 1 if deleting an instruction from the current block
+ if( oldb == current_block ) blk_adjust++;
+ _cfg._bbs.map(old->_idx,NULL);
+ OptoReg::Name old_reg = lrgs(n2lidx(old)).reg();
+ if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
+ value->map(old_reg,NULL); // Yank from value/regnd maps
+ regnd->map(old_reg,NULL); // This register's value is now unknown
+ }
+ return blk_adjust;
+}
//------------------------------yank_if_dead-----------------------------------
// Removed an edge from 'old'. Yank if dead. Return adjustment counts to
@@ -80,18 +95,23 @@
int PhaseChaitin::yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
int blk_adjust=0;
while (old->outcnt() == 0 && old != C->top()) {
- Block *oldb = _cfg._bbs[old->_idx];
- oldb->find_remove(old);
- // Count 1 if deleting an instruction from the current block
- if( oldb == current_block ) blk_adjust++;
- _cfg._bbs.map(old->_idx,NULL);
- OptoReg::Name old_reg = lrgs(n2lidx(old)).reg();
- if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
- value->map(old_reg,NULL); // Yank from value/regnd maps
- regnd->map(old_reg,NULL); // This register's value is now unknown
+ blk_adjust += yank(old, current_block, value, regnd);
+
+ Node *tmp = NULL;
+ for (uint i = 1; i < old->req(); i++) {
+ if (old->in(i)->is_MachTemp()) {
+ // handle TEMP inputs
+ Node* machtmp = old->in(i);
+ if (machtmp->outcnt() == 1) {
+ assert(machtmp->unique_out() == old, "sanity");
+ blk_adjust += yank(machtmp, current_block, value, regnd);
+ machtmp->disconnect_inputs(NULL);
+ }
+ } else {
+ assert(tmp == NULL, "can't handle more non MachTemp inputs");
+ tmp = old->in(i);
+ }
}
- assert(old->req() <= 2, "can't handle more inputs");
- Node *tmp = old->req() > 1 ? old->in(1) : NULL;
old->disconnect_inputs(NULL);
if( !tmp ) break;
old = tmp;
--- a/hotspot/src/share/vm/opto/regalloc.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/regalloc.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
//------------------------------PhaseRegAlloc------------------------------------
// Abstract register allocator
class PhaseRegAlloc : public Phase {
+ friend class VMStructs;
static void (*_alloc_statistics[MAX_REG_ALLOCATORS])();
static int _num_allocators;
--- a/hotspot/src/share/vm/opto/type.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -64,6 +64,8 @@
// different kind of Type exists. Types are never modified after creation, so
// all their interesting fields are constant.
class Type {
+ friend class VMStructs;
+
public:
enum TYPES {
Bad=0, // Type check
--- a/hotspot/src/share/vm/prims/jni.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -492,7 +492,7 @@
// First check if this is a static field
if (modifiers & JVM_ACC_STATIC) {
- intptr_t offset = instanceKlass::cast(k1())->offset_from_fields( slot );
+ intptr_t offset = instanceKlass::cast(k1())->field_offset( slot );
JNIid* id = instanceKlass::cast(k1())->jni_id_for(offset);
assert(id != NULL, "corrupt Field object");
debug_only(id->set_is_static_field_id();)
@@ -504,7 +504,7 @@
// The slot is the index of the field description in the field-array
// The jfieldID is the offset of the field within the object
// It may also have hash bits for k, if VerifyJNIFields is turned on.
- intptr_t offset = instanceKlass::cast(k1())->offset_from_fields( slot );
+ intptr_t offset = instanceKlass::cast(k1())->field_offset( slot );
assert(instanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);
return ret;
--- a/hotspot/src/share/vm/prims/jvm.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -32,6 +32,7 @@
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.inline.hpp"
+#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/objArrayKlass.hpp"
#include "prims/jvm.h"
@@ -1493,7 +1494,7 @@
fieldDescriptor fd;
KlassHandle kh(THREAD, k);
- intptr_t offset = instanceKlass::cast(kh())->offset_from_fields(slot);
+ intptr_t offset = instanceKlass::cast(kh())->field_offset(slot);
if (modifiers & JVM_ACC_STATIC) {
// for static fields we only look in the current class
@@ -1593,9 +1594,6 @@
// Ensure class is linked
k->link_class(CHECK_NULL);
- typeArrayHandle fields(THREAD, k->fields());
- int fields_len = fields->length();
-
// 4496456 We need to filter out java.lang.Throwable.backtrace
bool skip_backtrace = false;
@@ -1604,12 +1602,11 @@
if (publicOnly) {
num_fields = 0;
- for (int i = 0, j = 0; i < fields_len; i += instanceKlass::next_offset, j++) {
- int mods = fields->ushort_at(i + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS;
- if (mods & JVM_ACC_PUBLIC) ++num_fields;
+ for (JavaFieldStream fs(k()); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_public()) ++num_fields;
}
} else {
- num_fields = fields_len / instanceKlass::next_offset;
+ num_fields = k->java_fields_count();
if (k() == SystemDictionary::Throwable_klass()) {
num_fields--;
@@ -1622,16 +1619,15 @@
int out_idx = 0;
fieldDescriptor fd;
- for (int i = 0; i < fields_len; i += instanceKlass::next_offset) {
+ for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
if (skip_backtrace) {
// 4496456 skip java.lang.Throwable.backtrace
- int offset = k->offset_from_fields(i);
+ int offset = fs.offset();
if (offset == java_lang_Throwable::get_backtrace_offset()) continue;
}
- int mods = fields->ushort_at(i + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS;
- if (!publicOnly || (mods & JVM_ACC_PUBLIC)) {
- fd.initialize(k(), i);
+ if (!publicOnly || fs.access_flags().is_public()) {
+ fd.initialize(k(), fs.index());
oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);
result->obj_at_put(out_idx, field);
++out_idx;
@@ -2119,7 +2115,7 @@
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
if (!Klass::cast(k)->oop_is_instance())
return 0;
- return instanceKlass::cast(k)->fields()->length() / instanceKlass::next_offset;
+ return instanceKlass::cast(k)->java_fields_count();
JVM_END
@@ -2215,8 +2211,7 @@
JVMWrapper("JVM_GetFieldIxModifiers");
klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- typeArrayOop fields = instanceKlass::cast(k)->fields();
- return fields->ushort_at(field_index * instanceKlass::next_offset + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS;
+ return instanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS;
JVM_END
@@ -2399,7 +2394,7 @@
JVM_END
-JVM_QUICK_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls))
+JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls))
JVMWrapper("JVM_GetCPFieldModifiers");
klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
klassOop k_called = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(called_cls));
@@ -2411,12 +2406,9 @@
case JVM_CONSTANT_Fieldref: {
Symbol* name = cp->uncached_name_ref_at(cp_index);
Symbol* signature = cp->uncached_signature_ref_at(cp_index);
- typeArrayOop fields = instanceKlass::cast(k_called)->fields();
- int fields_count = fields->length();
- for (int i = 0; i < fields_count; i += instanceKlass::next_offset) {
- if (cp_called->symbol_at(fields->ushort_at(i + instanceKlass::name_index_offset)) == name &&
- cp_called->symbol_at(fields->ushort_at(i + instanceKlass::signature_index_offset)) == signature) {
- return fields->ushort_at(i + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS;
+ for (JavaFieldStream fs(k_called); !fs.done(); fs.next()) {
+ if (fs.name() == name && fs.signature() == signature) {
+ return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS;
}
}
return -1;
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "interpreter/bytecodeStream.hpp"
+#include "oops/fieldStreams.hpp"
#include "prims/jvmtiClassFileReconstituter.hpp"
#include "runtime/signature.hpp"
#ifdef TARGET_ARCH_x86
@@ -52,25 +53,22 @@
// JVMSpec| field_info fields[fields_count];
void JvmtiClassFileReconstituter::write_field_infos() {
HandleMark hm(thread());
- typeArrayHandle fields(thread(), ikh()->fields());
- int fields_length = fields->length();
- int num_fields = fields_length / instanceKlass::next_offset;
objArrayHandle fields_anno(thread(), ikh()->fields_annotations());
- write_u2(num_fields);
- for (int index = 0; index < fields_length; index += instanceKlass::next_offset) {
- AccessFlags access_flags;
- int flags = fields->ushort_at(index + instanceKlass::access_flags_offset);
- access_flags.set_flags(flags);
- int name_index = fields->ushort_at(index + instanceKlass::name_index_offset);
- int signature_index = fields->ushort_at(index + instanceKlass::signature_index_offset);
- int initial_value_index = fields->ushort_at(index + instanceKlass::initval_index_offset);
+ // Compute the real number of Java fields
+ int java_fields = ikh()->java_fields_count();
+
+ write_u2(java_fields);
+ for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) {
+ AccessFlags access_flags = fs.access_flags();
+ int name_index = fs.name_index();
+ int signature_index = fs.signature_index();
+ int initial_value_index = fs.initval_index();
guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field");
- int offset = ikh()->offset_from_fields( index );
- int generic_signature_index =
- fields->ushort_at(index + instanceKlass::generic_signature_offset);
+ // int offset = ikh()->field_offset( index );
+ int generic_signature_index = fs.generic_signature_index();
typeArrayHandle anno(thread(), fields_anno.not_null() ?
- (typeArrayOop)(fields_anno->obj_at(index / instanceKlass::next_offset)) :
+ (typeArrayOop)(fields_anno->obj_at(fs.index())) :
(typeArrayOop)NULL);
// JVMSpec| field_info {
@@ -81,7 +79,7 @@
// JVMSpec| attribute_info attributes[attributes_count];
// JVMSpec| }
- write_u2(flags & JVM_RECOGNIZED_FIELD_MODIFIERS);
+ write_u2(access_flags.as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
write_u2(name_index);
write_u2(signature_index);
int attr_count = 0;
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -2044,7 +2044,6 @@
// make sure we haven't set this watch before
if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE;
fdesc_ptr->set_is_field_access_watched(true);
- update_klass_field_access_flag(fdesc_ptr);
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, true);
@@ -2057,7 +2056,6 @@
// make sure we have a watch to clear
if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND;
fdesc_ptr->set_is_field_access_watched(false);
- update_klass_field_access_flag(fdesc_ptr);
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, false);
@@ -2070,7 +2068,6 @@
// make sure we haven't set this watch before
if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE;
fdesc_ptr->set_is_field_modification_watched(true);
- update_klass_field_access_flag(fdesc_ptr);
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, true);
@@ -2083,7 +2080,6 @@
// make sure we have a watch to clear
if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND;
fdesc_ptr->set_is_field_modification_watched(false);
- update_klass_field_access_flag(fdesc_ptr);
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, false);
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -565,15 +565,6 @@
}
-// update the access_flags for the field in the klass
-void
-JvmtiEnvBase::update_klass_field_access_flag(fieldDescriptor *fd) {
- instanceKlass* ik = instanceKlass::cast(fd->field_holder());
- typeArrayOop fields = ik->fields();
- fields->ushort_at_put(fd->index(), (jushort)fd->access_flags().as_short());
-}
-
-
// return the vframe on the specified thread and depth, NULL if no such frame
vframe*
JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) {
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -267,8 +267,6 @@
// convert to a jni jclass from a non-null klassOop
jclass get_jni_class_non_null(klassOop k);
- void update_klass_field_access_flag(fieldDescriptor *fd);
-
jint count_locked_objects(JavaThread *java_thread, Handle hobj);
jvmtiError get_locked_objects_in_frame(JavaThread *calling_thread,
JavaThread* java_thread,
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -66,6 +66,7 @@
// This class contains the JVMTI interface for the rest of hotspot.
//
class JvmtiExport : public AllStatic {
+ friend class VMStructs;
private:
static int _field_access_count;
static int _field_modification_count;
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -30,6 +30,7 @@
#include "interpreter/rewriter.hpp"
#include "memory/gcLocker.hpp"
#include "memory/universe.inline.hpp"
+#include "oops/fieldStreams.hpp"
#include "oops/klassVtable.hpp"
#include "prims/jvmtiImpl.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
@@ -551,41 +552,35 @@
// Check if the number, names, types and order of fields declared in these classes
// are the same.
- typeArrayOop k_old_fields = the_class->fields();
- typeArrayOop k_new_fields = scratch_class->fields();
- int n_fields = k_old_fields->length();
- if (n_fields != k_new_fields->length()) {
- return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
- }
-
- for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
+ JavaFieldStream old_fs(the_class);
+ JavaFieldStream new_fs(scratch_class);
+ for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
// access
- old_flags = k_old_fields->ushort_at(i + instanceKlass::access_flags_offset);
- new_flags = k_new_fields->ushort_at(i + instanceKlass::access_flags_offset);
+ old_flags = old_fs.access_flags().as_short();
+ new_flags = new_fs.access_flags().as_short();
if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
}
// offset
- if (k_old_fields->short_at(i + instanceKlass::low_offset) !=
- k_new_fields->short_at(i + instanceKlass::low_offset) ||
- k_old_fields->short_at(i + instanceKlass::high_offset) !=
- k_new_fields->short_at(i + instanceKlass::high_offset)) {
+ if (old_fs.offset() != new_fs.offset()) {
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
}
// name and signature
- jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset);
- jshort sig_index = k_old_fields->short_at(i +instanceKlass::signature_index_offset);
- Symbol* name_sym1 = the_class->constants()->symbol_at(name_index);
- Symbol* sig_sym1 = the_class->constants()->symbol_at(sig_index);
- name_index = k_new_fields->short_at(i + instanceKlass::name_index_offset);
- sig_index = k_new_fields->short_at(i + instanceKlass::signature_index_offset);
- Symbol* name_sym2 = scratch_class->constants()->symbol_at(name_index);
- Symbol* sig_sym2 = scratch_class->constants()->symbol_at(sig_index);
+ Symbol* name_sym1 = the_class->constants()->symbol_at(old_fs.name_index());
+ Symbol* sig_sym1 = the_class->constants()->symbol_at(old_fs.signature_index());
+ Symbol* name_sym2 = scratch_class->constants()->symbol_at(new_fs.name_index());
+ Symbol* sig_sym2 = scratch_class->constants()->symbol_at(new_fs.signature_index());
if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) {
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
}
}
+ // If both streams aren't done then we have a differing number of
+ // fields.
+ if (!old_fs.done() || !new_fs.done()) {
+ return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
+ }
+
// Do a parallel walk through the old and new methods. Detect
// cases where they match (exist in both), have been added in
// the new methods, or have been deleted (exist only in the
@@ -2369,38 +2364,34 @@
int i; // for portability
// update each field in klass to use new constant pool indices as needed
- typeArrayHandle fields(THREAD, scratch_class->fields());
- int n_fields = fields->length();
- for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
- jshort cur_index = fields->short_at(i + instanceKlass::name_index_offset);
+ for (JavaFieldStream fs(scratch_class); !fs.done(); fs.next()) {
+ jshort cur_index = fs.name_index();
jshort new_index = find_new_index(cur_index);
if (new_index != 0) {
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
("field-name_index change: %d to %d", cur_index, new_index));
- fields->short_at_put(i + instanceKlass::name_index_offset, new_index);
+ fs.set_name_index(new_index);
}
- cur_index = fields->short_at(i + instanceKlass::signature_index_offset);
+ cur_index = fs.signature_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
("field-signature_index change: %d to %d", cur_index, new_index));
- fields->short_at_put(i + instanceKlass::signature_index_offset,
- new_index);
+ fs.set_signature_index(new_index);
}
- cur_index = fields->short_at(i + instanceKlass::initval_index_offset);
+ cur_index = fs.initval_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
("field-initval_index change: %d to %d", cur_index, new_index));
- fields->short_at_put(i + instanceKlass::initval_index_offset, new_index);
+ fs.set_initval_index(new_index);
}
- cur_index = fields->short_at(i + instanceKlass::generic_signature_offset);
+ cur_index = fs.generic_signature_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
("field-generic_signature change: %d to %d", cur_index, new_index));
- fields->short_at_put(i + instanceKlass::generic_signature_offset,
- new_index);
+ fs.set_generic_signature_index(new_index);
}
} // end for each field
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -520,7 +520,7 @@
int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
int mods = java_lang_reflect_Field::modifiers(target_oop);
klassOop k = java_lang_Class::as_klassOop(clazz);
- int offset = instanceKlass::cast(k)->offset_from_fields(slot);
+ int offset = instanceKlass::cast(k)->field_offset(slot);
init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
} else {
KlassHandle receiver_limit; int decode_flags = 0;
@@ -1632,8 +1632,6 @@
THROW(vmSymbols::java_lang_InternalError());
}
- java_lang_invoke_MethodHandle::init_vmslots(mh());
-
if (VerifyMethodHandles) {
// The privileged code which invokes this routine should not make
// a mistake about types, but it's better to verify.
@@ -1756,7 +1754,6 @@
if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
- java_lang_invoke_MethodHandle::init_vmslots(mh());
int vmargslot = m->size_of_parameters() - 1;
assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, "");
@@ -1862,7 +1859,6 @@
THROW(vmSymbols::java_lang_InternalError());
}
- java_lang_invoke_MethodHandle::init_vmslots(mh());
int argslot = java_lang_invoke_BoundMethodHandle::vmargslot(mh());
if (VerifyMethodHandles) {
@@ -2686,6 +2682,7 @@
java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie);
}
}
+ assert(java_lang_invoke_MethodTypeForm::vmslots(mtform()) == argument_slot_count(mtype()), "must agree");
}
#ifdef ASSERT
@@ -3081,6 +3078,30 @@
}
JVM_END
+JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
+ oop call_site = JNIHandles::resolve_non_null(call_site_jh);
+ oop target = JNIHandles::resolve(target_jh);
+ {
+ // Walk all nmethods depending on this call site.
+ MutexLocker mu(Compile_lock, thread);
+ Universe::flush_dependents_on(call_site, target);
+ }
+ java_lang_invoke_CallSite::set_target(call_site, target);
+}
+JVM_END
+
+JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
+ oop call_site = JNIHandles::resolve_non_null(call_site_jh);
+ oop target = JNIHandles::resolve(target_jh);
+ {
+ // Walk all nmethods depending on this call site.
+ MutexLocker mu(Compile_lock, thread);
+ Universe::flush_dependents_on(call_site, target);
+ }
+ java_lang_invoke_CallSite::set_target_volatile(call_site, target);
+}
+JVM_END
+
methodOop MethodHandles::resolve_raise_exception_method(TRAPS) {
if (_raise_exception_method != NULL) {
// no need to do it twice
@@ -3137,12 +3158,15 @@
/// JVM_RegisterMethodHandleMethods
+#undef CS // Solaris builds complain
+
#define LANG "Ljava/lang/"
#define JLINV "Ljava/lang/invoke/"
#define OBJ LANG"Object;"
#define CLS LANG"Class;"
#define STRG LANG"String;"
+#define CS JLINV"CallSite;"
#define MT JLINV"MethodType;"
#define MH JLINV"MethodHandle;"
#define MEM JLINV"MemberName;"
@@ -3153,29 +3177,34 @@
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
-// These are the native methods on sun.invoke.MethodHandleNatives.
+// These are the native methods on java.lang.invoke.MethodHandleNatives.
static JNINativeMethod methods[] = {
// void init(MemberName self, AccessibleObject ref)
- {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHN_init_AMH)},
- {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHN_init_BMH)},
- {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHN_init_DMH)},
- {CC"init", CC"("MT")V", FN_PTR(MHN_init_MT)},
- {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
- {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
- {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHN_resolve_Mem)},
- {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHN_getTarget)},
- {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)},
+ {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHN_init_AMH)},
+ {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHN_init_BMH)},
+ {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHN_init_DMH)},
+ {CC"init", CC"("MT")V", FN_PTR(MHN_init_MT)},
+ {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
+ {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
+ {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHN_resolve_Mem)},
+ {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHN_getTarget)},
+ {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)},
// static native int getNamedCon(int which, Object[] name)
- {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)},
+ {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)},
// static native int getMembers(Class<?> defc, String matchName, String matchSig,
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
- {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
+ {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
+};
+
+static JNINativeMethod call_site_methods[] = {
+ {CC"setCallSiteTargetNormal", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetNormal)},
+ {CC"setCallSiteTargetVolatile", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetVolatile)}
};
static JNINativeMethod invoke_methods[] = {
// void init(MemberName self, AccessibleObject ref)
- {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
- {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
+ {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
+ {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
};
// This one function is exported, used by NativeLookup.
@@ -3188,11 +3217,11 @@
return; // bind nothing
}
+ assert(!MethodHandles::enabled(), "must not be enabled");
bool enable_MH = true;
{
ThreadToNativeFromVM ttnfv(thread);
-
int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (!env->ExceptionOccurred()) {
const char* L_MH_name = (JLINV "MethodHandle");
@@ -3201,11 +3230,16 @@
status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod));
}
if (env->ExceptionOccurred()) {
- MethodHandles::set_enabled(false);
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
env->ExceptionClear();
}
+
+ status = env->RegisterNatives(MHN_class, call_site_methods, sizeof(call_site_methods)/sizeof(JNINativeMethod));
+ if (env->ExceptionOccurred()) {
+ // Exception is okay until 7087357
+ env->ExceptionClear();
+ }
}
if (enable_MH) {
--- a/hotspot/src/share/vm/prims/methodHandles.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -515,11 +515,12 @@
}
// Here is the transformation the i2i adapter must perform:
static int truncate_subword_from_vminfo(jint value, int vminfo) {
- jint tem = value << vminfo;
+ int shift = vminfo & ~CONV_VMINFO_SIGN_FLAG;
+ jint tem = value << shift;
if ((vminfo & CONV_VMINFO_SIGN_FLAG) != 0) {
- return (jint)tem >> vminfo;
+ return (jint)tem >> shift;
} else {
- return (juint)tem >> vminfo;
+ return (juint)tem >> shift;
}
}
--- a/hotspot/src/share/vm/prims/unsafe.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -719,7 +719,7 @@
}
}
- int offset = instanceKlass::cast(k)->offset_from_fields(slot);
+ int offset = instanceKlass::cast(k)->field_offset(slot);
return field_offset_from_byte_offset(offset);
}
--- a/hotspot/src/share/vm/runtime/arguments.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -3021,9 +3021,6 @@
}
#ifdef JAVASE_EMBEDDED
- #ifdef PPC
- UNSUPPORTED_OPTION(EnableInvokeDynamic, "Invoke dynamic");
- #endif
UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
#endif
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -103,7 +103,7 @@
_frame_pcs = frame_pcs;
_register_block = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2);
_return_type = return_type;
- _initial_fp = 0;
+ _initial_info = 0;
// PD (x86 only)
_counter_temp = 0;
_unpack_kind = 0;
@@ -486,9 +486,10 @@
frame_sizes,
frame_pcs,
return_type);
- // On some platforms, we need a way to pass fp to the unpacking code
- // so the skeletal frames come out correct.
- info->set_initial_fp((intptr_t) array->sender().fp());
+ // On some platforms, we need a way to pass some platform dependent
+ // information to the unpacking code so the skeletal frames come out
+ // correct (initial fp value, unextended sp, ...)
+ info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info());
if (array->frames() > 1) {
if (VerifyStack && TraceDeoptimization) {
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -34,6 +34,8 @@
class ObjectValue;
class Deoptimization : AllStatic {
+ friend class VMStructs;
+
public:
// What condition caused the deoptimization?
enum DeoptReason {
@@ -137,7 +139,7 @@
address* _frame_pcs; // Array of frame pc's, in bytes, for unrolling the stack
intptr_t* _register_block; // Block for storing callee-saved registers.
BasicType _return_type; // Tells if we have to restore double or long return value
- intptr_t _initial_fp; // FP of the sender frame
+ intptr_t _initial_info; // Platform dependent data for the sender frame (was FP on x86)
int _caller_actual_parameters; // The number of actual arguments at the
// interpreted caller of the deoptimized frame
@@ -170,7 +172,7 @@
// Returns the total size of frames
int size_of_frames() const;
- void set_initial_fp(intptr_t fp) { _initial_fp = fp; }
+ void set_initial_info(intptr_t info) { _initial_info = info; }
int caller_actual_parameters() const { return _caller_actual_parameters; }
@@ -184,7 +186,7 @@
static int register_block_offset_in_bytes() { return offset_of(UnrollBlock, _register_block); }
static int return_type_offset_in_bytes() { return offset_of(UnrollBlock, _return_type); }
static int counter_temp_offset_in_bytes() { return offset_of(UnrollBlock, _counter_temp); }
- static int initial_fp_offset_in_bytes() { return offset_of(UnrollBlock, _initial_fp); }
+ static int initial_info_offset_in_bytes() { return offset_of(UnrollBlock, _initial_info); }
static int unpack_kind_offset_in_bytes() { return offset_of(UnrollBlock, _unpack_kind); }
static int sender_sp_temp_offset_in_bytes() { return offset_of(UnrollBlock, _sender_sp_temp); }
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -42,59 +42,51 @@
objArrayOop md = ik->fields_annotations();
if (md == NULL)
return NULL;
- assert((index() % instanceKlass::next_offset) == 0, "");
- return typeArrayOop(md->obj_at(index() / instanceKlass::next_offset));
+ return typeArrayOop(md->obj_at(index()));
}
constantTag fieldDescriptor::initial_value_tag() const {
- return constants()->tag_at(_initial_value_index);
+ return constants()->tag_at(initial_value_index());
}
jint fieldDescriptor::int_initial_value() const {
- return constants()->int_at(_initial_value_index);
+ return constants()->int_at(initial_value_index());
}
jlong fieldDescriptor::long_initial_value() const {
- return constants()->long_at(_initial_value_index);
+ return constants()->long_at(initial_value_index());
}
jfloat fieldDescriptor::float_initial_value() const {
- return constants()->float_at(_initial_value_index);
+ return constants()->float_at(initial_value_index());
}
jdouble fieldDescriptor::double_initial_value() const {
- return constants()->double_at(_initial_value_index);
+ return constants()->double_at(initial_value_index());
}
oop fieldDescriptor::string_initial_value(TRAPS) const {
- return constants()->string_at(_initial_value_index, CHECK_0);
+ return constants()->string_at(initial_value_index(), CHECK_0);
}
void fieldDescriptor::initialize(klassOop k, int index) {
instanceKlass* ik = instanceKlass::cast(k);
_cp = ik->constants();
- typeArrayOop fields = ik->fields();
-
- assert(fields->length() % instanceKlass::next_offset == 0, "Illegal size of field array");
- assert(fields->length() >= index + instanceKlass::next_offset, "Illegal size of field array");
+ FieldInfo* f = ik->field(index);
+ assert(!f->is_internal(), "regular Java fields only");
- _access_flags.set_field_flags(fields->ushort_at(index + instanceKlass::access_flags_offset));
- _name_index = fields->ushort_at(index + instanceKlass::name_index_offset);
- _signature_index = fields->ushort_at(index + instanceKlass::signature_index_offset);
- _initial_value_index = fields->ushort_at(index + instanceKlass::initval_index_offset);
- guarantee(_name_index != 0 && _signature_index != 0, "bad constant pool index for fieldDescriptor");
- _offset = ik->offset_from_fields( index );
- _generic_signature_index = fields->ushort_at(index + instanceKlass::generic_signature_offset);
+ _access_flags = accessFlags_from(f->access_flags());
+ guarantee(f->name_index() != 0 && f->signature_index() != 0, "bad constant pool index for fieldDescriptor");
_index = index;
}
#ifndef PRODUCT
void fieldDescriptor::print_on(outputStream* st) const {
- _access_flags.print_on(st);
- constants()->symbol_at(_name_index)->print_value_on(st);
+ access_flags().print_on(st);
+ name()->print_value_on(st);
st->print(" ");
- constants()->symbol_at(_signature_index)->print_value_on(st);
+ signature()->print_value_on(st);
st->print(" @%d ", offset());
if (WizardMode && has_initial_value()) {
st->print("(initval ");
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -40,29 +40,40 @@
class fieldDescriptor VALUE_OBJ_CLASS_SPEC {
private:
AccessFlags _access_flags;
- int _name_index;
- int _signature_index;
- int _initial_value_index;
- int _offset;
- int _generic_signature_index;
- int _index; // index into fields() array
+ int _index; // the field index
constantPoolHandle _cp;
+ // update the access_flags for the field in the klass
+ void update_klass_field_access_flag() {
+ instanceKlass* ik = instanceKlass::cast(field_holder());
+ ik->field(index())->set_access_flags(_access_flags.as_short());
+ }
+
+ FieldInfo* field() const {
+ instanceKlass* ik = instanceKlass::cast(field_holder());
+ return ik->field(_index);
+ }
+
public:
- Symbol* name() const { return _cp->symbol_at(_name_index); }
- Symbol* signature() const { return _cp->symbol_at(_signature_index); }
+ Symbol* name() const {
+ return field()->name(_cp);
+ }
+ Symbol* signature() const {
+ return field()->signature(_cp);
+ }
klassOop field_holder() const { return _cp->pool_holder(); }
constantPoolOop constants() const { return _cp(); }
AccessFlags access_flags() const { return _access_flags; }
oop loader() const;
// Offset (in words) of field from start of instanceOop / klassOop
- int offset() const { return _offset; }
- Symbol* generic_signature() const { return (_generic_signature_index > 0 ? _cp->symbol_at(_generic_signature_index) : (Symbol*)NULL); }
+ int offset() const { return field()->offset(); }
+ Symbol* generic_signature() const { return field()->generic_signature(_cp); }
int index() const { return _index; }
typeArrayOop annotations() const;
// Initial field value
- bool has_initial_value() const { return _initial_value_index != 0; }
+ bool has_initial_value() const { return field()->initval_index() != 0; }
+ int initial_value_index() const { return field()->initval_index(); }
constantTag initial_value_tag() const; // The tag will return true on one of is_int(), is_long(), is_single(), is_double()
jint int_initial_value() const;
jlong long_initial_value() const;
@@ -74,25 +85,31 @@
BasicType field_type() const { return FieldType::basic_type(signature()); }
// Access flags
- bool is_public() const { return _access_flags.is_public(); }
- bool is_private() const { return _access_flags.is_private(); }
- bool is_protected() const { return _access_flags.is_protected(); }
+ bool is_public() const { return access_flags().is_public(); }
+ bool is_private() const { return access_flags().is_private(); }
+ bool is_protected() const { return access_flags().is_protected(); }
bool is_package_private() const { return !is_public() && !is_private() && !is_protected(); }
- bool is_static() const { return _access_flags.is_static(); }
- bool is_final() const { return _access_flags.is_final(); }
- bool is_volatile() const { return _access_flags.is_volatile(); }
- bool is_transient() const { return _access_flags.is_transient(); }
+ bool is_static() const { return access_flags().is_static(); }
+ bool is_final() const { return access_flags().is_final(); }
+ bool is_volatile() const { return access_flags().is_volatile(); }
+ bool is_transient() const { return access_flags().is_transient(); }
- bool is_synthetic() const { return _access_flags.is_synthetic(); }
+ bool is_synthetic() const { return access_flags().is_synthetic(); }
- bool is_field_access_watched() const { return _access_flags.is_field_access_watched(); }
+ bool is_field_access_watched() const { return access_flags().is_field_access_watched(); }
bool is_field_modification_watched() const
- { return _access_flags.is_field_modification_watched(); }
- void set_is_field_access_watched(const bool value)
- { _access_flags.set_is_field_access_watched(value); }
- void set_is_field_modification_watched(const bool value)
- { _access_flags.set_is_field_modification_watched(value); }
+ { return access_flags().is_field_modification_watched(); }
+
+ void set_is_field_access_watched(const bool value) {
+ _access_flags.set_is_field_access_watched(value);
+ update_klass_field_access_flag();
+ }
+
+ void set_is_field_modification_watched(const bool value) {
+ _access_flags.set_is_field_modification_watched(value);
+ update_klass_field_access_flag();
+ }
// Initialization
void initialize(klassOop k, int index);
--- a/hotspot/src/share/vm/runtime/frame.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -221,6 +221,10 @@
// returns the stack pointer of the calling frame
intptr_t* sender_sp() const;
+ // Deoptimization info, if needed (platform dependent).
+ // Stored in the initial_info field of the unroll info, to be used by
+ // the platform dependent deoptimization blobs.
+ intptr_t *initial_deoptimization_info();
// Interpreter frames:
--- a/hotspot/src/share/vm/runtime/reflectionUtils.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/reflectionUtils.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -107,10 +107,8 @@
class FieldStream : public KlassStream {
private:
- int length() const { return fields()->length(); }
- constantPoolOop constants() const { return _klass->constants(); }
- protected:
- typeArrayOop fields() const { return _klass->fields(); }
+ int length() const { return _klass->java_fields_count(); }
+
public:
FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
: KlassStream(klass, local_only, classes_only) {
@@ -118,26 +116,23 @@
next();
}
- void next() { _index -= instanceKlass::next_offset; }
+ void next() { _index -= 1; }
// Accessors for current field
AccessFlags access_flags() const {
AccessFlags flags;
- flags.set_flags(fields()->ushort_at(index() + instanceKlass::access_flags_offset));
+ flags.set_flags(_klass->field_access_flags(_index));
return flags;
}
Symbol* name() const {
- int name_index = fields()->ushort_at(index() + instanceKlass::name_index_offset);
- return constants()->symbol_at(name_index);
+ return _klass->field_name(_index);
}
Symbol* signature() const {
- int signature_index = fields()->ushort_at(index() +
- instanceKlass::signature_index_offset);
- return constants()->symbol_at(signature_index);
+ return _klass->field_signature(_index);
}
// missing: initval()
int offset() const {
- return _klass->offset_from_fields( index() );
+ return _klass->field_offset( index() );
}
};
@@ -213,10 +208,10 @@
}
int field_count();
void next() {
- _index -= instanceKlass::next_offset;
+ _index -= 1;
if (has_filtered_field()) {
while (_index >=0 && FilteredFieldsMap::is_filtered_field((klassOop)_klass(), offset())) {
- _index -= instanceKlass::next_offset;
+ _index -= 1;
}
}
}
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -51,8 +51,6 @@
address StubRoutines::_forward_exception_entry = NULL;
address StubRoutines::_throw_AbstractMethodError_entry = NULL;
address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
-address StubRoutines::_throw_ArithmeticException_entry = NULL;
-address StubRoutines::_throw_NullPointerException_entry = NULL;
address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
address StubRoutines::_throw_StackOverflowError_entry = NULL;
address StubRoutines::_throw_WrongMethodTypeException_entry = NULL;
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -128,8 +128,6 @@
static address _catch_exception_entry;
static address _throw_AbstractMethodError_entry;
static address _throw_IncompatibleClassChangeError_entry;
- static address _throw_ArithmeticException_entry;
- static address _throw_NullPointerException_entry;
static address _throw_NullPointerException_at_call_entry;
static address _throw_StackOverflowError_entry;
static address _throw_WrongMethodTypeException_entry;
@@ -254,8 +252,6 @@
// Implicit exceptions
static address throw_AbstractMethodError_entry() { return _throw_AbstractMethodError_entry; }
static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; }
- static address throw_ArithmeticException_entry() { return _throw_ArithmeticException_entry; }
- static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; }
static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; }
static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; }
static address throw_WrongMethodTypeException_entry() { return _throw_WrongMethodTypeException_entry; }
--- a/hotspot/src/share/vm/runtime/thread.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -966,7 +966,7 @@
// General purpose hook into Java code, run once when the VM is initialized.
// The Java library method itself may be changed independently from the VM.
static void call_postVMInitHook(TRAPS) {
- klassOop k = SystemDictionary::sun_misc_PostVMInitHook_klass();
+ klassOop k = SystemDictionary::PostVMInitHook_klass();
instanceKlassHandle klass (THREAD, k);
if (klass.not_null()) {
JavaValue result(T_VOID);
--- a/hotspot/src/share/vm/runtime/vframeArray.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/vframeArray.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,8 @@
// represent an interpreter frame which will eventually be created.
class vframeArrayElement : public _ValueObj {
+ friend class VMStructs;
+
private:
frame _frame; // the interpreter frame we will unpack into
@@ -107,6 +109,8 @@
// at the data in each vframeElement
class vframeArray: public CHeapObj {
+ friend class VMStructs;
+
private:
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Sep 15 12:44:09 2011 -0700
@@ -29,6 +29,11 @@
#include "classfile/placeholders.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
+#include "ci/ciField.hpp"
+#include "ci/ciInstance.hpp"
+#include "ci/ciObjArrayKlass.hpp"
+#include "ci/ciMethodData.hpp"
+#include "ci/ciSymbol.hpp"
#include "code/codeBlob.hpp"
#include "code/codeCache.hpp"
#include "code/compressedStream.hpp"
@@ -38,6 +43,7 @@
#include "code/stubs.hpp"
#include "code/vmreg.hpp"
#include "compiler/oopMap.hpp"
+#include "compiler/compileBroker.hpp"
#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
#include "gc_implementation/shared/immutableSpace.hpp"
#include "gc_implementation/shared/markSweep.hpp"
@@ -90,6 +96,8 @@
#include "oops/typeArrayOop.hpp"
#include "prims/jvmtiAgentThread.hpp"
#include "runtime/arguments.hpp"
+#include "runtime/deoptimization.hpp"
+#include "runtime/vframeArray.hpp"
#include "runtime/globals.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
@@ -167,7 +175,23 @@
#include "gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp"
#endif
#ifdef COMPILER2
+#include "opto/addnode.hpp"
+#include "opto/block.hpp"
+#include "opto/callnode.hpp"
+#include "opto/cfgnode.hpp"
+#include "opto/chaitin.hpp"
+#include "opto/divnode.hpp"
+#include "opto/locknode.hpp"
+#include "opto/loopnode.hpp"
+#include "opto/machnode.hpp"
#include "opto/matcher.hpp"
+#include "opto/mulnode.hpp"
+#include "opto/phaseX.hpp"
+#include "opto/parse.hpp"
+#include "opto/regalloc.hpp"
+#include "opto/rootnode.hpp"
+#include "opto/subnode.hpp"
+#include "opto/vectornode.hpp"
#ifdef TARGET_ARCH_MODEL_x86_32
# include "adfiles/adGlobals_x86_32.hpp"
#endif
@@ -261,6 +285,7 @@
nonstatic_field(instanceKlass, _nof_implementors, int) \
nonstatic_field(instanceKlass, _implementors[0], klassOop) \
nonstatic_field(instanceKlass, _fields, typeArrayOop) \
+ nonstatic_field(instanceKlass, _java_fields_count, int) \
nonstatic_field(instanceKlass, _constants, constantPoolOop) \
nonstatic_field(instanceKlass, _class_loader, oop) \
nonstatic_field(instanceKlass, _protection_domain, oop) \
@@ -293,6 +318,10 @@
nonstatic_field(instanceKlass, _methods_annotations, objArrayOop) \
nonstatic_field(instanceKlass, _methods_parameter_annotations, objArrayOop) \
nonstatic_field(instanceKlass, _methods_default_annotations, objArrayOop) \
+ nonstatic_field(instanceKlass, _dependencies, nmethodBucket*) \
+ nonstatic_field(nmethodBucket, _nmethod, nmethod*) \
+ nonstatic_field(nmethodBucket, _count, int) \
+ nonstatic_field(nmethodBucket, _next, nmethodBucket*) \
nonstatic_field(Klass, _super_check_offset, juint) \
nonstatic_field(Klass, _secondary_super_cache, klassOop) \
nonstatic_field(Klass, _secondary_supers, objArrayOop) \
@@ -311,17 +340,26 @@
nonstatic_field(methodKlass, _alloc_size, juint) \
nonstatic_field(methodDataOopDesc, _size, int) \
nonstatic_field(methodDataOopDesc, _method, methodOop) \
+ nonstatic_field(methodDataOopDesc, _data_size, int) \
+ nonstatic_field(methodDataOopDesc, _data[0], intptr_t) \
+ nonstatic_field(methodDataOopDesc, _nof_decompiles, uint) \
+ nonstatic_field(methodDataOopDesc, _nof_overflow_recompiles, uint) \
+ nonstatic_field(methodDataOopDesc, _nof_overflow_traps, uint) \
+ nonstatic_field(methodDataOopDesc, _eflags, intx) \
+ nonstatic_field(methodDataOopDesc, _arg_local, intx) \
+ nonstatic_field(methodDataOopDesc, _arg_stack, intx) \
+ nonstatic_field(methodDataOopDesc, _arg_returned, intx) \
nonstatic_field(methodOopDesc, _constMethod, constMethodOop) \
nonstatic_field(methodOopDesc, _constants, constantPoolOop) \
- c2_nonstatic_field(methodOopDesc, _method_data, methodDataOop) \
- c2_nonstatic_field(methodOopDesc, _interpreter_invocation_count, int) \
+ nonstatic_field(methodOopDesc, _method_data, methodDataOop) \
+ nonstatic_field(methodOopDesc, _interpreter_invocation_count, int) \
nonstatic_field(methodOopDesc, _access_flags, AccessFlags) \
nonstatic_field(methodOopDesc, _vtable_index, int) \
nonstatic_field(methodOopDesc, _method_size, u2) \
nonstatic_field(methodOopDesc, _max_stack, u2) \
nonstatic_field(methodOopDesc, _max_locals, u2) \
nonstatic_field(methodOopDesc, _size_of_parameters, u2) \
- c2_nonstatic_field(methodOopDesc, _interpreter_throwout_count, u2) \
+ nonstatic_field(methodOopDesc, _interpreter_throwout_count, u2) \
nonstatic_field(methodOopDesc, _number_of_breakpoints, u2) \
nonstatic_field(methodOopDesc, _invocation_counter, InvocationCounter) \
nonstatic_field(methodOopDesc, _backedge_counter, InvocationCounter) \
@@ -407,7 +445,7 @@
static_field(Universe, _constantPoolCacheKlassObj, klassOop) \
static_field(Universe, _compiledICHolderKlassObj, klassOop) \
static_field(Universe, _systemObjArrayKlassObj, klassOop) \
- static_field(Universe, _mirrors[0], oop) \
+ static_field(Universe, _mirrors[0], oop) \
static_field(Universe, _main_thread_group, oop) \
static_field(Universe, _system_thread_group, oop) \
static_field(Universe, _the_empty_byte_array, typeArrayOop) \
@@ -708,6 +746,15 @@
nonstatic_field(LoaderConstraintEntry, _max_loaders, int) \
nonstatic_field(LoaderConstraintEntry, _loaders, oop*) \
\
+ /*******************/ \
+ /* GrowableArrays */ \
+ /*******************/ \
+ \
+ nonstatic_field(GenericGrowableArray, _len, int) \
+ nonstatic_field(GenericGrowableArray, _max, int) \
+ nonstatic_field(GenericGrowableArray, _arena, Arena*) \
+ nonstatic_field(GrowableArray<int>, _data, int*) \
+ \
/********************************/ \
/* CodeCache (NOTE: incomplete) */ \
/********************************/ \
@@ -813,11 +860,14 @@
nonstatic_field(nmethod, _lock_count, jint) \
nonstatic_field(nmethod, _stack_traversal_mark, long) \
nonstatic_field(nmethod, _compile_id, int) \
+ nonstatic_field(nmethod, _exception_cache, ExceptionCache*) \
nonstatic_field(nmethod, _marked_for_deoptimization, bool) \
\
nonstatic_field(RicochetBlob, _bounce_offset, int) \
nonstatic_field(RicochetBlob, _exception_offset, int) \
\
+ unchecked_c2_static_field(Deoptimization, _trap_reason_name, void*) \
+ \
/********************************/ \
/* JavaCalls (NOTE: incomplete) */ \
/********************************/ \
@@ -838,6 +888,9 @@
static_field(Threads, _number_of_non_daemon_threads, int) \
static_field(Threads, _return_code, int) \
\
+ nonstatic_field(ThreadShadow, _pending_exception, oop) \
+ nonstatic_field(ThreadShadow, _exception_file, const char*) \
+ nonstatic_field(ThreadShadow, _exception_line, int) \
volatile_nonstatic_field(Thread, _suspend_flags, uint32_t) \
nonstatic_field(Thread, _active_handles, JNIHandleBlock*) \
nonstatic_field(Thread, _tlab, ThreadLocalAllocBuffer) \
@@ -849,10 +902,22 @@
nonstatic_field(JavaThread, _next, JavaThread*) \
nonstatic_field(JavaThread, _threadObj, oop) \
nonstatic_field(JavaThread, _anchor, JavaFrameAnchor) \
+ nonstatic_field(JavaThread, _vm_result, oop) \
+ nonstatic_field(JavaThread, _vm_result_2, oop) \
+ nonstatic_field(JavaThread, _pending_async_exception, oop) \
+ volatile_nonstatic_field(JavaThread, _exception_oop, oop) \
+ volatile_nonstatic_field(JavaThread, _exception_pc, address) \
+ nonstatic_field(JavaThread, _is_compiling, bool) \
+ nonstatic_field(JavaThread, _special_runtime_exit_condition, JavaThread::AsyncRequests) \
+ nonstatic_field(JavaThread, _saved_exception_pc, address) \
volatile_nonstatic_field(JavaThread, _thread_state, JavaThreadState) \
nonstatic_field(JavaThread, _osthread, OSThread*) \
nonstatic_field(JavaThread, _stack_base, address) \
nonstatic_field(JavaThread, _stack_size, size_t) \
+ nonstatic_field(JavaThread, _vframe_array_head, vframeArray*) \
+ nonstatic_field(JavaThread, _vframe_array_last, vframeArray*) \
+ nonstatic_field(Thread, _resource_area, ResourceArea*) \
+ nonstatic_field(CompilerThread, _env, ciEnv*) \
\
/************/ \
/* OSThread */ \
@@ -902,7 +967,83 @@
/* Runtime1 (NOTE: incomplete) */ \
/*******************************/ \
\
- unchecked_c1_static_field(Runtime1, _blobs, sizeof(Runtime1::_blobs)) /* NOTE: no type */ \
+ unchecked_c1_static_field(Runtime1, _blobs, sizeof(Runtime1::_blobs)) /* NOTE: no type */ \
+ \
+ /**************/ \
+ /* allocation */ \
+ /**************/ \
+ \
+ nonstatic_field(Chunk, _next, Chunk*) \
+ nonstatic_field(Chunk, _len, const size_t) \
+ \
+ nonstatic_field(Arena, _first, Chunk*) \
+ nonstatic_field(Arena, _chunk, Chunk*) \
+ nonstatic_field(Arena, _hwm, char*) \
+ nonstatic_field(Arena, _max, char*) \
+ \
+ /************/ \
+ /* CI */ \
+ /************/ \
+ \
+ nonstatic_field(ciEnv, _system_dictionary_modification_counter, int) \
+ nonstatic_field(ciEnv, _compiler_data, void*) \
+ nonstatic_field(ciEnv, _failure_reason, const char*) \
+ nonstatic_field(ciEnv, _factory, ciObjectFactory*) \
+ nonstatic_field(ciEnv, _dependencies, Dependencies*) \
+ nonstatic_field(ciEnv, _task, CompileTask*) \
+ nonstatic_field(ciEnv, _arena, Arena*) \
+ \
+ nonstatic_field(ciObject, _handle, jobject) \
+ nonstatic_field(ciObject, _klass, ciKlass*) \
+ nonstatic_field(ciObject, _ident, uint) \
+ \
+ nonstatic_field(ciSymbol, _ident, uint) \
+ nonstatic_field(ciSymbol, _symbol, Symbol*) \
+ \
+ nonstatic_field(ciType, _basic_type, BasicType) \
+ \
+ nonstatic_field(ciKlass, _name, ciSymbol*) \
+ \
+ nonstatic_field(ciArrayKlass, _dimension, jint) \
+ \
+ nonstatic_field(ciObjArrayKlass, _element_klass, ciKlass*) \
+ nonstatic_field(ciObjArrayKlass, _base_element_klass, ciKlass*) \
+ \
+ nonstatic_field(ciInstanceKlass, _init_state, instanceKlass::ClassState) \
+ nonstatic_field(ciInstanceKlass, _is_shared, bool) \
+ \
+ nonstatic_field(ciMethod, _interpreter_invocation_count, int) \
+ nonstatic_field(ciMethod, _interpreter_throwout_count, int) \
+ \
+ nonstatic_field(ciMethodData, _data_size, int) \
+ nonstatic_field(ciMethodData, _state, u_char) \
+ nonstatic_field(ciMethodData, _extra_data_size, int) \
+ nonstatic_field(ciMethodData, _data, intptr_t*) \
+ nonstatic_field(ciMethodData, _hint_di, int) \
+ nonstatic_field(ciMethodData, _eflags, intx) \
+ nonstatic_field(ciMethodData, _arg_local, intx) \
+ nonstatic_field(ciMethodData, _arg_stack, intx) \
+ nonstatic_field(ciMethodData, _arg_returned, intx) \
+ nonstatic_field(ciMethodData, _current_mileage, int) \
+ nonstatic_field(ciMethodData, _orig, methodDataOopDesc) \
+ \
+ nonstatic_field(ciField, _holder, ciInstanceKlass*) \
+ nonstatic_field(ciField, _name, ciSymbol*) \
+ nonstatic_field(ciField, _signature, ciSymbol*) \
+ nonstatic_field(ciField, _offset, int) \
+ nonstatic_field(ciField, _is_constant, bool) \
+ nonstatic_field(ciField, _constant_value, ciConstant) \
+ \
+ nonstatic_field(ciObjectFactory, _ci_objects, GrowableArray<ciObject*>*) \
+ nonstatic_field(ciObjectFactory, _symbols, GrowableArray<ciSymbol*>*) \
+ nonstatic_field(ciObjectFactory, _unloaded_methods, GrowableArray<ciMethod*>*) \
+ \
+ nonstatic_field(ciConstant, _type, BasicType) \
+ nonstatic_field(ciConstant, _value._int, jint) \
+ nonstatic_field(ciConstant, _value._long, jlong) \
+ nonstatic_field(ciConstant, _value._float, jfloat) \
+ nonstatic_field(ciConstant, _value._double, jdouble) \
+ nonstatic_field(ciConstant, _value._object, ciObject*) \
\
/************/ \
/* Monitors */ \
@@ -924,7 +1065,114 @@
/* Matcher (C2 only) */ \
/*********************/ \
\
- unchecked_c2_static_field(Matcher, _regEncode, sizeof(Matcher::_regEncode)) /* NOTE: no type */ \
+ unchecked_c2_static_field(Matcher, _regEncode, sizeof(Matcher::_regEncode)) /* NOTE: no type */ \
+ \
+ c2_nonstatic_field(Node, _in, Node**) \
+ c2_nonstatic_field(Node, _out, Node**) \
+ c2_nonstatic_field(Node, _cnt, node_idx_t) \
+ c2_nonstatic_field(Node, _max, node_idx_t) \
+ c2_nonstatic_field(Node, _outcnt, node_idx_t) \
+ c2_nonstatic_field(Node, _outmax, node_idx_t) \
+ c2_nonstatic_field(Node, _idx, const node_idx_t) \
+ c2_nonstatic_field(Node, _class_id, jushort) \
+ c2_nonstatic_field(Node, _flags, jushort) \
+ \
+ c2_nonstatic_field(Compile, _root, RootNode*) \
+ c2_nonstatic_field(Compile, _unique, uint) \
+ c2_nonstatic_field(Compile, _entry_bci, int) \
+ c2_nonstatic_field(Compile, _top, Node*) \
+ c2_nonstatic_field(Compile, _cfg, PhaseCFG*) \
+ c2_nonstatic_field(Compile, _regalloc, PhaseRegAlloc*) \
+ c2_nonstatic_field(Compile, _method, ciMethod*) \
+ c2_nonstatic_field(Compile, _compile_id, const int) \
+ c2_nonstatic_field(Compile, _save_argument_registers, const bool) \
+ c2_nonstatic_field(Compile, _subsume_loads, const bool) \
+ c2_nonstatic_field(Compile, _do_escape_analysis, const bool) \
+ c2_nonstatic_field(Compile, _ilt, InlineTree*) \
+ \
+ c2_nonstatic_field(InlineTree, _caller_jvms, JVMState*) \
+ c2_nonstatic_field(InlineTree, _method, ciMethod*) \
+ c2_nonstatic_field(InlineTree, _caller_tree, InlineTree*) \
+ c2_nonstatic_field(InlineTree, _subtrees, GrowableArray<InlineTree*>) \
+ \
+ c2_nonstatic_field(OptoRegPair, _first, short) \
+ c2_nonstatic_field(OptoRegPair, _second, short) \
+ \
+ c2_nonstatic_field(JVMState, _caller, JVMState*) \
+ c2_nonstatic_field(JVMState, _depth, uint) \
+ c2_nonstatic_field(JVMState, _locoff, uint) \
+ c2_nonstatic_field(JVMState, _stkoff, uint) \
+ c2_nonstatic_field(JVMState, _monoff, uint) \
+ c2_nonstatic_field(JVMState, _scloff, uint) \
+ c2_nonstatic_field(JVMState, _endoff, uint) \
+ c2_nonstatic_field(JVMState, _sp, uint) \
+ c2_nonstatic_field(JVMState, _bci, int) \
+ c2_nonstatic_field(JVMState, _method, ciMethod*) \
+ c2_nonstatic_field(JVMState, _map, SafePointNode*) \
+ \
+ c2_nonstatic_field(SafePointNode, _jvms, JVMState* const) \
+ \
+ c2_nonstatic_field(MachSafePointNode, _jvms, JVMState*) \
+ c2_nonstatic_field(MachSafePointNode, _jvmadj, uint) \
+ \
+ c2_nonstatic_field(MachIfNode, _prob, jfloat) \
+ c2_nonstatic_field(MachIfNode, _fcnt, jfloat) \
+ \
+ c2_nonstatic_field(CallNode, _entry_point, address) \
+ \
+ c2_nonstatic_field(CallJavaNode, _method, ciMethod*) \
+ \
+ c2_nonstatic_field(CallRuntimeNode, _name, const char*) \
+ \
+ c2_nonstatic_field(CallStaticJavaNode, _name, const char*) \
+ \
+ c2_nonstatic_field(MachCallJavaNode, _method, ciMethod*) \
+ c2_nonstatic_field(MachCallJavaNode, _bci, int) \
+ \
+ c2_nonstatic_field(MachCallStaticJavaNode, _name, const char*) \
+ \
+ c2_nonstatic_field(MachCallRuntimeNode, _name, const char*) \
+ \
+ c2_nonstatic_field(PhaseCFG, _num_blocks, uint) \
+ c2_nonstatic_field(PhaseCFG, _blocks, Block_List) \
+ c2_nonstatic_field(PhaseCFG, _bbs, Block_Array) \
+ c2_nonstatic_field(PhaseCFG, _broot, Block*) \
+ \
+ c2_nonstatic_field(PhaseRegAlloc, _node_regs, OptoRegPair*) \
+ c2_nonstatic_field(PhaseRegAlloc, _node_regs_max_index, uint) \
+ c2_nonstatic_field(PhaseRegAlloc, _framesize, uint) \
+ c2_nonstatic_field(PhaseRegAlloc, _max_reg, OptoReg::Name) \
+ \
+ c2_nonstatic_field(PhaseChaitin, _trip_cnt, int) \
+ c2_nonstatic_field(PhaseChaitin, _alternate, int) \
+ c2_nonstatic_field(PhaseChaitin, _lo_degree, uint) \
+ c2_nonstatic_field(PhaseChaitin, _lo_stk_degree, uint) \
+ c2_nonstatic_field(PhaseChaitin, _hi_degree, uint) \
+ c2_nonstatic_field(PhaseChaitin, _simplified, uint) \
+ c2_nonstatic_field(PhaseChaitin, _maxlrg, uint) \
+ \
+ c2_nonstatic_field(Block, _nodes, Node_List) \
+ c2_nonstatic_field(Block, _succs, Block_Array) \
+ c2_nonstatic_field(Block, _num_succs, uint) \
+ c2_nonstatic_field(Block, _pre_order, uint) \
+ c2_nonstatic_field(Block, _dom_depth, uint) \
+ c2_nonstatic_field(Block, _idom, Block*) \
+ c2_nonstatic_field(Block, _freq, jfloat) \
+ \
+ c2_nonstatic_field(CFGElement, _freq, jfloat) \
+ \
+ c2_nonstatic_field(Block_List, _cnt, uint) \
+ \
+ c2_nonstatic_field(Block_Array, _size, uint) \
+ c2_nonstatic_field(Block_Array, _blocks, Block**) \
+ c2_nonstatic_field(Block_Array, _arena, Arena*) \
+ \
+ c2_nonstatic_field(Node_List, _cnt, uint) \
+ \
+ c2_nonstatic_field(Node_Array, _max, uint) \
+ c2_nonstatic_field(Node_Array, _nodes, Node**) \
+ c2_nonstatic_field(Node_Array, _a, Arena*) \
+ \
\
/*********************/ \
/* -XX flags */ \
@@ -934,6 +1182,7 @@
nonstatic_field(Flag, name, const char*) \
unchecked_nonstatic_field(Flag, addr, sizeof(void*)) /* NOTE: no type */ \
nonstatic_field(Flag, kind, const char*) \
+ nonstatic_field(Flag, origin, FlagValueOrigin) \
static_field(Flag, flags, Flag*) \
static_field(Flag, numFlags, size_t) \
\
@@ -951,7 +1200,14 @@
nonstatic_field(JDK_Version, _partially_initialized, bool) \
nonstatic_field(JDK_Version, _major, unsigned char) \
\
+ /*************************/ \
+ /* JVMTI */ \
+ /*************************/ \
\
+ static_field(JvmtiExport, _can_access_local_variables, bool) \
+ static_field(JvmtiExport, _can_hotswap_or_post_breakpoint, bool) \
+ static_field(JvmtiExport, _can_post_on_exceptions, bool) \
+ static_field(JvmtiExport, _can_walk_any_space, bool) \
\
/*************/ \
/* Arguments */ \
@@ -967,20 +1223,36 @@
/* java_lang_Class fields */ \
/*********************************/ \
\
- static_field(java_lang_Class, klass_offset, int) \
- static_field(java_lang_Class, resolved_constructor_offset, int) \
- static_field(java_lang_Class, array_klass_offset, int) \
- static_field(java_lang_Class, oop_size_offset, int) \
- static_field(java_lang_Class, static_oop_field_count_offset, int) \
+ static_field(java_lang_Class, _klass_offset, int) \
+ static_field(java_lang_Class, _resolved_constructor_offset, int) \
+ static_field(java_lang_Class, _array_klass_offset, int) \
+ static_field(java_lang_Class, _oop_size_offset, int) \
+ static_field(java_lang_Class, _static_oop_field_count_offset, int) \
\
/************************/ \
/* Miscellaneous fields */ \
/************************/ \
\
- nonstatic_field(AccessFlags, _flags, jint) \
- nonstatic_field(elapsedTimer, _counter, jlong) \
- nonstatic_field(elapsedTimer, _active, bool) \
- nonstatic_field(InvocationCounter, _counter, unsigned int)
+ nonstatic_field(CompileTask, _method, jobject) \
+ nonstatic_field(CompileTask, _osr_bci, int) \
+ nonstatic_field(CompileTask, _comp_level, int) \
+ nonstatic_field(CompileTask, _compile_id, uint) \
+ nonstatic_field(CompileTask, _next, CompileTask*) \
+ nonstatic_field(CompileTask, _prev, CompileTask*) \
+ \
+ nonstatic_field(vframeArray, _next, vframeArray*) \
+ nonstatic_field(vframeArray, _original, frame) \
+ nonstatic_field(vframeArray, _caller, frame) \
+ nonstatic_field(vframeArray, _frames, int) \
+ \
+ nonstatic_field(vframeArrayElement, _frame, frame) \
+ nonstatic_field(vframeArrayElement, _bci, int) \
+ nonstatic_field(vframeArrayElement, _method, methodOop) \
+ \
+ nonstatic_field(AccessFlags, _flags, jint) \
+ nonstatic_field(elapsedTimer, _counter, jlong) \
+ nonstatic_field(elapsedTimer, _active, bool) \
+ nonstatic_field(InvocationCounter, _counter, unsigned int)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
@@ -1060,12 +1332,16 @@
/* and are valid types for Fields. */ \
/*********************************************************************/ \
declare_integer_type(bool) \
+ declare_integer_type(short) \
declare_integer_type(int) \
declare_integer_type(long) \
declare_integer_type(char) \
declare_unsigned_integer_type(unsigned char) \
+ declare_unsigned_integer_type(u_char) \
declare_unsigned_integer_type(unsigned int) \
+ declare_unsigned_integer_type(uint) \
declare_unsigned_integer_type(unsigned short) \
+ declare_unsigned_integer_type(jushort) \
declare_unsigned_integer_type(unsigned long) \
/* The compiler thinks this is a different type than */ \
/* unsigned short on Win32 */ \
@@ -1079,7 +1355,6 @@
declare_toplevel_type(int*) \
declare_toplevel_type(char*) \
declare_toplevel_type(char**) \
- declare_toplevel_type(const char*) \
declare_toplevel_type(u_char*) \
declare_toplevel_type(unsigned char*) \
\
@@ -1091,14 +1366,12 @@
\
declare_unsigned_integer_type(size_t) \
declare_integer_type(ssize_t) \
- declare_unsigned_integer_type(const size_t) \
declare_integer_type(intx) \
declare_integer_type(intptr_t) \
declare_unsigned_integer_type(uintx) \
declare_unsigned_integer_type(uintptr_t) \
declare_unsigned_integer_type(uint32_t) \
declare_unsigned_integer_type(uint64_t) \
- declare_integer_type(const int) \
\
/*******************************************************************************/ \
/* OopDesc and Klass hierarchies (NOTE: missing methodDataOop-related classes) */ \
@@ -1124,8 +1397,8 @@
declare_type(klassKlass, Klass) \
declare_type(klassOopDesc, oopDesc) \
declare_type(markOopDesc, oopDesc) \
- declare_type(methodDataKlass, Klass) \
- declare_type(methodDataOopDesc, oopDesc) \
+ declare_type(methodDataKlass, Klass) \
+ declare_type(methodDataOopDesc, oopDesc) \
declare_type(methodKlass, Klass) \
declare_type(constMethodKlass, Klass) \
declare_type(methodOopDesc, oopDesc) \
@@ -1139,6 +1412,8 @@
declare_toplevel_type(Symbol) \
declare_toplevel_type(Symbol*) \
\
+ declare_toplevel_type(nmethodBucket) \
+ \
/********/ \
/* Oops */ \
/********/ \
@@ -1206,7 +1481,6 @@
declare_toplevel_type(GenerationSpec) \
declare_toplevel_type(HeapWord) \
declare_toplevel_type(MemRegion) \
- declare_toplevel_type(const MemRegion) \
declare_toplevel_type(PermanentGenerationSpec) \
declare_toplevel_type(ThreadLocalAllocBuffer) \
declare_toplevel_type(VirtualSpace) \
@@ -1267,6 +1541,12 @@
declare_toplevel_type(SystemDictionary) \
declare_toplevel_type(ProtectionDomainEntry) \
\
+ declare_toplevel_type(GenericGrowableArray) \
+ declare_toplevel_type(GrowableArray<int>) \
+ declare_toplevel_type(Arena) \
+ declare_type(ResourceArea, Arena) \
+ declare_toplevel_type(Chunk) \
+ \
/***********************************************************/ \
/* Thread hierarchy (needed for run-time type information) */ \
/***********************************************************/ \
@@ -1279,7 +1559,7 @@
declare_type(JavaThread, Thread) \
declare_type(JvmtiAgentThread, JavaThread) \
declare_type(ServiceThread, JavaThread) \
- declare_type(CompilerThread, JavaThread) \
+ declare_type(CompilerThread, JavaThread) \
declare_toplevel_type(OSThread) \
declare_toplevel_type(JavaFrameAnchor) \
\
@@ -1345,6 +1625,11 @@
/***************************************/ \
\
declare_toplevel_type(PcDesc) \
+ declare_toplevel_type(ExceptionCache) \
+ declare_toplevel_type(PcDescCache) \
+ declare_toplevel_type(Dependencies) \
+ declare_toplevel_type(CompileTask) \
+ declare_toplevel_type(Deoptimization) \
\
/************************/ \
/* OopMap and OopMapSet */ \
@@ -1371,6 +1656,7 @@
\
declare_toplevel_type(JNIHandles) \
declare_toplevel_type(JNIHandleBlock) \
+ declare_toplevel_type(jobject) \
\
/**********************/ \
/* Runtime1 (C1 only) */ \
@@ -1391,9 +1677,349 @@
/* Matcher (C2 only) */ \
/*********************/ \
\
- /* NOTE: this is not really a toplevel type, but we only need */ \
- /* this one -- FIXME later if necessary */ \
declare_c2_toplevel_type(Matcher) \
+ declare_c2_toplevel_type(Compile) \
+ declare_c2_toplevel_type(InlineTree) \
+ declare_c2_toplevel_type(OptoRegPair) \
+ declare_c2_toplevel_type(JVMState) \
+ declare_c2_toplevel_type(Phase) \
+ declare_c2_type(PhaseCFG, Phase) \
+ declare_c2_type(PhaseRegAlloc, Phase) \
+ declare_c2_type(PhaseChaitin, PhaseRegAlloc) \
+ declare_c2_toplevel_type(CFGElement) \
+ declare_c2_type(Block, CFGElement) \
+ declare_c2_toplevel_type(Block_Array) \
+ declare_c2_type(Block_List, Block_Array) \
+ declare_c2_toplevel_type(Node_Array) \
+ declare_c2_type(Node_List, Node_Array) \
+ declare_c2_type(Unique_Node_List, Node_List) \
+ declare_c2_toplevel_type(Node) \
+ declare_c2_type(AddNode, Node) \
+ declare_c2_type(AddINode, AddNode) \
+ declare_c2_type(AddLNode, AddNode) \
+ declare_c2_type(AddFNode, AddNode) \
+ declare_c2_type(AddDNode, AddNode) \
+ declare_c2_type(AddPNode, Node) \
+ declare_c2_type(OrINode, AddNode) \
+ declare_c2_type(OrLNode, AddNode) \
+ declare_c2_type(XorINode, AddNode) \
+ declare_c2_type(XorLNode, AddNode) \
+ declare_c2_type(MaxNode, AddNode) \
+ declare_c2_type(MaxINode, MaxNode) \
+ declare_c2_type(MinINode, MaxNode) \
+ declare_c2_type(StartNode, MultiNode) \
+ declare_c2_type(StartOSRNode, StartNode) \
+ declare_c2_type(ParmNode, ProjNode) \
+ declare_c2_type(ReturnNode, Node) \
+ declare_c2_type(RethrowNode, Node) \
+ declare_c2_type(TailCallNode, ReturnNode) \
+ declare_c2_type(TailJumpNode, ReturnNode) \
+ declare_c2_type(SafePointNode, MultiNode) \
+ declare_c2_type(CallNode, SafePointNode) \
+ declare_c2_type(CallJavaNode, CallNode) \
+ declare_c2_type(CallStaticJavaNode, CallJavaNode) \
+ declare_c2_type(CallDynamicJavaNode, CallJavaNode) \
+ declare_c2_type(CallRuntimeNode, CallNode) \
+ declare_c2_type(CallLeafNode, CallRuntimeNode) \
+ declare_c2_type(CallLeafNoFPNode, CallLeafNode) \
+ declare_c2_type(AllocateNode, CallNode) \
+ declare_c2_type(AllocateArrayNode, AllocateNode) \
+ declare_c2_type(LockNode, AbstractLockNode) \
+ declare_c2_type(UnlockNode, AbstractLockNode) \
+ declare_c2_type(FastLockNode, CmpNode) \
+ declare_c2_type(FastUnlockNode, CmpNode) \
+ declare_c2_type(RegionNode, Node) \
+ declare_c2_type(JProjNode, ProjNode) \
+ declare_c2_type(PhiNode, TypeNode) \
+ declare_c2_type(GotoNode, Node) \
+ declare_c2_type(CProjNode, ProjNode) \
+ declare_c2_type(MultiBranchNode, MultiNode) \
+ declare_c2_type(IfNode, MultiBranchNode) \
+ declare_c2_type(IfTrueNode, CProjNode) \
+ declare_c2_type(IfFalseNode, CProjNode) \
+ declare_c2_type(PCTableNode, MultiBranchNode) \
+ declare_c2_type(JumpNode, PCTableNode) \
+ declare_c2_type(JumpProjNode, JProjNode) \
+ declare_c2_type(CatchNode, PCTableNode) \
+ declare_c2_type(CatchProjNode, CProjNode) \
+ declare_c2_type(CreateExNode, TypeNode) \
+ declare_c2_type(ClearArrayNode, Node) \
+ declare_c2_type(NeverBranchNode, MultiBranchNode) \
+ declare_c2_type(ConNode, TypeNode) \
+ declare_c2_type(ConINode, ConNode) \
+ declare_c2_type(ConPNode, ConNode) \
+ declare_c2_type(ConNNode, ConNode) \
+ declare_c2_type(ConLNode, ConNode) \
+ declare_c2_type(ConFNode, ConNode) \
+ declare_c2_type(ConDNode, ConNode) \
+ declare_c2_type(BinaryNode, Node) \
+ declare_c2_type(CMoveNode, TypeNode) \
+ declare_c2_type(CMoveDNode, CMoveNode) \
+ declare_c2_type(CMoveFNode, CMoveNode) \
+ declare_c2_type(CMoveINode, CMoveNode) \
+ declare_c2_type(CMoveLNode, CMoveNode) \
+ declare_c2_type(CMovePNode, CMoveNode) \
+ declare_c2_type(CMoveNNode, CMoveNode) \
+ declare_c2_type(EncodePNode, TypeNode) \
+ declare_c2_type(DecodeNNode, TypeNode) \
+ declare_c2_type(ConstraintCastNode, TypeNode) \
+ declare_c2_type(CastIINode, ConstraintCastNode) \
+ declare_c2_type(CastPPNode, ConstraintCastNode) \
+ declare_c2_type(CheckCastPPNode, TypeNode) \
+ declare_c2_type(Conv2BNode, Node) \
+ declare_c2_type(ConvD2FNode, Node) \
+ declare_c2_type(ConvD2INode, Node) \
+ declare_c2_type(ConvD2LNode, Node) \
+ declare_c2_type(ConvF2DNode, Node) \
+ declare_c2_type(ConvF2INode, Node) \
+ declare_c2_type(ConvF2LNode, Node) \
+ declare_c2_type(ConvI2DNode, Node) \
+ declare_c2_type(ConvI2FNode, Node) \
+ declare_c2_type(ConvI2LNode, TypeNode) \
+ declare_c2_type(ConvL2DNode, Node) \
+ declare_c2_type(ConvL2FNode, Node) \
+ declare_c2_type(ConvL2INode, Node) \
+ declare_c2_type(CastX2PNode, Node) \
+ declare_c2_type(CastP2XNode, Node) \
+ declare_c2_type(MemBarNode, MultiNode) \
+ declare_c2_type(MemBarAcquireNode, MemBarNode) \
+ declare_c2_type(MemBarReleaseNode, MemBarNode) \
+ declare_c2_type(MemBarVolatileNode, MemBarNode) \
+ declare_c2_type(MemBarCPUOrderNode, MemBarNode) \
+ declare_c2_type(InitializeNode, MemBarNode) \
+ declare_c2_type(ThreadLocalNode, Node) \
+ declare_c2_type(Opaque1Node, Node) \
+ declare_c2_type(Opaque2Node, Node) \
+ declare_c2_type(PartialSubtypeCheckNode, Node) \
+ declare_c2_type(MoveI2FNode, Node) \
+ declare_c2_type(MoveL2DNode, Node) \
+ declare_c2_type(MoveF2INode, Node) \
+ declare_c2_type(MoveD2LNode, Node) \
+ declare_c2_type(DivINode, Node) \
+ declare_c2_type(DivLNode, Node) \
+ declare_c2_type(DivFNode, Node) \
+ declare_c2_type(DivDNode, Node) \
+ declare_c2_type(ModINode, Node) \
+ declare_c2_type(ModLNode, Node) \
+ declare_c2_type(ModFNode, Node) \
+ declare_c2_type(ModDNode, Node) \
+ declare_c2_type(DivModNode, MultiNode) \
+ declare_c2_type(DivModINode, DivModNode) \
+ declare_c2_type(DivModLNode, DivModNode) \
+ declare_c2_type(BoxLockNode, Node) \
+ declare_c2_type(LoopNode, RegionNode) \
+ declare_c2_type(CountedLoopNode, LoopNode) \
+ declare_c2_type(CountedLoopEndNode, IfNode) \
+ declare_c2_type(MachNode, Node) \
+ declare_c2_type(MachIdealNode, MachNode) \
+ declare_c2_type(MachTypeNode, MachNode) \
+ declare_c2_type(MachBreakpointNode, MachIdealNode) \
+ declare_c2_type(MachUEPNode, MachIdealNode) \
+ declare_c2_type(MachPrologNode, MachIdealNode) \
+ declare_c2_type(MachEpilogNode, MachIdealNode) \
+ declare_c2_type(MachNopNode, MachIdealNode) \
+ declare_c2_type(MachSpillCopyNode, MachIdealNode) \
+ declare_c2_type(MachNullCheckNode, MachIdealNode) \
+ declare_c2_type(MachProjNode, ProjNode) \
+ declare_c2_type(MachIfNode, MachNode) \
+ declare_c2_type(MachFastLockNode, MachNode) \
+ declare_c2_type(MachReturnNode, MachNode) \
+ declare_c2_type(MachSafePointNode, MachReturnNode) \
+ declare_c2_type(MachCallNode, MachSafePointNode) \
+ declare_c2_type(MachCallJavaNode, MachCallNode) \
+ declare_c2_type(MachCallStaticJavaNode, MachCallJavaNode) \
+ declare_c2_type(MachCallDynamicJavaNode, MachCallJavaNode) \
+ declare_c2_type(MachCallRuntimeNode, MachCallNode) \
+ declare_c2_type(MachHaltNode, MachReturnNode) \
+ declare_c2_type(MachTempNode, MachNode) \
+ declare_c2_type(MemNode, Node) \
+ declare_c2_type(MergeMemNode, Node) \
+ declare_c2_type(LoadNode, MemNode) \
+ declare_c2_type(LoadBNode, LoadNode) \
+ declare_c2_type(LoadUSNode, LoadNode) \
+ declare_c2_type(LoadINode, LoadNode) \
+ declare_c2_type(LoadRangeNode, LoadINode) \
+ declare_c2_type(LoadLNode, LoadNode) \
+ declare_c2_type(LoadL_unalignedNode, LoadLNode) \
+ declare_c2_type(LoadFNode, LoadNode) \
+ declare_c2_type(LoadDNode, LoadNode) \
+ declare_c2_type(LoadD_unalignedNode, LoadDNode) \
+ declare_c2_type(LoadPNode, LoadNode) \
+ declare_c2_type(LoadNNode, LoadNode) \
+ declare_c2_type(LoadKlassNode, LoadPNode) \
+ declare_c2_type(LoadNKlassNode, LoadNNode) \
+ declare_c2_type(LoadSNode, LoadNode) \
+ declare_c2_type(StoreNode, MemNode) \
+ declare_c2_type(StoreBNode, StoreNode) \
+ declare_c2_type(StoreCNode, StoreNode) \
+ declare_c2_type(StoreINode, StoreNode) \
+ declare_c2_type(StoreLNode, StoreNode) \
+ declare_c2_type(StoreFNode, StoreNode) \
+ declare_c2_type(StoreDNode, StoreNode) \
+ declare_c2_type(StorePNode, StoreNode) \
+ declare_c2_type(StoreNNode, StoreNode) \
+ declare_c2_type(StoreCMNode, StoreNode) \
+ declare_c2_type(LoadPLockedNode, LoadPNode) \
+ declare_c2_type(LoadLLockedNode, LoadLNode) \
+ declare_c2_type(SCMemProjNode, ProjNode) \
+ declare_c2_type(LoadStoreNode, Node) \
+ declare_c2_type(StorePConditionalNode, LoadStoreNode) \
+ declare_c2_type(StoreLConditionalNode, LoadStoreNode) \
+ declare_c2_type(CompareAndSwapLNode, LoadStoreNode) \
+ declare_c2_type(CompareAndSwapINode, LoadStoreNode) \
+ declare_c2_type(CompareAndSwapPNode, LoadStoreNode) \
+ declare_c2_type(CompareAndSwapNNode, LoadStoreNode) \
+ declare_c2_type(PrefetchReadNode, Node) \
+ declare_c2_type(PrefetchWriteNode, Node) \
+ declare_c2_type(MulNode, Node) \
+ declare_c2_type(MulINode, MulNode) \
+ declare_c2_type(MulLNode, MulNode) \
+ declare_c2_type(MulFNode, MulNode) \
+ declare_c2_type(MulDNode, MulNode) \
+ declare_c2_type(MulHiLNode, Node) \
+ declare_c2_type(AndINode, MulINode) \
+ declare_c2_type(AndLNode, MulLNode) \
+ declare_c2_type(LShiftINode, Node) \
+ declare_c2_type(LShiftLNode, Node) \
+ declare_c2_type(RShiftINode, Node) \
+ declare_c2_type(RShiftLNode, Node) \
+ declare_c2_type(URShiftINode, Node) \
+ declare_c2_type(URShiftLNode, Node) \
+ declare_c2_type(MultiNode, Node) \
+ declare_c2_type(ProjNode, Node) \
+ declare_c2_type(TypeNode, Node) \
+ declare_c2_type(NodeHash, StackObj) \
+ declare_c2_type(RootNode, LoopNode) \
+ declare_c2_type(HaltNode, Node) \
+ declare_c2_type(SubNode, Node) \
+ declare_c2_type(SubINode, SubNode) \
+ declare_c2_type(SubLNode, SubNode) \
+ declare_c2_type(SubFPNode, SubNode) \
+ declare_c2_type(SubFNode, SubFPNode) \
+ declare_c2_type(SubDNode, SubFPNode) \
+ declare_c2_type(CmpNode, SubNode) \
+ declare_c2_type(CmpINode, CmpNode) \
+ declare_c2_type(CmpUNode, CmpNode) \
+ declare_c2_type(CmpPNode, CmpNode) \
+ declare_c2_type(CmpNNode, CmpNode) \
+ declare_c2_type(CmpLNode, CmpNode) \
+ declare_c2_type(CmpL3Node, CmpLNode) \
+ declare_c2_type(CmpFNode, CmpNode) \
+ declare_c2_type(CmpF3Node, CmpFNode) \
+ declare_c2_type(CmpDNode, CmpNode) \
+ declare_c2_type(CmpD3Node, CmpDNode) \
+ declare_c2_type(BoolNode, Node) \
+ declare_c2_type(AbsNode, Node) \
+ declare_c2_type(AbsINode, AbsNode) \
+ declare_c2_type(AbsFNode, AbsNode) \
+ declare_c2_type(AbsDNode, AbsNode) \
+ declare_c2_type(CmpLTMaskNode, Node) \
+ declare_c2_type(NegNode, Node) \
+ declare_c2_type(NegFNode, NegNode) \
+ declare_c2_type(NegDNode, NegNode) \
+ declare_c2_type(CosDNode, Node) \
+ declare_c2_type(SinDNode, Node) \
+ declare_c2_type(TanDNode, Node) \
+ declare_c2_type(AtanDNode, Node) \
+ declare_c2_type(SqrtDNode, Node) \
+ declare_c2_type(ExpDNode, Node) \
+ declare_c2_type(LogDNode, Node) \
+ declare_c2_type(Log10DNode, Node) \
+ declare_c2_type(PowDNode, Node) \
+ declare_c2_type(ReverseBytesINode, Node) \
+ declare_c2_type(ReverseBytesLNode, Node) \
+ declare_c2_type(VectorNode, Node) \
+ declare_c2_type(AddVBNode, VectorNode) \
+ declare_c2_type(AddVCNode, VectorNode) \
+ declare_c2_type(AddVSNode, VectorNode) \
+ declare_c2_type(AddVINode, VectorNode) \
+ declare_c2_type(AddVLNode, VectorNode) \
+ declare_c2_type(AddVFNode, VectorNode) \
+ declare_c2_type(AddVDNode, VectorNode) \
+ declare_c2_type(SubVBNode, VectorNode) \
+ declare_c2_type(SubVCNode, VectorNode) \
+ declare_c2_type(SubVSNode, VectorNode) \
+ declare_c2_type(SubVINode, VectorNode) \
+ declare_c2_type(SubVLNode, VectorNode) \
+ declare_c2_type(SubVFNode, VectorNode) \
+ declare_c2_type(SubVDNode, VectorNode) \
+ declare_c2_type(MulVFNode, VectorNode) \
+ declare_c2_type(MulVDNode, VectorNode) \
+ declare_c2_type(DivVFNode, VectorNode) \
+ declare_c2_type(DivVDNode, VectorNode) \
+ declare_c2_type(LShiftVBNode, VectorNode) \
+ declare_c2_type(LShiftVCNode, VectorNode) \
+ declare_c2_type(LShiftVSNode, VectorNode) \
+ declare_c2_type(LShiftVINode, VectorNode) \
+ declare_c2_type(URShiftVBNode, VectorNode) \
+ declare_c2_type(URShiftVCNode, VectorNode) \
+ declare_c2_type(URShiftVSNode, VectorNode) \
+ declare_c2_type(URShiftVINode, VectorNode) \
+ declare_c2_type(AndVNode, VectorNode) \
+ declare_c2_type(OrVNode, VectorNode) \
+ declare_c2_type(XorVNode, VectorNode) \
+ declare_c2_type(VectorLoadNode, LoadNode) \
+ declare_c2_type(Load16BNode, VectorLoadNode) \
+ declare_c2_type(Load8BNode, VectorLoadNode) \
+ declare_c2_type(Load4BNode, VectorLoadNode) \
+ declare_c2_type(Load8CNode, VectorLoadNode) \
+ declare_c2_type(Load4CNode, VectorLoadNode) \
+ declare_c2_type(Load2CNode, VectorLoadNode) \
+ declare_c2_type(Load8SNode, VectorLoadNode) \
+ declare_c2_type(Load4SNode, VectorLoadNode) \
+ declare_c2_type(Load2SNode, VectorLoadNode) \
+ declare_c2_type(Load4INode, VectorLoadNode) \
+ declare_c2_type(Load2INode, VectorLoadNode) \
+ declare_c2_type(Load2LNode, VectorLoadNode) \
+ declare_c2_type(Load4FNode, VectorLoadNode) \
+ declare_c2_type(Load2FNode, VectorLoadNode) \
+ declare_c2_type(Load2DNode, VectorLoadNode) \
+ declare_c2_type(VectorStoreNode, StoreNode) \
+ declare_c2_type(Store16BNode, VectorStoreNode) \
+ declare_c2_type(Store8BNode, VectorStoreNode) \
+ declare_c2_type(Store4BNode, VectorStoreNode) \
+ declare_c2_type(Store8CNode, VectorStoreNode) \
+ declare_c2_type(Store4CNode, VectorStoreNode) \
+ declare_c2_type(Store2CNode, VectorStoreNode) \
+ declare_c2_type(Store4INode, VectorStoreNode) \
+ declare_c2_type(Store2INode, VectorStoreNode) \
+ declare_c2_type(Store2LNode, VectorStoreNode) \
+ declare_c2_type(Store4FNode, VectorStoreNode) \
+ declare_c2_type(Store2FNode, VectorStoreNode) \
+ declare_c2_type(Store2DNode, VectorStoreNode) \
+ declare_c2_type(Replicate16BNode, VectorNode) \
+ declare_c2_type(Replicate8BNode, VectorNode) \
+ declare_c2_type(Replicate4BNode, VectorNode) \
+ declare_c2_type(Replicate8CNode, VectorNode) \
+ declare_c2_type(Replicate4CNode, VectorNode) \
+ declare_c2_type(Replicate2CNode, VectorNode) \
+ declare_c2_type(Replicate8SNode, VectorNode) \
+ declare_c2_type(Replicate4SNode, VectorNode) \
+ declare_c2_type(Replicate2SNode, VectorNode) \
+ declare_c2_type(Replicate4INode, VectorNode) \
+ declare_c2_type(Replicate2INode, VectorNode) \
+ declare_c2_type(Replicate2LNode, VectorNode) \
+ declare_c2_type(Replicate4FNode, VectorNode) \
+ declare_c2_type(Replicate2FNode, VectorNode) \
+ declare_c2_type(Replicate2DNode, VectorNode) \
+ declare_c2_type(PackNode, VectorNode) \
+ declare_c2_type(PackBNode, PackNode) \
+ declare_c2_type(PackCNode, PackNode) \
+ declare_c2_type(PackSNode, PackNode) \
+ declare_c2_type(PackINode, PackNode) \
+ declare_c2_type(PackLNode, PackNode) \
+ declare_c2_type(PackFNode, PackNode) \
+ declare_c2_type(PackDNode, PackNode) \
+ declare_c2_type(Pack2x1BNode, PackNode) \
+ declare_c2_type(Pack2x2BNode, PackNode) \
+ declare_c2_type(ExtractNode, Node) \
+ declare_c2_type(ExtractBNode, ExtractNode) \
+ declare_c2_type(ExtractCNode, ExtractNode) \
+ declare_c2_type(ExtractSNode, ExtractNode) \
+ declare_c2_type(ExtractINode, ExtractNode) \
+ declare_c2_type(ExtractLNode, ExtractNode) \
+ declare_c2_type(ExtractFNode, ExtractNode) \
+ declare_c2_type(ExtractDNode, ExtractNode) \
\
/*********************/ \
/* Adapter Blob Entries */ \
@@ -1401,6 +2027,32 @@
declare_toplevel_type(AdapterHandlerEntry) \
declare_toplevel_type(AdapterHandlerEntry*) \
\
+ /*********************/ \
+ /* CI */ \
+ /*********************/ \
+ declare_toplevel_type(ciEnv) \
+ declare_toplevel_type(ciObjectFactory) \
+ declare_toplevel_type(ciConstant) \
+ declare_toplevel_type(ciField) \
+ declare_toplevel_type(void*) \
+ declare_toplevel_type(ciObject) \
+ declare_type(ciMethod, ciObject) \
+ declare_type(ciMethodData, ciObject) \
+ declare_type(ciType, ciObject) \
+ declare_type(ciInstance, ciObject) \
+ declare_toplevel_type(ciSymbol) \
+ declare_type(ciKlass, ciType) \
+ declare_type(ciInstanceKlass, ciKlass) \
+ declare_type(ciArrayKlass, ciKlass) \
+ declare_type(ciTypeArrayKlass, ciArrayKlass) \
+ declare_type(ciObjArrayKlass, ciArrayKlass) \
+ declare_type(ciMethodKlass, ciKlass) \
+ declare_type(ciKlassKlass, ciKlass) \
+ declare_type(ciInstanceKlassKlass, ciKlassKlass) \
+ declare_type(ciArrayKlassKlass, ciKlassKlass) \
+ declare_type(ciTypeArrayKlassKlass, ciArrayKlassKlass) \
+ declare_type(ciObjArrayKlassKlass, ciArrayKlassKlass) \
+ \
/********************/ \
/* -XX flags */ \
/********************/ \
@@ -1409,6 +2061,12 @@
declare_toplevel_type(Flag*) \
\
/********************/ \
+ /* JVMTI */ \
+ /********************/ \
+ \
+ declare_toplevel_type(JvmtiExport) \
+ \
+ /********************/ \
/* JDK/VM version */ \
/********************/ \
\
@@ -1434,19 +2092,24 @@
declare_integer_type(Location::Type) \
declare_integer_type(Location::Where) \
declare_integer_type(PermGen::Name) \
+ declare_integer_type(FlagValueOrigin) \
+ COMPILER2_PRESENT(declare_integer_type(OptoReg::Name)) \
\
declare_integer_type(AccessFlags) /* FIXME: wrong type (not integer) */\
declare_toplevel_type(address) /* FIXME: should this be an integer type? */\
+ declare_integer_type(BasicType) /* FIXME: wrong type (not integer) */\
declare_toplevel_type(BreakpointInfo) \
declare_toplevel_type(BreakpointInfo*) \
declare_toplevel_type(CodeBlob*) \
declare_toplevel_type(CompressedWriteStream*) \
declare_toplevel_type(ConstantPoolCacheEntry) \
declare_toplevel_type(elapsedTimer) \
+ declare_toplevel_type(frame) \
declare_toplevel_type(intptr_t*) \
declare_unsigned_integer_type(InvocationCounter) /* FIXME: wrong type (not integer) */ \
declare_toplevel_type(JavaThread*) \
declare_toplevel_type(java_lang_Class) \
+ declare_integer_type(JavaThread::AsyncRequests) \
declare_toplevel_type(jbyte*) \
declare_toplevel_type(jbyte**) \
declare_toplevel_type(jint*) \
@@ -1459,6 +2122,7 @@
declare_toplevel_type(jmethodID*) \
declare_toplevel_type(Mutex*) \
declare_toplevel_type(nmethod*) \
+ COMPILER2_PRESENT(declare_unsigned_integer_type(node_idx_t)) \
declare_toplevel_type(ObjectMonitor*) \
declare_toplevel_type(oop*) \
declare_toplevel_type(OopMap**) \
@@ -1469,7 +2133,10 @@
declare_integer_type(ReferenceType) \
declare_toplevel_type(StubQueue*) \
declare_toplevel_type(Thread*) \
- declare_toplevel_type(Universe)
+ declare_toplevel_type(Universe) \
+ declare_toplevel_type(vframeArray) \
+ declare_toplevel_type(vframeArrayElement)
+
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must be */
@@ -1662,18 +2329,23 @@
declare_constant(constMethodOopDesc::_has_localvariable_table) \
\
/*************************************/ \
- /* instanceKlass FieldOffset enum */ \
+ /* instanceKlass enum */ \
+ /*************************************/ \
+ \
+ declare_constant(instanceKlass::implementors_limit) \
+ \
+ /*************************************/ \
+ /* FieldInfo FieldOffset enum */ \
/*************************************/ \
\
- declare_constant(instanceKlass::access_flags_offset) \
- declare_constant(instanceKlass::name_index_offset) \
- declare_constant(instanceKlass::signature_index_offset) \
- declare_constant(instanceKlass::initval_index_offset) \
- declare_constant(instanceKlass::low_offset) \
- declare_constant(instanceKlass::high_offset) \
- declare_constant(instanceKlass::generic_signature_offset) \
- declare_constant(instanceKlass::next_offset) \
- declare_constant(instanceKlass::implementors_limit) \
+ declare_constant(FieldInfo::access_flags_offset) \
+ declare_constant(FieldInfo::name_index_offset) \
+ declare_constant(FieldInfo::signature_index_offset) \
+ declare_constant(FieldInfo::initval_index_offset) \
+ declare_constant(FieldInfo::low_offset) \
+ declare_constant(FieldInfo::high_offset) \
+ declare_constant(FieldInfo::generic_signature_offset) \
+ declare_constant(FieldInfo::field_slots) \
\
/************************************************/ \
/* instanceKlass InnerClassAttributeOffset enum */ \
@@ -1769,6 +2441,27 @@
declare_constant(Location::on_stack) \
declare_constant(Location::in_register) \
\
+ declare_constant(Deoptimization::Reason_many) \
+ declare_constant(Deoptimization::Reason_none) \
+ declare_constant(Deoptimization::Reason_null_check) \
+ declare_constant(Deoptimization::Reason_null_assert) \
+ declare_constant(Deoptimization::Reason_range_check) \
+ declare_constant(Deoptimization::Reason_class_check) \
+ declare_constant(Deoptimization::Reason_array_check) \
+ declare_constant(Deoptimization::Reason_intrinsic) \
+ declare_constant(Deoptimization::Reason_bimorphic) \
+ declare_constant(Deoptimization::Reason_unloaded) \
+ declare_constant(Deoptimization::Reason_uninitialized) \
+ declare_constant(Deoptimization::Reason_unreached) \
+ declare_constant(Deoptimization::Reason_unhandled) \
+ declare_constant(Deoptimization::Reason_constraint) \
+ declare_constant(Deoptimization::Reason_div0_check) \
+ declare_constant(Deoptimization::Reason_age) \
+ declare_constant(Deoptimization::Reason_predicate) \
+ declare_constant(Deoptimization::Reason_loop_limit_check) \
+ declare_constant(Deoptimization::Reason_LIMIT) \
+ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \
+ \
/*********************/ \
/* Matcher (C2 only) */ \
/*********************/ \
@@ -2472,12 +3165,14 @@
{
VMTypeEntry* types = origtypes;
while (types->typeName != NULL) {
- if (!strcmp(typeName, types->typeName)) {
+ if (strcmp(typeName, types->typeName) == 0) {
+ // Found it
return 1;
}
++types;
}
}
+ // Search for the base type by peeling off const and *
size_t len = strlen(typeName);
if (typeName[len-1] == '*') {
char * s = new char[len];
@@ -2522,7 +3217,7 @@
if (!isRecurse) {
tty->print_cr("type \"%s\" not found", typeName);
}
- return 2;
+ return 0;
}
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -79,9 +79,14 @@
// Note that the class-related ACC_ANNOTATION bit conflicts with these flags.
JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI
JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI
+ JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT
+
+ JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED |
+ JVM_ACC_FIELD_MODIFICATION_WATCHED |
+ JVM_ACC_FIELD_INTERNAL,
// flags accepted by set_field_flags()
- JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS
+ JVM_ACC_FIELD_FLAGS = JVM_RECOGNIZED_FIELD_MODIFIERS | JVM_ACC_FIELD_INTERNAL_FLAGS
};
@@ -150,13 +155,17 @@
bool is_field_access_watched() const { return (_flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; }
bool is_field_modification_watched() const
{ return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
+ bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; }
// get .class file flags
jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); }
// Initialization
void add_promoted_flags(jint flags) { _flags |= (flags & JVM_ACC_PROMOTED_FLAGS); }
- void set_field_flags(jint flags) { _flags = (flags & JVM_ACC_FIELD_FLAGS); }
+ void set_field_flags(jint flags) {
+ assert((flags & JVM_ACC_FIELD_FLAGS) == flags, "only recognized flags");
+ _flags = (flags & JVM_ACC_FIELD_FLAGS);
+ }
void set_flags(jint flags) { _flags = (flags & JVM_ACC_WRITTEN_FLAGS); }
void set_queued_for_compilation() { atomic_set_bits(JVM_ACC_QUEUED); }
@@ -218,8 +227,8 @@
}
// Conversion
- jshort as_short() { return (jshort)_flags; }
- jint as_int() { return _flags; }
+ jshort as_short() const { return (jshort)_flags; }
+ jint as_int() const { return _flags; }
inline friend AccessFlags accessFlags_from(jint flags);
--- a/hotspot/src/share/vm/utilities/exceptions.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -58,6 +58,8 @@
// include hierachy reasons).
class ThreadShadow: public CHeapObj {
+ friend class VMStructs;
+
protected:
oop _pending_exception; // Thread has gc actions.
const char* _exception_file; // file information for exception (debugging only)
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Tue Sep 13 20:28:00 2011 -0700
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Thu Sep 15 12:44:09 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,6 +77,8 @@
}
class GenericGrowableArray : public ResourceObj {
+ friend class VMStructs;
+
protected:
int _len; // current length
int _max; // maximum length
@@ -136,6 +138,8 @@
};
template<class E> class GrowableArray : public GenericGrowableArray {
+ friend class VMStructs;
+
private:
E* _data; // data array
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7068051/Test7068051.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7068051
+ * @summary SIGSEGV in PhaseIdealLoop::build_loop_late_post on T5440
+ *
+ * @run shell/timeout=300 Test7068051.sh
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.util.zip.*;
+
+public class Test7068051 {
+
+ public static void main (String[] args) throws Throwable {
+
+ ZipFile zf = new ZipFile(args[0]);
+
+ Enumeration<? extends ZipEntry> entries = zf.entries();
+ ArrayList<String> names = new ArrayList<String>();
+ while (entries.hasMoreElements()) {
+ names.add(entries.nextElement().getName());
+ }
+
+ byte[] bytes = new byte[16];
+ for (String name : names) {
+ ZipEntry e = zf.getEntry(name);
+
+ if (e.isDirectory())
+ continue;
+
+ final InputStream is = zf.getInputStream(e);
+
+ try {
+ while (is.read(bytes) >= 0) {
+ }
+ is.close();
+
+ } catch (IOException x) {
+ System.out.println("..................................");
+ System.out.println(" --> is :" + is);
+ System.out.println(" is.hash :" + is.hashCode());
+ System.out.println();
+ System.out.println(" e.name :" + e.getName());
+ System.out.println(" e.hash :" + e.hashCode());
+ System.out.println(" e.method :" + e.getMethod());
+ System.out.println(" e.size :" + e.getSize());
+ System.out.println(" e.csize :" + e.getCompressedSize());
+
+ x.printStackTrace();
+ System.out.println("..................................");
+ System.exit(97);
+ }
+ }
+ zf.close();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7068051/Test7068051.sh Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+echo "TESTSRC=${TESTSRC}"
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+echo "TESTJAVA=${TESTJAVA}"
+
+set -x
+
+${TESTJAVA}/bin/jar xf ${TESTJAVA}/jre/lib/javaws.jar
+${TESTJAVA}/bin/jar cf foo.jar *
+cp ${TESTSRC}/Test7068051.java ./
+${TESTJAVA}/bin/jar -uf0 foo.jar Test7068051.java
+
+${TESTJAVA}/bin/javac -d . Test7068051.java
+
+${TESTJAVA}/bin/java -showversion -Xbatch ${TESTVMOPTS} Test7068051 foo.jar
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7088020/Test7088020.java Thu Sep 15 12:44:09 2011 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7088020
+ * @summary SEGV in JNIHandleBlock::release_block
+ *
+ * @run main Test7088020
+ */
+
+import java.lang.invoke.*;
+
+
+public class Test7088020 {
+ public static boolean test() {
+ return false;
+ }
+
+ public static void main(String... args) throws Throwable {
+ MethodHandle test = MethodHandles.lookup().findStatic(Test7088020.class, "test", MethodType.methodType(Boolean.TYPE));
+
+ // Exercise WMT with different argument alignments
+ int thrown = 0;
+ try {
+ test.invokeExact(0);
+ } catch (WrongMethodTypeException wmt) {
+ thrown++;
+ if (wmt.getStackTrace().length < 1) throw new InternalError("missing stack frames");
+ }
+ try {
+ test.invokeExact(0, 1);
+ } catch (WrongMethodTypeException wmt) {
+ thrown++;
+ if (wmt.getStackTrace().length < 1) throw new InternalError("missing stack frames");
+ }
+ try {
+ test.invokeExact(0, 1, 2);
+ } catch (WrongMethodTypeException wmt) {
+ thrown++;
+ if (wmt.getStackTrace().length < 1) throw new InternalError("missing stack frames");
+ }
+ try {
+ test.invokeExact(0, 1, 2, 3);
+ } catch (WrongMethodTypeException wmt) {
+ thrown++;
+ if (wmt.getStackTrace().length < 1) throw new InternalError("missing stack frames");
+ }
+ try {
+ thrown++;
+ test.invokeExact(0, 1, 2, 3, 4);
+ } catch (WrongMethodTypeException wmt) {
+ if (wmt.getStackTrace().length < 1) throw new InternalError("missing stack frames");
+ }
+ if (thrown != 5) {
+ throw new InternalError("not enough throws");
+ }
+ }
+}