# HG changeset patch # User ysr # Date 1292533011 28800 # Node ID 320ef6401fcefaa4c559da220f558814d7b43f77 # Parent 36eef023306ffbe5ababf11e091eebb6a1509804# Parent 6ce496c8fc07b87854205e85d3338761074b6ab7 Merge diff -r 36eef023306f -r 320ef6401fce make/linux/makefiles/build_vm_def.sh --- a/make/linux/makefiles/build_vm_def.sh Thu Dec 16 09:14:34 2010 -0800 +++ b/make/linux/makefiles/build_vm_def.sh Thu Dec 16 12:56:51 2010 -0800 @@ -1,7 +1,7 @@ #!/bin/sh # If we're cross compiling use that path for nm -if [ "$ALT_COMPILER_PATH" != "" ]; then +if [ "$CROSS_COMPILE_ARCH" != "" ]; then NM=$ALT_COMPILER_PATH/nm else NM=nm diff -r 36eef023306f -r 320ef6401fce make/linux/makefiles/buildtree.make --- a/make/linux/makefiles/buildtree.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/linux/makefiles/buildtree.make Thu Dec 16 12:56:51 2010 -0800 @@ -124,7 +124,7 @@ BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \ - env.sh env.csh .dbxrc test_gamma + env.sh env.csh jdkpath.sh .dbxrc test_gamma BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \ ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT) @@ -318,6 +318,13 @@ sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \ ) > $@ +jdkpath.sh: $(BUILDTREE_MAKE) + @echo Creating $@ ... + $(QUIETLY) ( \ + $(BUILDTREE_COMMENT); \ + echo "JDK=${JAVA_HOME}"; \ + ) > $@ + .dbxrc: $(BUILDTREE_MAKE) @echo Creating $@ ... $(QUIETLY) ( \ diff -r 36eef023306f -r 320ef6401fce make/linux/makefiles/gcc.make --- a/make/linux/makefiles/gcc.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/linux/makefiles/gcc.make Thu Dec 16 12:56:51 2010 -0800 @@ -25,7 +25,9 @@ #------------------------------------------------------------------------ # CC, CPP & AS -ifdef ALT_COMPILER_PATH +# When cross-compiling the ALT_COMPILER_PATH points +# to the cross-compilation toolset +ifdef CROSS_COMPILE_ARCH CPP = $(ALT_COMPILER_PATH)/g++ CC = $(ALT_COMPILER_PATH)/gcc else diff -r 36eef023306f -r 320ef6401fce make/linux/makefiles/vm.make --- a/make/linux/makefiles/vm.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/linux/makefiles/vm.make Thu Dec 16 12:56:51 2010 -0800 @@ -168,7 +168,9 @@ # Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE. define findsrc - $(notdir $(shell find $(1) \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \) )) + $(notdir $(shell find $(1)/. ! -name . -prune \ + -a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \ + -a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \))) endef Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e))) diff -r 36eef023306f -r 320ef6401fce make/solaris/makefiles/buildtree.make --- a/make/solaris/makefiles/buildtree.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/solaris/makefiles/buildtree.make Thu Dec 16 12:56:51 2010 -0800 @@ -117,7 +117,7 @@ BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \ - env.ksh env.csh .dbxrc test_gamma + env.ksh env.csh jdkpath.sh .dbxrc test_gamma BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \ ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT) @@ -314,6 +314,13 @@ sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \ ) > $@ +jdkpath.sh: $(BUILDTREE_MAKE) + @echo Creating $@ ... + $(QUIETLY) ( \ + $(BUILDTREE_COMMENT); \ + echo "JDK=${JAVA_HOME}"; \ + ) > $@ + .dbxrc: $(BUILDTREE_MAKE) @echo Creating $@ ... $(QUIETLY) ( \ diff -r 36eef023306f -r 320ef6401fce make/solaris/makefiles/vm.make --- a/make/solaris/makefiles/vm.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/solaris/makefiles/vm.make Thu Dec 16 12:56:51 2010 -0800 @@ -106,17 +106,17 @@ # Not sure what the 'designed for' comment is referring too above. # The order may not be too significant anymore, but I have placed this # older libm before libCrun, just to make sure it's found and used first. -LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc +LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc -ldemangle else ifeq ($(COMPILER_REV_NUMERIC), 502) # SC6.1 has it's own libm.so: specifying anything else provokes a name conflict. -LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor +LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor -ldemangle else -LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor +LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor -ldemangle endif # 502 endif # 505 else -LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc +LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle endif # sparcWorks # By default, link the *.o into the library, not the executable. @@ -184,7 +184,9 @@ # Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE. define findsrc - $(notdir $(shell find $(1) \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \) )) + $(notdir $(shell find $(1)/. ! -name . -prune \ + -a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \ + -a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \))) endef Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e))) diff -r 36eef023306f -r 320ef6401fce make/windows/build_vm_def.sh --- a/make/windows/build_vm_def.sh Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/build_vm_def.sh Thu Dec 16 12:56:51 2010 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2010, 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,9 @@ echo "EXPORTS" > vm1.def AWK="$MKS_HOME/awk.exe" +if [ ! -e $AWK ]; then + AWK="$MKS_HOME/gawk.exe" +fi GREP="$MKS_HOME/grep.exe" SORT="$MKS_HOME/sort.exe" UNIQ="$MKS_HOME/uniq.exe" @@ -57,7 +60,7 @@ LINK_VER="$1" fi -if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" ]; then +if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" -a "x$LINK_VER" != "x1000" ]; then $DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$GREP" -v "type_info" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def else # Can't use pipes when calling cl.exe or link.exe from IDE. Using transit file vm3.def diff -r 36eef023306f -r 320ef6401fce make/windows/create.bat --- a/make/windows/create.bat Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/create.bat Thu Dec 16 12:56:51 2010 -0800 @@ -36,6 +36,20 @@ REM Note: Running this batch file from the Windows command shell requires REM that "grep" be accessible on the PATH. An MKS install does this. REM + +cl 2>NUL >NUL +if %errorlevel% == 0 goto nexttest +echo Make sure cl.exe is in your PATH before running this script. +goto end + +:nexttest +grep -V 2>NUL >NUL +if %errorlevel% == 0 goto testit +echo Make sure grep.exe is in your PATH before running this script. Either cygwin or MKS should work. +goto end + + +:testit cl 2>&1 | grep "IA-64" >NUL if %errorlevel% == 0 goto isia64 cl 2>&1 | grep "AMD64" >NUL @@ -44,37 +58,40 @@ set BUILDARCH=i486 set Platform_arch=x86 set Platform_arch_model=x86_32 -goto end +goto done :amd64 set ARCH=x86 set BUILDARCH=amd64 set Platform_arch=x86 set Platform_arch_model=x86_64 -goto end +goto done :isia64 set ARCH=ia64 set BUILDARCH=ia64 set Platform_arch=ia64 set Platform_arch_model=ia64 -:end +:done setlocal if "%1" == "" goto usage -if not "%4" == "" goto usage +if not "%2" == "" goto usage -set HotSpotWorkSpace=%1 -set HotSpotBuildSpace=%2 -set HotSpotJDKDist=%3 +REM Set HotSpotWorkSpace to the directy two steps above this script +for %%i in ("%~dp0..") do ( set HotSpotWorkSpace=%%~dpi) +set HotSpotBuildRoot=%HotSpotWorkSpace%build +set HotSpotBuildSpace=%HotSpotBuildRoot%\vs +set HotSpotJDKDist=%1 + REM figure out MSC version for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i echo ************************************************************** -set ProjectFile=vm.vcproj +set ProjectFile=jvm.vcproj if "%MSC_VER%" == "1200" ( -set ProjectFile=vm.dsp +set ProjectFile=jvm.dsp echo Will generate VC6 project {unsupported} ) else ( if "%MSC_VER%" == "1400" ( @@ -83,10 +100,16 @@ if "%MSC_VER%" == "1500" ( echo Will generate VC9 {Visual Studio 2008} ) else ( +if "%MSC_VER%" == "1600" ( +echo Detected Visual Studio 2010, but +echo will generate VC9 {Visual Studio 2008} +echo Use conversion wizard in VS 2010. +) else ( echo Will generate VC7 project {Visual Studio 2003 .NET} ) ) ) +) echo %ProjectFile% echo ************************************************************** @@ -118,6 +141,8 @@ :test3 if not "%HOTSPOTMKSHOME%" == "" goto makedir +if exist c:\cygwin\bin set HOTSPOTMKSHOME=c:\cygwin\bin +if not "%HOTSPOTMKSHOME%" == "" goto makedir echo Warning: please set variable HOTSPOTMKSHOME to place where echo your MKS/Cygwin installation is echo. @@ -133,21 +158,24 @@ REM This is now safe to do. :copyfiles for /D %%i in (compiler1, compiler2, tiered, core, kernel) do ( -if NOT EXIST %HotSpotBuildSpace%\%%i mkdir %HotSpotBuildSpace%\%%i -copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\ > NUL +if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated +copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL ) REM force regneration of ProjectFile if exist %HotSpotBuildSpace%\%ProjectFile% del %HotSpotBuildSpace%\%ProjectFile% for /D %%i in (compiler1, compiler2, tiered, core, kernel) do ( - -echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make +echo -- %%i -- +echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make echo # Changing a variable below and then deleting %ProjectFile% will cause >> %HotSpotBuildSpace%\%%i\local.make echo # %ProjectFile% to be regenerated with the new values. Changing the >> %HotSpotBuildSpace%\%%i\local.make -echo # version requires rerunning create.bat. >> %HotSpotBuildSpace%\%%i\local.make +echo # version requires rerunning create.bat. >> %HotSpotBuildSpace%\%%i\local.make echo. >> %HotSpotBuildSpace%\%%i\local.make +echo Variant=%%i >> %HotSpotBuildSpace%\%%i\local.make +echo WorkSpace=%HotSpotWorkSpace% >> %HotSpotBuildSpace%\%%i\local.make echo HOTSPOTWORKSPACE=%HotSpotWorkSpace% >> %HotSpotBuildSpace%\%%i\local.make +echo HOTSPOTBUILDROOT=%HotSpotBuildRoot% >> %HotSpotBuildSpace%\%%i\local.make echo HOTSPOTBUILDSPACE=%HotSpotBuildSpace% >> %HotSpotBuildSpace%\%%i\local.make echo HOTSPOTJDKDIST=%HotSpotJDKDist% >> %HotSpotBuildSpace%\%%i\local.make echo ARCH=%ARCH% >> %HotSpotBuildSpace%\%%i\local.make @@ -155,42 +183,35 @@ echo Platform_arch=%Platform_arch% >> %HotSpotBuildSpace%\%%i\local.make echo Platform_arch_model=%Platform_arch_model% >> %HotSpotBuildSpace%\%%i\local.make -pushd %HotSpotBuildSpace%\%%i +for /D %%j in (debug, fastdebug, product) do ( +if NOT EXIST %HotSpotBuildSpace%\%%i\%%j mkdir %HotSpotBuildSpace%\%%i\%%j +) + +pushd %HotSpotBuildSpace%\%%i\generated nmake /nologo popd ) -pushd %HotSpotBuildSpace% +pushd %HotSpotBuildRoot% -echo # Generated file! > local.make -echo # Changing a variable below and then deleting %ProjectFile% will cause >> local.make -echo # %ProjectFile% to be regenerated with the new values. Changing the >> local.make -echo # version requires rerunning create.bat. >> local.make -echo. >> local.make -echo HOTSPOTWORKSPACE=%HotSpotWorkSpace% >> local.make -echo HOTSPOTBUILDSPACE=%HotSpotBuildSpace% >> local.make -echo HOTSPOTJDKDIST=%HotSpotJDKDist% >> local.make -echo ARCH=%ARCH% >> local.make -echo BUILDARCH=%BUILDARCH% >> local.make -echo Platform_arch=%Platform_arch% >> local.make -echo Platform_arch_model=%Platform_arch_model% >> local.make - -nmake /nologo /F %HotSpotWorkSpace%/make/windows/projectfiles/common/Makefile %HotSpotBuildSpace%/%ProjectFile% +REM It doesn't matter which variant we use here, "compiler1" is as good as any of the others - we need the common variables +nmake /nologo /F %HotSpotWorkSpace%/make/windows/projectfiles/common/Makefile LOCAL_MAKE=%HotSpotBuildSpace%\compiler1\local.make %HotSpotBuildRoot%/%ProjectFile% popd goto end :usage -echo Usage: create HotSpotWorkSpace HotSpotBuildSpace HotSpotJDKDist +echo Usage: create HotSpotJDKDist echo. -echo This is the interactive build setup script (as opposed to the batch -echo build execution script). It creates HotSpotBuildSpace if necessary, -echo copies the appropriate files out of HotSpotWorkSpace into it, and +echo This is the VS build setup script (as opposed to the batch +echo build execution script). It creates a build directory if necessary, +echo copies the appropriate files out of the workspace into it, and echo builds and runs ProjectCreator in it. This has the side-effect of creating echo the %ProjectFile% file in the build space, which is then used in Visual C++. -echo The HotSpotJDKDist defines place where JVM binaries should be placed. +echo. +echo The HotSpotJDKDist defines the JDK that should be used when running the JVM. echo Environment variable FORCE_MSC_VER allows to override MSVC version autodetection. echo. echo NOTE that it is now NOT safe to modify any of the files in the build diff -r 36eef023306f -r 320ef6401fce make/windows/create_obj_files.sh --- a/make/windows/create_obj_files.sh Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/create_obj_files.sh Thu Dec 16 12:56:51 2010 -0800 @@ -107,8 +107,12 @@ "x86_64") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_32*" ;; esac +# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE. function findsrc { - $FIND ${1} \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name ${Src_Files_EXCLUDE// / -o -name } \) | sed 's/.*\/\(.*\)/\1/'; + $FIND ${1}/. ! -name . -prune \ + -a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \ + -a \! \( -name ${Src_Files_EXCLUDE// / -o -name } \) \ + | sed 's/.*\/\(.*\)/\1/'; } Src_Files= diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/adlc.make --- a/make/windows/makefiles/adlc.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/adlc.make Thu Dec 16 12:56:51 2010 -0800 @@ -22,7 +22,6 @@ # # -!include $(WorkSpace)/make/windows/makefiles/compile.make # Rules for building adlc.exe @@ -46,15 +45,7 @@ ADLCFLAGS=-q -T -U_LP64 !endif -CPP_FLAGS=$(CPP_FLAGS) \ - /D TARGET_OS_FAMILY_windows \ - /D TARGET_ARCH_$(Platform_arch) \ - /D TARGET_ARCH_MODEL_$(Platform_arch_model) \ - /D TARGET_OS_ARCH_windows_$(Platform_arch) \ - /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model) \ - /D TARGET_COMPILER_visCPP - -CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE +ADLC_CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE CPP_INCLUDE_DIRS=\ /I "..\generated" \ @@ -92,10 +83,10 @@ $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp {$(WorkSpace)\src\share\vm\adlc}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $< + $(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $< {$(WorkSpace)\src\share\vm\opto}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $< + $(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $< adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \ forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/compile.make --- a/make/windows/makefiles/compile.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/compile.make Thu Dec 16 12:56:51 2010 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2010, 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 @@ -80,6 +80,20 @@ CPP=ARCH_ERROR !endif +CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS" + +# Must specify this for sharedRuntimeTrig.cpp +CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN" + +# Used for platform dispatching +CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_FAMILY_windows +CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_$(Platform_arch) +CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model) +CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch) +CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model) +CPP_FLAGS=$(CPP_FLAGS) /D TARGET_COMPILER_visCPP + + # MSC_VER is a 4 digit number that tells us what compiler is being used # and is generated when the local.make file is created by build.make # via the script get_msc_ver.sh diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/debug.make --- a/make/windows/makefiles/debug.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/debug.make Thu Dec 16 12:56:51 2010 -0800 @@ -26,7 +26,6 @@ HS_FNAME=$(HS_INTERNAL_NAME).dll AOUT=$(HS_FNAME) SAWINDBG=sawindbg.dll -LAUNCHER_NAME=hotspot.exe GENERATED=../generated # Allow the user to turn off precompiled headers from the command line. @@ -34,7 +33,7 @@ BUILD_PCH_FILE=_build_pch_file.obj !endif -default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA +default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA !include ../local.make !include compile.make @@ -49,8 +48,10 @@ # Force resources to be rebuilt every time $(Res_Files): FORCE -$(AOUT): $(Res_Files) $(Obj_Files) +vm.def: $(Obj_Files) sh $(WorkSpace)/make/windows/build_vm_def.sh + +$(AOUT): $(Res_Files) $(Obj_Files) vm.def $(LINK) @<< $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/fastdebug.make --- a/make/windows/makefiles/fastdebug.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/fastdebug.make Thu Dec 16 12:56:51 2010 -0800 @@ -26,7 +26,6 @@ HS_FNAME=$(HS_INTERNAL_NAME).dll AOUT=$(HS_FNAME) SAWINDBG=sawindbg.dll -LAUNCHER_NAME=hotspot.exe GENERATED=../generated # Allow the user to turn off precompiled headers from the command line. @@ -34,7 +33,7 @@ BUILD_PCH_FILE=_build_pch_file.obj !endif -default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA +default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA !include ../local.make !include compile.make @@ -49,8 +48,10 @@ # Force resources to be rebuilt every time $(Res_Files): FORCE -$(AOUT): $(Res_Files) $(Obj_Files) +vm.def: $(Obj_Files) sh $(WorkSpace)/make/windows/build_vm_def.sh + +$(AOUT): $(Res_Files) $(Obj_Files) vm.def $(LINK) @<< $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/generated.make --- a/make/windows/makefiles/generated.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/generated.make Thu Dec 16 12:56:51 2010 -0800 @@ -51,6 +51,7 @@ !if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered") +!include $(WorkSpace)/make/windows/makefiles/compile.make !include $(WorkSpace)/make/windows/makefiles/adlc.make !endif diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/launcher.make --- a/make/windows/makefiles/launcher.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/launcher.make Thu Dec 16 12:56:51 2010 -0800 @@ -22,7 +22,8 @@ # # -LAUNCHER_FLAGS=$(ARCHFLAG) \ + +LAUNCHER_FLAGS=$(CPP_FLAGS) $(ARCHFLAG) \ /D FULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \ /D JDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \ /D JDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \ @@ -32,9 +33,11 @@ /D _CRT_SECURE_NO_DEPRECATE \ /D LINK_INTO_LIBJVM \ /I $(WorkSpace)\src\os\windows\launcher \ - /I $(WorkSpace)\src\share\tools\launcher - -CPP_FLAGS=$(CPP_FLAGS) $(LAUNCHER_FLAGS) + /I $(WorkSpace)\src\share\tools\launcher \ + /I $(WorkSpace)\src\share\vm\prims \ + /I $(WorkSpace)\src\share\vm \ + /I $(WorkSpace)\src\cpu\$(Platform_arch)\vm \ + /I $(WorkSpace)\src\os\windows\vm LINK_FLAGS=/manifest $(HS_INTERNAL_NAME).lib kernel32.lib user32.lib /nologo /machine:$(MACHINE) /map /debug /subsystem:console @@ -46,22 +49,23 @@ LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB) !endif -LAUNCHERDIR = $(GAMMADIR)/src/os/windows/launcher -LAUNCHERDIR_SHARE = $(GAMMADIR)/src/share/tools/launcher +LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher +LAUNCHERDIR_SHARE = $(WorkSpace)/src/share/tools/launcher OUTDIR = launcher {$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj: - -mkdir $(OUTDIR) - $(CPP) $(CPP_FLAGS) /c /Fo$@ $< + -mkdir $(OUTDIR) 2>NUL >NUL + $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $< {$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj: - -mkdir $(OUTDIR) - $(CPP) $(CPP_FLAGS) /c /Fo$@ $< + -mkdir $(OUTDIR) 2>NUL >NUL + $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $< $(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h -$(LAUNCHER_NAME): $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj - $(LINK) $(LINK_FLAGS) /out:$@ $** +launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj + echo $(JAVA_HOME) > jdkpath.txt + $(LINK) $(LINK_FLAGS) /out:hotspot.exe $** diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/product.make --- a/make/windows/makefiles/product.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/product.make Thu Dec 16 12:56:51 2010 -0800 @@ -25,7 +25,6 @@ HS_INTERNAL_NAME=jvm HS_FNAME=$(HS_INTERNAL_NAME).dll AOUT=$(HS_FNAME) -LAUNCHER_NAME=hotspot.exe GENERATED=../generated # Allow the user to turn off precompiled headers from the command line. @@ -33,7 +32,7 @@ BUILD_PCH_FILE=_build_pch_file.obj !endif -default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA +default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA !include ../local.make !include compile.make @@ -59,8 +58,10 @@ $(LINK_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files) << !else -$(AOUT): $(Res_Files) $(Obj_Files) +vm.def: $(Obj_Files) sh $(WorkSpace)/make/windows/build_vm_def.sh + +$(AOUT): $(Res_Files) $(Obj_Files) vm.def $(LINK) @<< $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/projectcreator.make --- a/make/windows/makefiles/projectcreator.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/projectcreator.make Thu Dec 16 12:56:51 2010 -0800 @@ -84,11 +84,12 @@ -buildBase $(HOTSPOTBUILDSPACE)\%f\%b \ -startAt src \ -compiler $(VcVersion) \ - -projectFileName $(HOTSPOTBUILDSPACE)\$(ProjectFile) \ + -projectFileName $(HOTSPOTBUILDROOT)\$(ProjectFile) \ -jdkTargetRoot $(HOTSPOTJDKDIST) \ -define ALIGN_STACK_FRAMES \ -define VM_LITTLE_ENDIAN \ -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \ + -postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \ -ignoreFile jsig.c \ -ignoreFile jvmtiEnvRecommended.cpp \ -ignoreFile jvmtiEnvStub.cpp \ diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/rules.make --- a/make/windows/makefiles/rules.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/rules.make Thu Dec 16 12:56:51 2010 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2010, 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 @@ -48,7 +48,7 @@ JAVAC_FLAGS=-g -encoding ascii BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION) -ProjectFile=vm.vcproj +ProjectFile=jvm.vcproj !if "$(MSC_VER)" == "1200" @@ -63,6 +63,11 @@ VcVersion=VC9 +!elseif "$(MSC_VER)" == "1600" + +# for compatibility - we don't yet have a ProjectCreator for VC10 +VcVersion=VC9 + !else VcVersion=VC7 diff -r 36eef023306f -r 320ef6401fce make/windows/makefiles/vm.make --- a/make/windows/makefiles/vm.make Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/makefiles/vm.make Thu Dec 16 12:56:51 2010 -0800 @@ -71,22 +71,11 @@ CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\"" CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\"" -CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS" $(CPP_INCLUDE_DIRS) - -# Must specify this for sharedRuntimeTrig.cpp -CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN" +CPP_FLAGS=$(CPP_FLAGS) $(CPP_INCLUDE_DIRS) # Define that so jni.h is on correct side CPP_FLAGS=$(CPP_FLAGS) /D "_JNI_IMPLEMENTATION_" -# Used for platform dispatching -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_FAMILY_windows -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_$(Platform_arch) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_COMPILER_visCPP - !if "$(BUILDARCH)" == "ia64" STACK_SIZE="/STACK:1048576,262144" !else @@ -104,6 +93,8 @@ !endif !endif +# If you modify exports below please do the corresponding changes in +# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \ /export:JNI_GetDefaultJavaVMInitArgs \ /export:JNI_CreateJavaVM \ diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/common/Makefile --- a/make/windows/projectfiles/common/Makefile Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/common/Makefile Thu Dec 16 12:56:51 2010 -0800 @@ -22,7 +22,10 @@ # # -!include local.make +!ifdef LOCAL_MAKE +!include $(LOCAL_MAKE) +!endif + WorkSpace=$(HOTSPOTWORKSPACE) @@ -34,11 +37,18 @@ !else !ifdef JAVA_HOME BootStrapDir=$(JAVA_HOME) +!else +!ifdef HOTSPOTJDKDIST +BootStrapDir=$(HOTSPOTJDKDIST) +!endif !endif !endif !endif + + !include $(HOTSPOTWORKSPACE)/make/windows/makefiles/projectcreator.make +!include $(WorkSpace)/make/windows/makefiles/compile.make # Pick up rules for building JVMTI (JSR-163) JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles @@ -56,6 +66,9 @@ !include $(HOTSPOTWORKSPACE)/make/windows/makefiles/adlc.make !endif +HS_INTERNAL_NAME=jvm +!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/launcher.make + default:: $(AdditionalTargets) $(JvmtiGeneratedFiles) !include $(HOTSPOTWORKSPACE)/make/hotspot_version @@ -97,7 +110,7 @@ -define JRE_RELEASE_VERSION=\\\"$(JRE_RELEASE_VERSION)\\\" \ -define HOTSPOT_VM_DISTRO=\\\"$(HOTSPOT_VM_DISTRO)\\\" -$(HOTSPOTBUILDSPACE)/$(ProjectFile): local.make $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class +$(HOTSPOTBUILDROOT)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class @$(RUN_JAVA) -Djava.class.path=$(HOTSPOTBUILDSPACE)/classes ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions) clean: diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/compiler1/Makefile --- a/make/windows/projectfiles/compiler1/Makefile Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/compiler1/Makefile Thu Dec 16 12:56:51 2010 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2010, 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 @@ -22,7 +22,6 @@ # # -Variant=compiler1 -!include local.make +!include ../local.make !include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/compiler1/vm.def --- a/make/windows/projectfiles/compiler1/vm.def Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/compiler1/vm.def Thu Dec 16 12:56:51 2010 -0800 @@ -2,6 +2,6 @@ ; This .DEF file is a placeholder for one which is automatically ; generated during the build process. See ; make\windows\build_vm_def.sh and -; make\windows\makefiles\makedeps.make (esp. the "-prelink" +; make\windows\makefiles\projectcreator.make (esp. the "-prelink" ; options). ; diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/compiler2/Makefile --- a/make/windows/projectfiles/compiler2/Makefile Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/compiler2/Makefile Thu Dec 16 12:56:51 2010 -0800 @@ -22,8 +22,7 @@ # # -Variant=compiler2 -!include local.make +!include ../local.make AdlcOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\adfiles AdditionalTargets=$(AdlcOutDir)\ad_$(Platform_arch_model).cpp $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/compiler2/vm.def --- a/make/windows/projectfiles/compiler2/vm.def Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/compiler2/vm.def Thu Dec 16 12:56:51 2010 -0800 @@ -2,6 +2,6 @@ ; This .DEF file is a placeholder for one which is automatically ; generated during the build process. See ; make\windows\build_vm_def.sh and -; make\windows\makefiles\makedeps.make (esp. the "-prelink" +; make\windows\makefiles\projectcreator.make (esp. the "-prelink" ; options). ; diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/core/Makefile --- a/make/windows/projectfiles/core/Makefile Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/core/Makefile Thu Dec 16 12:56:51 2010 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2010, 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 @@ -22,7 +22,6 @@ # # -Variant=core -!include local.make +!include ../local.make !include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/core/vm.def --- a/make/windows/projectfiles/core/vm.def Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/core/vm.def Thu Dec 16 12:56:51 2010 -0800 @@ -2,6 +2,6 @@ ; This .DEF file is a placeholder for one which is automatically ; generated during the build process. See ; make\windows\build_vm_def.sh and -; make\windows\makefiles\makedeps.make (esp. the "-prelink" +; make\windows\makefiles\projectcreator.make (esp. the "-prelink" ; options). ; diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/kernel/Makefile --- a/make/windows/projectfiles/kernel/Makefile Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/kernel/Makefile Thu Dec 16 12:56:51 2010 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2010 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 @@ -22,7 +22,6 @@ # # -Variant=kernel -!include local.make +!include ../local.make !include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/kernel/vm.def --- a/make/windows/projectfiles/kernel/vm.def Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/kernel/vm.def Thu Dec 16 12:56:51 2010 -0800 @@ -2,6 +2,6 @@ ; This .DEF file is a placeholder for one which is automatically ; generated during the build process. See ; make\windows\build_vm_def.sh and -; make\windows\makefiles\makedeps.make (esp. the "-prelink" +; make\windows\makefiles\projectcreator.make (esp. the "-prelink" ; options). ; diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/tiered/Makefile --- a/make/windows/projectfiles/tiered/Makefile Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/tiered/Makefile Thu Dec 16 12:56:51 2010 -0800 @@ -22,8 +22,7 @@ # # -Variant=tiered -!include local.make +!include ../local.make AdlcOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\adfiles AdditionalTargets=$(AdlcOutDir)\ad_$(Platform_arch_model).cpp $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp diff -r 36eef023306f -r 320ef6401fce make/windows/projectfiles/tiered/vm.def --- a/make/windows/projectfiles/tiered/vm.def Thu Dec 16 09:14:34 2010 -0800 +++ b/make/windows/projectfiles/tiered/vm.def Thu Dec 16 12:56:51 2010 -0800 @@ -2,6 +2,6 @@ ; This .DEF file is a placeholder for one which is automatically ; generated during the build process. See ; make\windows\build_vm_def.sh and -; make\windows\makefiles\makedeps.make (esp. the "-prelink" +; make\windows\makefiles\projectcreator.make (esp. the "-prelink" ; options). ; diff -r 36eef023306f -r 320ef6401fce src/os/linux/vm/decoder_linux.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os/linux/vm/decoder_linux.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1997, 2010, 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 "prims/jvm.h" +#include "utilities/decoder.hpp" + +#include + +bool Decoder::demangle(const char* symbol, char *buf, int buflen) { + int status; + char* result; + size_t size = (size_t)buflen; + + // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small, + // __cxa_demangle will call system "realloc" for additional memory, which + // may use different malloc/realloc mechanism that allocates 'buf'. + if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) { + jio_snprintf(buf, buflen, "%s", result); + // call c library's free + ::free(result); + return true; + } + return false; +} diff -r 36eef023306f -r 320ef6401fce src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/os/linux/vm/os_linux.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -59,6 +59,7 @@ #include "services/attachListener.hpp" #include "services/runtimeService.hpp" #include "thread_linux.inline.hpp" +#include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" #include "utilities/growableArray.hpp" @@ -1688,14 +1689,23 @@ Dl_info dlinfo; if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { - if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); - if (offset) *offset = addr - (address)dlinfo.dli_saddr; + if (buf != NULL) { + if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { + jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); + } + } + if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; return true; - } else { - if (buf) buf[0] = '\0'; - if (offset) *offset = -1; - return false; + } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { + if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), + dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) { + return true; + } } + + if (buf != NULL) buf[0] = '\0'; + if (offset != NULL) *offset = -1; + return false; } struct _address_to_library_name { diff -r 36eef023306f -r 320ef6401fce src/os/posix/launcher/java_md.c --- a/src/os/posix/launcher/java_md.c Thu Dec 16 09:14:34 2010 -0800 +++ b/src/os/posix/launcher/java_md.c Thu Dec 16 12:56:51 2010 -0800 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -812,13 +813,10 @@ #ifdef GAMMA { - /* gamma launcher uses JAVA_HOME or ALT_JAVA_HOME environment variable to find JDK/JRE */ - char* java_home_var = getenv("ALT_JAVA_HOME"); + /* gamma launcher uses JAVA_HOME environment variable to find JDK/JRE */ + char* java_home_var = getenv("JAVA_HOME"); if (java_home_var == NULL) { - java_home_var = getenv("JAVA_HOME"); - } - if (java_home_var == NULL) { - printf("JAVA_HOME or ALT_JAVA_HOME must point to a valid JDK/JRE to run gamma\n"); + printf("JAVA_HOME must point to a valid JDK/JRE to run gamma\n"); return JNI_FALSE; } snprintf(buf, bufsize, "%s", java_home_var); @@ -1837,7 +1835,7 @@ if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) { void * tmp; pthread_join(tid, &tmp); - rslt = (int)tmp; + rslt = (int)(intptr_t)tmp; } else { /* * Continue execution in current thread if for some reason (e.g. out of @@ -1855,7 +1853,7 @@ if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) { void * tmp; thr_join(tid, NULL, &tmp); - rslt = (int)tmp; + rslt = (int)(intptr_t)tmp; } else { /* See above. Continue in current thread if thr_create() failed */ rslt = continuation(args); diff -r 36eef023306f -r 320ef6401fce src/os/posix/launcher/launcher.script --- a/src/os/posix/launcher/launcher.script Thu Dec 16 09:14:34 2010 -0800 +++ b/src/os/posix/launcher/launcher.script Thu Dec 16 12:56:51 2010 -0800 @@ -95,17 +95,21 @@ ;; esac +# Find out the absolute path to this script +MYDIR=$(cd $(dirname $SCRIPT) && pwd) + +JDK= if [ "${ALT_JAVA_HOME}" = "" ]; then - if [ "${JAVA_HOME}" = "" ]; then - echo "Neither ALT_JAVA_HOME nor JAVA_HOME is set. Aborting."; - exit 1; - else - JDK=${JAVA_HOME%%/jre}; - fi + source ${MYDIR}/jdkpath.sh else JDK=${ALT_JAVA_HOME%%/jre}; fi +if [ "${JDK}" = "" ]; then + echo Failed to find JDK. ALT_JAVA_HOME is not set or ./jdkpath.sh is empty or not found. + exit 1 +fi + # We will set the LD_LIBRARY_PATH as follows: # o $JVMPATH (directory portion only) # o $JRE/lib/$ARCH diff -r 36eef023306f -r 320ef6401fce src/os/solaris/vm/decoder_solaris.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os/solaris/vm/decoder_solaris.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1997, 2010, 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 "utilities/decoder.hpp" + +#include + +bool Decoder::demangle(const char* symbol, char *buf, int buflen) { + return !cplus_demangle(symbol, buf, (size_t)buflen); +} diff -r 36eef023306f -r 320ef6401fce src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/os/solaris/vm/os_solaris.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -57,6 +57,7 @@ #include "services/attachListener.hpp" #include "services/runtimeService.hpp" #include "thread_solaris.inline.hpp" +#include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" #include "utilities/growableArray.hpp" @@ -1969,27 +1970,42 @@ Sym * info; if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, RTLD_DL_SYMENT)) { - if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); - if (offset) *offset = addr - (address)dlinfo.dli_saddr; - - // check if the returned symbol really covers addr - return ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr); - } else { - if (buf) buf[0] = '\0'; - if (offset) *offset = -1; - return false; + if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { + if (buf != NULL) { + if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) + jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); + } + if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; + return true; + } } + if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { + if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), + dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) { + return true; + } + } + if (buf != NULL) buf[0] = '\0'; + if (offset != NULL) *offset = -1; + return false; } else { // no, only dladdr is available - if(dladdr((void *)addr, &dlinfo)) { - if (buf) jio_snprintf(buf, buflen, dlinfo.dli_sname); - if (offset) *offset = addr - (address)dlinfo.dli_saddr; + if (dladdr((void *)addr, &dlinfo)) { + if (buf != NULL) { + if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) + jio_snprintf(buf, buflen, dlinfo.dli_sname); + } + if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; + return true; + } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { + if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), + dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) { return true; - } else { - if (buf) buf[0] = '\0'; - if (offset) *offset = -1; - return false; + } } + if (buf != NULL) buf[0] = '\0'; + if (offset != NULL) *offset = -1; + return false; } } diff -r 36eef023306f -r 320ef6401fce src/os/windows/launcher/java_md.c --- a/src/os/windows/launcher/java_md.c Thu Dec 16 09:14:34 2010 -0800 +++ b/src/os/windows/launcher/java_md.c Thu Dec 16 12:56:51 2010 -0800 @@ -22,6 +22,7 @@ * */ +#include #include #include #include @@ -486,16 +487,62 @@ #else /* ifndef GAMMA */ - /* gamma launcher uses JAVA_HOME or ALT_JAVA_HOME environment variable to find JDK/JRE */ - char* java_home_var = getenv("ALT_JAVA_HOME"); - if (java_home_var == NULL) { - java_home_var = getenv("JAVA_HOME"); + char env[MAXPATHLEN + 1]; + + /* gamma launcher uses ALT_JAVA_HOME environment variable or jdkpath.txt file to find JDK/JRE */ + + if (getenv("ALT_JAVA_HOME") != NULL) { + snprintf(buf, bufsize, "%s", getenv("ALT_JAVA_HOME")); } - if (java_home_var == NULL) { - printf("JAVA_HOME or ALT_JAVA_HOME must point to a valid JDK/JRE to run gamma\n"); - return JNI_FALSE; + else { + char path[MAXPATHLEN + 1]; + char* p; + int len; + FILE* fp; + + // find the path to the currect executable + len = GetModuleFileName(NULL, path, MAXPATHLEN + 1); + if (len == 0 || len > MAXPATHLEN) { + printf("Could not get directory of current executable."); + return JNI_FALSE; + } + // remove last path component ("hotspot.exe") + p = strrchr(path, '\\'); + if (p == NULL) { + printf("Could not parse directory of current executable.\n"); + return JNI_FALSE; + } + *p = '\0'; + + // open jdkpath.txt and read JAVA_HOME from it + if (strlen(path) + strlen("\\jdkpath.txt") + 1 >= MAXPATHLEN) { + printf("Path too long: %s\n", path); + return JNI_FALSE; + } + strcat(path, "\\jdkpath.txt"); + fp = fopen(path, "r"); + if (fp == NULL) { + printf("Could not open file %s to get path to JDK.\n", path); + return JNI_FALSE; + } + + if (fgets(buf, bufsize, fp) == NULL) { + printf("Could not read from file %s to get path to JDK.\n", path); + fclose(fp); + return JNI_FALSE; + } + // trim the buffer + p = buf + strlen(buf) - 1; + while(isspace(*p)) { + *p = '\0'; + p--; + } + fclose(fp); } - snprintf(buf, bufsize, "%s", java_home_var); + + _snprintf(env, MAXPATHLEN, "JAVA_HOME=%s", buf); + _putenv(env); + return JNI_TRUE; #endif /* ifndef GAMMA */ } diff -r 36eef023306f -r 320ef6401fce src/os/windows/vm/decoder_windows.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os/windows/vm/decoder_windows.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "prims/jvm.h" +#include "utilities/decoder.hpp" + +HMODULE Decoder::_dbghelp_handle = NULL; +bool Decoder::_can_decode_in_vm = false; +pfn_SymGetSymFromAddr64 Decoder::_pfnSymGetSymFromAddr64 = NULL; +pfn_UndecorateSymbolName Decoder::_pfnUndecorateSymbolName = NULL; + +void Decoder::initialize() { + if (!_initialized) { + _initialized = true; + + HMODULE handle = ::LoadLibrary("dbghelp.dll"); + if (!handle) { + _decoder_status = helper_not_found; + return; + } + + _dbghelp_handle = handle; + + pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions"); + pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize"); + _pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64"); + _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName"); + + if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { + _pfnSymGetSymFromAddr64 = NULL; + _pfnUndecorateSymbolName = NULL; + ::FreeLibrary(handle); + _dbghelp_handle = NULL; + _decoder_status = helper_func_error; + return; + } + + _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); + if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) { + _pfnSymGetSymFromAddr64 = NULL; + _pfnUndecorateSymbolName = NULL; + ::FreeLibrary(handle); + _dbghelp_handle = NULL; + _decoder_status = helper_init_error; + return; + } + + // find out if jvm.dll contains private symbols, by decoding + // current function and comparing the result + address addr = (address)Decoder::initialize; + char buf[MAX_PATH]; + if (decode(addr, buf, sizeof(buf), NULL) == no_error) { + _can_decode_in_vm = !strcmp(buf, "Decoder::initialize"); + } + } +} + +void Decoder::uninitialize() { + assert(_initialized, "Decoder not yet initialized"); + _pfnSymGetSymFromAddr64 = NULL; + _pfnUndecorateSymbolName = NULL; + if (_dbghelp_handle != NULL) { + ::FreeLibrary(_dbghelp_handle); + } + _initialized = false; +} + +bool Decoder::can_decode_C_frame_in_vm() { + initialize(); + return _can_decode_in_vm; +} + + +Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) { + assert(_initialized, "Decoder not yet initialized"); + if (_pfnSymGetSymFromAddr64 != NULL) { + PIMAGEHLP_SYMBOL64 pSymbol; + char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)]; + pSymbol = (PIMAGEHLP_SYMBOL64)symbolInfo; + pSymbol->MaxNameLength = MAX_PATH; + pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + DWORD64 displacement; + if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) { + if (buf != NULL) { + if (!demangle(pSymbol->Name, buf, buflen)) { + jio_snprintf(buf, buflen, "%s", pSymbol->Name); + } + } + if (offset != NULL) *offset = (int)displacement; + return no_error; + } + } + return helper_not_found; +} + +bool Decoder::demangle(const char* symbol, char *buf, int buflen) { + assert(_initialized, "Decoder not yet initialized"); + return _pfnUndecorateSymbolName != NULL && + _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE); +} + diff -r 36eef023306f -r 320ef6401fce src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/os/windows/vm/os_windows.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -62,6 +62,7 @@ #include "services/attachListener.hpp" #include "services/runtimeService.hpp" #include "thread_windows.inline.hpp" +#include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" #include "utilities/growableArray.hpp" @@ -1365,12 +1366,11 @@ bool os::dll_address_to_function_name(address addr, char *buf, int buflen, int *offset) { - // Unimplemented on Windows - in order to use SymGetSymFromAddr(), - // we need to initialize imagehlp/dbghelp, then load symbol table - // for every module. That's too much work to do after a fatal error. - // For an example on how to implement this function, see 1.4.2. - if (offset) *offset = -1; - if (buf) buf[0] = '\0'; + if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) { + return true; + } + if (offset != NULL) *offset = -1; + if (buf != NULL) buf[0] = '\0'; return false; } @@ -1711,14 +1711,11 @@ buf[0] = '\0'; if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { // Support for the gamma launcher. Check for an - // ALT_JAVA_HOME or JAVA_HOME environment variable + // JAVA_HOME environment variable // and fix up the path so it looks like // libjvm.so is installed there (append a fake suffix // hotspot/libjvm.so). - char* java_home_var = ::getenv("ALT_JAVA_HOME"); - if (java_home_var == NULL) { - java_home_var = ::getenv("JAVA_HOME"); - } + char* java_home_var = ::getenv("JAVA_HOME"); if (java_home_var != NULL && java_home_var[0] != 0) { strncpy(buf, java_home_var, buflen); diff -r 36eef023306f -r 320ef6401fce src/share/tools/ProjectCreator/BuildConfig.java --- a/src/share/tools/ProjectCreator/BuildConfig.java Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/tools/ProjectCreator/BuildConfig.java Thu Dec 16 12:56:51 2010 -0800 @@ -22,8 +22,11 @@ * */ -import java.util.*; import java.io.File; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; class BuildConfig { Hashtable vars; @@ -57,7 +60,6 @@ // ones mentioned above were needed to expand format String buildBase = expandFormat(getFieldString(null, "BuildBase")); - String jdkDir = getFieldString(null, "JdkTargetRoot"); String sourceBase = getFieldString(null, "SourceBase"); String outDir = buildBase; @@ -65,7 +67,7 @@ put("OutputDir", outDir); put("SourceBase", sourceBase); put("BuildBase", buildBase); - put("OutputDll", jdkDir + Util.sep + outDll); + put("OutputDll", outDir + Util.sep + outDll); context = new String [] {flavourBuild, flavour, build, null}; } @@ -537,68 +539,75 @@ } } -class C1DebugConfig extends GenericDebugConfig { +abstract class GenericDebugNonKernelConfig extends GenericDebugConfig { + protected void init(Vector includes, Vector defines) { + super.init(includes, defines); + getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags")); + } +} + +class C1DebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getNoOptFlag(); } C1DebugConfig() { - initNames("compiler1", "debug", "fastdebug\\jre\\bin\\client\\jvm.dll"); + initNames("compiler1", "debug", "jvm.dll"); init(getIncludes(), getDefines()); } } -class C1FastDebugConfig extends GenericDebugConfig { +class C1FastDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getOptFlag(); } C1FastDebugConfig() { - initNames("compiler1", "fastdebug", "fastdebug\\jre\\bin\\client\\jvm.dll"); + initNames("compiler1", "fastdebug", "jvm.dll"); init(getIncludes(), getDefines()); } } -class C2DebugConfig extends GenericDebugConfig { +class C2DebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getNoOptFlag(); } C2DebugConfig() { - initNames("compiler2", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll"); + initNames("compiler2", "debug", "jvm.dll"); init(getIncludes(), getDefines()); } } -class C2FastDebugConfig extends GenericDebugConfig { +class C2FastDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getOptFlag(); } C2FastDebugConfig() { - initNames("compiler2", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll"); + initNames("compiler2", "fastdebug", "jvm.dll"); init(getIncludes(), getDefines()); } } -class TieredDebugConfig extends GenericDebugConfig { +class TieredDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getNoOptFlag(); } TieredDebugConfig() { - initNames("tiered", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll"); + initNames("tiered", "debug", "jvm.dll"); init(getIncludes(), getDefines()); } } -class TieredFastDebugConfig extends GenericDebugConfig { +class TieredFastDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getOptFlag(); } TieredFastDebugConfig() { - initNames("tiered", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll"); + initNames("tiered", "fastdebug", "jvm.dll"); init(getIncludes(), getDefines()); } } @@ -618,45 +627,45 @@ class C1ProductConfig extends ProductConfig { C1ProductConfig() { - initNames("compiler1", "product", "jre\\bin\\client\\jvm.dll"); + initNames("compiler1", "product", "jvm.dll"); init(getIncludes(), getDefines()); } } class C2ProductConfig extends ProductConfig { C2ProductConfig() { - initNames("compiler2", "product", "jre\\bin\\server\\jvm.dll"); + initNames("compiler2", "product", "jvm.dll"); init(getIncludes(), getDefines()); } } class TieredProductConfig extends ProductConfig { TieredProductConfig() { - initNames("tiered", "product", "jre\\bin\\server\\jvm.dll"); + initNames("tiered", "product", "jvm.dll"); init(getIncludes(), getDefines()); } } -class CoreDebugConfig extends GenericDebugConfig { +class CoreDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getNoOptFlag(); } CoreDebugConfig() { - initNames("core", "debug", "fastdebug\\jre\\bin\\core\\jvm.dll"); + initNames("core", "debug", "jvm.dll"); init(getIncludes(), getDefines()); } } -class CoreFastDebugConfig extends GenericDebugConfig { +class CoreFastDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getOptFlag(); } CoreFastDebugConfig() { - initNames("core", "fastdebug", "fastdebug\\jre\\bin\\core\\jvm.dll"); + initNames("core", "fastdebug", "jvm.dll"); init(getIncludes(), getDefines()); } } @@ -664,7 +673,7 @@ class CoreProductConfig extends ProductConfig { CoreProductConfig() { - initNames("core", "product", "jre\\bin\\core\\jvm.dll"); + initNames("core", "product", "jvm.dll"); init(getIncludes(), getDefines()); } } @@ -675,7 +684,7 @@ } KernelDebugConfig() { - initNames("kernel", "debug", "fastdebug\\jre\\bin\\kernel\\jvm.dll"); + initNames("kernel", "debug", "jvm.dll"); init(getIncludes(), getDefines()); } } @@ -687,7 +696,7 @@ } KernelFastDebugConfig() { - initNames("kernel", "fastdebug", "fastdebug\\jre\\bin\\kernel\\jvm.dll"); + initNames("kernel", "fastdebug", "jvm.dll"); init(getIncludes(), getDefines()); } } @@ -695,7 +704,7 @@ class KernelProductConfig extends ProductConfig { KernelProductConfig() { - initNames("kernel", "product", "jre\\bin\\kernel\\jvm.dll"); + initNames("kernel", "product", "jvm.dll"); init(getIncludes(), getDefines()); } } @@ -704,6 +713,7 @@ abstract Vector getBaseLinkerFlags(String outDir, String outDll); abstract Vector getDebugCompilerFlags(String opt); abstract Vector getDebugLinkerFlags(); + abstract void getAdditionalNonKernelLinkerFlags(Vector rv); abstract Vector getProductCompilerFlags(); abstract Vector getProductLinkerFlags(); abstract String getOptFlag(); @@ -713,4 +723,14 @@ void addAttr(Vector receiver, String attr, String value) { receiver.add(attr); receiver.add(value); } + void extAttr(Vector receiver, String attr, String value) { + int attr_pos=receiver.indexOf(attr) ; + if ( attr_pos == -1) { + // If attr IS NOT present in the Vector - add it + receiver.add(attr); receiver.add(value); + } else { + // If attr IS present in the Vector - append value to it + receiver.set(attr_pos+1,receiver.get(attr_pos+1)+value); + } + } } diff -r 36eef023306f -r 320ef6401fce src/share/tools/ProjectCreator/WinGammaPlatform.java --- a/src/share/tools/ProjectCreator/WinGammaPlatform.java Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java Thu Dec 16 12:56:51 2010 -0800 @@ -22,8 +22,15 @@ * */ -import java.io.*; -import java.util.*; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.TreeSet; +import java.util.Vector; abstract class HsArgHandler extends ArgHandler { static final int STRING = 1; @@ -345,11 +352,23 @@ new ArgsParser(args, new ArgRule[] { - new HsArgRule("-sourceBase", - "SourceBase", - " (Did you set the HotSpotWorkSpace environment variable?)", - HsArgHandler.STRING - ), + new ArgRule("-sourceBase", + new HsArgHandler() { + public void handle(ArgIterator it) { + String cfg = getCfg(it.get()); + if (nextNotKey(it)) { + String sb = (String) it.get(); + if (sb.endsWith(Util.sep)) { + sb = sb.substring(0, sb.length() - 1); + } + BuildConfig.putField(cfg, "SourceBase", sb); + it.next(); + } else { + empty("-sourceBase", null); + } + } + } + ), new HsArgRule("-buildBase", "BuildBase", @@ -512,7 +531,6 @@ new HsArgHandler() { public void handle(ArgIterator it) { if (nextNotKey(it)) { - String build = it.get(); if (nextNotKey(it)) { String description = it.get(); if (nextNotKey(it)) { @@ -528,7 +546,28 @@ empty(null, "** Error: wrong number of args to -prelink"); } } - ) + ), + + new ArgRule("-postbuild", + new HsArgHandler() { + public void handle(ArgIterator it) { + if (nextNotKey(it)) { + if (nextNotKey(it)) { + String description = it.get(); + if (nextNotKey(it)) { + String command = it.get(); + BuildConfig.putField(null, "PostbuildDescription", description); + BuildConfig.putField(null, "PostbuildCommand", command); + it.next(); + return; + } + } + } + + empty(null, "** Error: wrong number of args to -postbuild"); + } + } + ), }, new ArgHandler() { public void handle(ArgIterator it) { @@ -618,10 +657,6 @@ public int compareTo(Object o) { FileInfo oo = (FileInfo)o; - // Don't squelch identical short file names where the full - // paths are different - if (!attr.shortName.equals(oo.attr.shortName)) - return attr.shortName.compareTo(oo.attr.shortName); return full.compareTo(oo.full); } diff -r 36eef023306f -r 320ef6401fce src/share/tools/ProjectCreator/WinGammaPlatformVC6.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java Thu Dec 16 12:56:51 2010 -0800 @@ -260,6 +260,8 @@ return rv; } + void getAdditionalNonKernelLinkerFlags(Vector rv) {} + Vector getProductCompilerFlags() { Vector rv = new Vector(); diff -r 36eef023306f -r 320ef6401fce src/share/tools/ProjectCreator/WinGammaPlatformVC7.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Thu Dec 16 12:56:51 2010 -0800 @@ -22,8 +22,13 @@ * */ -import java.io.*; -import java.util.*; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.TreeSet; +import java.util.Vector; public class WinGammaPlatformVC7 extends WinGammaPlatform { @@ -104,7 +109,9 @@ boolean match(FileInfo fi) { - return fi.full.regionMatches(true, baseLen, dir, 0, dirLen); + int lastSlashIndex = fi.full.lastIndexOf('/'); + String fullDir = fi.full.substring(0, lastSlashIndex); + return fullDir.endsWith(dir); } } @@ -217,65 +224,41 @@ // - container filter just provides a container to group together real filters // - real filter can select elements from the set according to some rule, put it into XML // and remove from the list - Vector makeFilters(TreeSet files) { + Vector makeFilters(TreeSet files) { Vector rv = new Vector(); String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase")+"/src/"); - ContainerFilter rt = new ContainerFilter("Runtime"); - rt.add(new DirectoryFilter("share/vm/prims", sbase)); - rt.add(new DirectoryFilter("share/vm/runtime", sbase)); - rt.add(new DirectoryFilter("share/vm/oops", sbase)); - rv.add(rt); - - ContainerFilter gc = new ContainerFilter("GC"); - gc.add(new DirectoryFilter("share/vm/memory", sbase)); - gc.add(new DirectoryFilter("share/vm/gc_interface", sbase)); + String currentDir = ""; + DirectoryFilter container = null; + for(FileInfo fileInfo : files) { - ContainerFilter gc_impl = new ContainerFilter("Implementations"); - gc_impl.add(new DirectoryFilter("CMS", - "share/vm/gc_implementation/concurrentMarkSweep", - sbase)); - gc_impl.add(new DirectoryFilter("Parallel Scavenge", - "share/vm/gc_implementation/parallelScavenge", - sbase)); - gc_impl.add(new DirectoryFilter("Shared", - "share/vm/gc_implementation/shared", - sbase)); - // for all leftovers - gc_impl.add(new DirectoryFilter("Misc", - "share/vm/gc_implementation", - sbase)); - - gc.add(gc_impl); - rv.add(gc); + if (!fileInfo.full.startsWith(sbase)) { + continue; + } - rv.add(new DirectoryFilter("C1", "share/vm/c1", sbase)); - - rv.add(new DirectoryFilter("C2", "share/vm/opto", sbase)); - - ContainerFilter comp = new ContainerFilter("Compiler Common"); - comp.add(new DirectoryFilter("share/vm/asm", sbase)); - comp.add(new DirectoryFilter("share/vm/ci", sbase)); - comp.add(new DirectoryFilter("share/vm/code", sbase)); - comp.add(new DirectoryFilter("share/vm/compiler", sbase)); - rv.add(comp); + int lastSlash = fileInfo.full.lastIndexOf('/'); + String dir = fileInfo.full.substring(sbase.length(), lastSlash); + if(dir.equals("share/vm")) { + // skip files directly in share/vm - should only be precompiled.hpp which is handled below + continue; + } + if (!dir.equals(currentDir)) { + currentDir = dir; + if (container != null) { + rv.add(container); + } - rv.add(new DirectoryFilter("Interpreter", - "share/vm/interpreter", - sbase)); - - ContainerFilter misc = new ContainerFilter("Misc"); - misc.add(new DirectoryFilter("share/vm/libadt", sbase)); - misc.add(new DirectoryFilter("share/vm/services", sbase)); - misc.add(new DirectoryFilter("share/vm/utilities", sbase)); - misc.add(new DirectoryFilter("share/vm/classfile", sbase)); - rv.add(misc); - - rv.add(new DirectoryFilter("os_cpu", sbase)); - - rv.add(new DirectoryFilter("cpu", sbase)); - - rv.add(new DirectoryFilter("os", sbase)); + // remove "share/vm/" from names + String name = dir; + if (dir.startsWith("share/vm/")) { + name = dir.substring("share/vm/".length(), dir.length()); + } + container = new DirectoryFilter(name, dir, sbase); + } + } + if (container != null) { + rv.add(container); + } ContainerFilter generated = new ContainerFilter("Generated"); ContainerFilter c1Generated = new ContainerFilter("C1"); @@ -397,7 +380,6 @@ "Name", cfg, "ExcludedFromBuild", "TRUE" }); - tag("Tool", new String[] {"Name", "VCCLCompilerTool"}); endTag("FileConfiguration"); } @@ -441,7 +423,11 @@ tag("Tool", new String[] { - "Name", "VCPostBuildEventTool" + "Name", "VCPostBuildEventTool", + "Description", BuildConfig.getFieldString(null, "PostbuildDescription"), + //Caution: String.replace(String,String) is available from JDK5 onwards only + "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace + ("\t", " ")) } ); @@ -469,33 +455,6 @@ "Culture", "1033" } ); - tag("Tool", - new String[] { - "Name", "VCWebServiceProxyGeneratorTool" - } - ); - - tag ("Tool", - new String[] { - "Name", "VCXMLDataGeneratorTool" - } - ); - - tag("Tool", - new String[] { - "Name", "VCWebDeploymentTool" - } - ); - tag("Tool", - new String[] { - "Name", "VCManagedWrapperGeneratorTool" - } - ); - tag("Tool", - new String[] { - "Name", "VCAuxiliaryManagedWrapperGeneratorTool" - } - ); tag("Tool", new String[] { @@ -597,7 +556,7 @@ addAttr(rv, "PrecompiledHeaderFile", outDir+Util.sep+"vm.pch"); addAttr(rv, "AssemblerListingLocation", outDir); addAttr(rv, "ObjectFile", outDir+Util.sep); - addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"vm.pdb"); + addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb"); // Set /nologo optin addAttr(rv, "SuppressStartupBanner", "TRUE"); // Surpass the default /Tc or /Tp. 0 is compileAsDefault @@ -631,17 +590,22 @@ addAttr(rv, "AdditionalOptions", "/export:JNI_GetDefaultJavaVMInitArgs " + "/export:JNI_CreateJavaVM " + + "/export:JVM_FindClassFromBootLoader "+ "/export:JNI_GetCreatedJavaVMs "+ "/export:jio_snprintf /export:jio_printf "+ "/export:jio_fprintf /export:jio_vfprintf "+ - "/export:jio_vsnprintf "); + "/export:jio_vsnprintf "+ + "/export:JVM_GetVersionInfo "+ + "/export:JVM_GetThreadStateNames "+ + "/export:JVM_GetThreadStateValues "+ + "/export:JVM_InitAgentProperties "); addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib"); addAttr(rv, "OutputFile", outDll); // Set /INCREMENTAL option. 1 is linkIncrementalNo addAttr(rv, "LinkIncremental", "1"); addAttr(rv, "SuppressStartupBanner", "TRUE"); addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def"); - addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"vm.pdb"); + addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb"); // Set /SUBSYSTEM option. 2 is subSystemWindows addAttr(rv, "SubSystem", "2"); addAttr(rv, "BaseAddress", "0x8000000"); @@ -682,6 +646,11 @@ return rv; } + void getAdditionalNonKernelLinkerFlags(Vector rv) { + extAttr(rv, "AdditionalOptions", + "/export:AsyncGetCallTrace "); + } + void getProductCompilerFlags_common(Vector rv) { // Set /O2 option. 2 is optimizeMaxSpeed addAttr(rv, "Optimization", "2"); diff -r 36eef023306f -r 320ef6401fce src/share/tools/ProjectCreator/WinGammaPlatformVC8.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java Thu Dec 16 12:56:51 2010 -0800 @@ -22,7 +22,7 @@ * */ -import java.util.*; +import java.util.Vector; public class WinGammaPlatformVC8 extends WinGammaPlatformVC7 { @@ -41,6 +41,9 @@ // Set /EHsc- option. 0 is cppExceptionHandlingNo addAttr(rv, "ExceptionHandling", "0"); + // enable multi process builds + extAttr(rv, "AdditionalOptions", "/MP"); + return rv; } diff -r 36eef023306f -r 320ef6401fce src/share/tools/launcher/java.c --- a/src/share/tools/launcher/java.c Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/tools/launcher/java.c Thu Dec 16 12:56:51 2010 -0800 @@ -275,6 +275,8 @@ jvmpath, sizeof(jvmpath), original_argv); + printf("Using java runtime at: %s\n", jrepath); + ifn.CreateJavaVM = 0; ifn.GetDefaultJavaVMInitArgs = 0; diff -r 36eef023306f -r 320ef6401fce src/share/tools/launcher/jli_util.c --- a/src/share/tools/launcher/jli_util.c Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/tools/launcher/jli_util.c Thu Dec 16 12:56:51 2010 -0800 @@ -1,3 +1,4 @@ + /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -27,7 +28,7 @@ #include "jli_util.h" #ifdef GAMMA -#ifdef _WINDOWS +#ifdef TARGET_OS_FAMILY_windows #define strdup _strdup #endif #endif diff -r 36eef023306f -r 320ef6401fce src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/code/nmethod.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -619,8 +619,8 @@ OopMapSet* oop_maps ) : CodeBlob("native nmethod", code_buffer, sizeof(nmethod), nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps), - _compiled_synchronized_native_basic_lock_owner_sp_offset(basic_lock_owner_sp_offset), - _compiled_synchronized_native_basic_lock_sp_offset(basic_lock_sp_offset) + _native_receiver_sp_offset(basic_lock_owner_sp_offset), + _native_basic_lock_sp_offset(basic_lock_sp_offset) { { debug_only(No_Safepoint_Verifier nsv;) @@ -696,8 +696,8 @@ int frame_size) : CodeBlob("dtrace nmethod", code_buffer, sizeof(nmethod), nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, NULL), - _compiled_synchronized_native_basic_lock_owner_sp_offset(in_ByteSize(-1)), - _compiled_synchronized_native_basic_lock_sp_offset(in_ByteSize(-1)) + _native_receiver_sp_offset(in_ByteSize(-1)), + _native_basic_lock_sp_offset(in_ByteSize(-1)) { { debug_only(No_Safepoint_Verifier nsv;) @@ -790,8 +790,8 @@ ) : CodeBlob("nmethod", code_buffer, sizeof(nmethod), nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps), - _compiled_synchronized_native_basic_lock_owner_sp_offset(in_ByteSize(-1)), - _compiled_synchronized_native_basic_lock_sp_offset(in_ByteSize(-1)) + _native_receiver_sp_offset(in_ByteSize(-1)), + _native_basic_lock_sp_offset(in_ByteSize(-1)) { assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); { diff -r 36eef023306f -r 320ef6401fce src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/code/nmethod.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -210,7 +210,7 @@ ExceptionCache *_exception_cache; PcDescCache _pc_desc_cache; - // These are only used for compiled synchronized native methods to + // These are used for compiled synchronized native methods to // locate the owner and stack slot for the BasicLock so that we can // properly revoke the bias of the owner if necessary. They are // needed because there is no debug information for compiled native @@ -220,8 +220,10 @@ // sharing between platforms. Note that currently biased locking // will never cause Class instances to be biased but this code // handles the static synchronized case as well. - ByteSize _compiled_synchronized_native_basic_lock_owner_sp_offset; - ByteSize _compiled_synchronized_native_basic_lock_sp_offset; + // JVMTI's GetLocalInstance() also uses these offsets to find the receiver + // for non-static native wrapper frames. + ByteSize _native_receiver_sp_offset; + ByteSize _native_basic_lock_sp_offset; friend class nmethodLocker; @@ -676,11 +678,11 @@ bool is_patchable_at(address instr_address); // UseBiasedLocking support - ByteSize compiled_synchronized_native_basic_lock_owner_sp_offset() { - return _compiled_synchronized_native_basic_lock_owner_sp_offset; + ByteSize native_receiver_sp_offset() { + return _native_receiver_sp_offset; } - ByteSize compiled_synchronized_native_basic_lock_sp_offset() { - return _compiled_synchronized_native_basic_lock_sp_offset; + ByteSize native_basic_lock_sp_offset() { + return _native_basic_lock_sp_offset; } // support for code generation diff -r 36eef023306f -r 320ef6401fce src/share/vm/oops/instanceRefKlass.cpp --- a/src/share/vm/oops/instanceRefKlass.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/oops/instanceRefKlass.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -457,6 +457,12 @@ } } +bool instanceRefKlass::owns_pending_list_lock(JavaThread* thread) { + if (java_lang_ref_Reference::pending_list_lock() == NULL) return false; + Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock()); + return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock); +} + void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) { // we may enter this with pending exception set PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument diff -r 36eef023306f -r 320ef6401fce src/share/vm/oops/instanceRefKlass.hpp --- a/src/share/vm/oops/instanceRefKlass.hpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/oops/instanceRefKlass.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -89,6 +89,7 @@ static void release_and_notify_pending_list_lock(BasicLock *pending_list_basic_lock); static void acquire_pending_list_lock(BasicLock *pending_list_basic_lock); + static bool owns_pending_list_lock(JavaThread* thread); // Update non-static oop maps so 'referent', 'nextPending' and // 'discovered' will look like non-oops diff -r 36eef023306f -r 320ef6401fce src/share/vm/oops/klassVtable.cpp --- a/src/share/vm/oops/klassVtable.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/oops/klassVtable.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -518,18 +518,21 @@ bool klassVtable::is_miranda(methodOop m, objArrayOop class_methods, klassOop super) { symbolOop name = m->name(); symbolOop signature = m->signature(); + if (instanceKlass::find_method(class_methods, name, signature) == NULL) { - // did not find it in the method table of the current class + // did not find it in the method table of the current class if (super == NULL) { // super doesn't exist return true; - } else { - if (instanceKlass::cast(super)->lookup_method(name, signature) == NULL) { - // super class hierarchy does not implement it - return true; - } + } + + methodOop mo = instanceKlass::cast(super)->lookup_method(name, signature); + if (mo == NULL || mo->access_flags().is_private() ) { + // super class hierarchy does not implement it or protection is different + return true; } } + return false; } diff -r 36eef023306f -r 320ef6401fce src/share/vm/oops/methodOop.cpp --- a/src/share/vm/oops/methodOop.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/oops/methodOop.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -309,6 +309,12 @@ // Build a methodDataOop object to hold information about this method // collected in the interpreter. void methodOopDesc::build_interpreter_method_data(methodHandle method, TRAPS) { + // Do not profile method if current thread holds the pending list lock, + // which avoids deadlock for acquiring the MethodData_lock. + if (instanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) { + return; + } + // Grab a lock here to prevent multiple // methodDataOops from being created. MutexLocker ml(MethodData_lock, THREAD); diff -r 36eef023306f -r 320ef6401fce src/share/vm/prims/jvmti.xml --- a/src/share/vm/prims/jvmti.xml Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/prims/jvmti.xml Thu Dec 16 12:56:51 2010 -0800 @@ -5649,6 +5649,45 @@ + + Get Local Instance + + This function can be used to retrieve the value of the local object + variable at slot 0 (the "this" object) from non-static + frames. This function can retrieve the "this" object from + native method frames, whereas GetLocalObject() would + return JVMTI_ERROR_OPAQUE_FRAME in those cases. + + new + + + + + + + + The thread of the frame containing the variable's value. + + + + + + The depth of the frame containing the variable's value. + + + + + + On return, points to the variable's value. + + + + + + If the specified frame is a static method frame. + + + Get Local Variable - Int diff -r 36eef023306f -r 320ef6401fce src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/prims/jvmtiEnv.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -1796,6 +1796,29 @@ } } /* end GetLocalObject */ +// Threads_lock NOT held, java_thread not protected by lock +// java_thread - pre-checked +// java_thread - unchecked +// depth - pre-checked as non-negative +// value - pre-checked for NULL +jvmtiError +JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value){ + JavaThread* current_thread = JavaThread::current(); + // rm object is created to clean up the javaVFrame created in + // doit_prologue(), but after doit() is finished with it. + ResourceMark rm(current_thread); + + VM_GetReceiver op(java_thread, current_thread, depth); + VMThread::execute(&op); + jvmtiError err = op.result(); + if (err != JVMTI_ERROR_NONE) { + return err; + } else { + *value = op.value().l; + return JVMTI_ERROR_NONE; + } +} /* end GetLocalInstance */ + // Threads_lock NOT held, java_thread not protected by lock // java_thread - pre-checked diff -r 36eef023306f -r 320ef6401fce src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/prims/jvmtiImpl.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -586,7 +586,6 @@ { } - vframe *VM_GetOrSetLocal::get_vframe() { if (!_thread->has_last_Java_frame()) { return NULL; @@ -609,7 +608,7 @@ } javaVFrame *jvf = (javaVFrame*)vf; - if (!vf->is_java_frame() || jvf->method()->is_native()) { + if (!vf->is_java_frame()) { _result = JVMTI_ERROR_OPAQUE_FRAME; return NULL; } @@ -740,6 +739,15 @@ _jvf = get_java_vframe(); NULL_CHECK(_jvf, false); + if (_jvf->method()->is_native()) { + if (getting_receiver() && !_jvf->method()->is_static()) { + return true; + } else { + _result = JVMTI_ERROR_OPAQUE_FRAME; + return false; + } + } + if (!check_slot_type(_jvf)) { return false; } @@ -781,40 +789,46 @@ HandleMark hm; switch (_type) { - case T_INT: locals->set_int_at (_index, _value.i); break; - case T_LONG: locals->set_long_at (_index, _value.j); break; - case T_FLOAT: locals->set_float_at (_index, _value.f); break; - case T_DOUBLE: locals->set_double_at(_index, _value.d); break; - case T_OBJECT: { - Handle ob_h(JNIHandles::resolve_external_guard(_value.l)); - locals->set_obj_at (_index, ob_h); - break; - } - default: ShouldNotReachHere(); + case T_INT: locals->set_int_at (_index, _value.i); break; + case T_LONG: locals->set_long_at (_index, _value.j); break; + case T_FLOAT: locals->set_float_at (_index, _value.f); break; + case T_DOUBLE: locals->set_double_at(_index, _value.d); break; + case T_OBJECT: { + Handle ob_h(JNIHandles::resolve_external_guard(_value.l)); + locals->set_obj_at (_index, ob_h); + break; + } + default: ShouldNotReachHere(); } _jvf->set_locals(locals); } else { - StackValueCollection *locals = _jvf->locals(); + if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) { + assert(getting_receiver(), "Can only get here when getting receiver"); + oop receiver = _jvf->fr().get_native_receiver(); + _value.l = JNIHandles::make_local(_calling_thread, receiver); + } else { + StackValueCollection *locals = _jvf->locals(); - if (locals->at(_index)->type() == T_CONFLICT) { - memset(&_value, 0, sizeof(_value)); - _value.l = NULL; - return; - } + if (locals->at(_index)->type() == T_CONFLICT) { + memset(&_value, 0, sizeof(_value)); + _value.l = NULL; + return; + } - switch (_type) { - case T_INT: _value.i = locals->int_at (_index); break; - case T_LONG: _value.j = locals->long_at (_index); break; - case T_FLOAT: _value.f = locals->float_at (_index); break; - case T_DOUBLE: _value.d = locals->double_at(_index); break; - case T_OBJECT: { - // Wrap the oop to be returned in a local JNI handle since - // oops_do() no longer applies after doit() is finished. - oop obj = locals->obj_at(_index)(); - _value.l = JNIHandles::make_local(_calling_thread, obj); - break; - } - default: ShouldNotReachHere(); + switch (_type) { + case T_INT: _value.i = locals->int_at (_index); break; + case T_LONG: _value.j = locals->long_at (_index); break; + case T_FLOAT: _value.f = locals->float_at (_index); break; + case T_DOUBLE: _value.d = locals->double_at(_index); break; + case T_OBJECT: { + // Wrap the oop to be returned in a local JNI handle since + // oops_do() no longer applies after doit() is finished. + oop obj = locals->obj_at(_index)(); + _value.l = JNIHandles::make_local(_calling_thread, obj); + break; + } + default: ShouldNotReachHere(); + } } } } @@ -825,6 +839,10 @@ } +VM_GetReceiver::VM_GetReceiver( + JavaThread* thread, JavaThread* caller_thread, jint depth) + : VM_GetOrSetLocal(thread, caller_thread, depth, 0) {} + ///////////////////////////////////////////////////////////////////////////////////////// // diff -r 36eef023306f -r 320ef6401fce src/share/vm/prims/jvmtiImpl.hpp --- a/src/share/vm/prims/jvmtiImpl.hpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/prims/jvmtiImpl.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -355,7 +355,7 @@ // to the thread simultaneously. // class VM_GetOrSetLocal : public VM_Operation { -private: + protected: JavaThread* _thread; JavaThread* _calling_thread; jint _depth; @@ -365,6 +365,10 @@ javaVFrame* _jvf; bool _set; + // It is possible to get the receiver out of a non-static native wrapper + // frame. Use VM_GetReceiver to do this. + virtual bool getting_receiver() const { return false; } + jvmtiError _result; vframe* get_vframe(); @@ -395,6 +399,15 @@ static bool is_assignable(const char* ty_sign, Klass* klass, Thread* thread); }; +class VM_GetReceiver : public VM_GetOrSetLocal { + protected: + virtual bool getting_receiver() const { return true; } + + public: + VM_GetReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth); + const char* name() const { return "get receiver"; } +}; + /////////////////////////////////////////////////////////////// // diff -r 36eef023306f -r 320ef6401fce src/share/vm/runtime/frame.cpp --- a/src/share/vm/runtime/frame.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/runtime/frame.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -41,6 +41,8 @@ #include "runtime/signature.hpp" #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" +#include "utilities/decoder.hpp" + #ifdef TARGET_ARCH_x86 # include "nativeInst_x86.hpp" #endif @@ -652,7 +654,7 @@ // names if pc is within jvm.dll or libjvm.so, because JVM only has // JVM_xxxx and a few other symbols in the dynamic symbol table. Do this // only for native libraries. - if (!in_vm) { + if (!in_vm || Decoder::can_decode_C_frame_in_vm()) { found = os::dll_address_to_function_name(pc, buf, buflen, &offset); if (found) { @@ -1071,28 +1073,20 @@ } } -BasicLock* frame::compiled_synchronized_native_monitor(nmethod* nm) { - if (nm == NULL) { - assert(_cb != NULL && _cb->is_nmethod() && - nm->method()->is_native() && - nm->method()->is_synchronized(), - "should not call this otherwise"); - nm = (nmethod*) _cb; - } - int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_sp_offset()); +BasicLock* frame::get_native_monitor() { + nmethod* nm = (nmethod*)_cb; + assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(), + "Should not call this unless it's a native nmethod"); + int byte_offset = in_bytes(nm->native_basic_lock_sp_offset()); assert(byte_offset >= 0, "should not see invalid offset"); return (BasicLock*) &sp()[byte_offset / wordSize]; } -oop frame::compiled_synchronized_native_monitor_owner(nmethod* nm) { - if (nm == NULL) { - assert(_cb != NULL && _cb->is_nmethod() && - nm->method()->is_native() && - nm->method()->is_synchronized(), - "should not call this otherwise"); - nm = (nmethod*) _cb; - } - int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_owner_sp_offset()); +oop frame::get_native_receiver() { + nmethod* nm = (nmethod*)_cb; + assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(), + "Should not call this unless it's a native nmethod"); + int byte_offset = in_bytes(nm->native_receiver_sp_offset()); assert(byte_offset >= 0, "should not see invalid offset"); oop owner = ((oop*) sp())[byte_offset / wordSize]; assert( Universe::heap()->is_in(owner), "bad receiver" ); diff -r 36eef023306f -r 320ef6401fce src/share/vm/runtime/frame.hpp --- a/src/share/vm/runtime/frame.hpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/runtime/frame.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -254,10 +254,10 @@ // Return the monitor owner and BasicLock for compiled synchronized // native methods so that biased locking can revoke the receiver's - // bias if necessary. Takes optional nmethod for this frame as - // argument to avoid performing repeated lookups in code cache. - BasicLock* compiled_synchronized_native_monitor (nmethod* nm = NULL); - oop compiled_synchronized_native_monitor_owner(nmethod* nm = NULL); + // bias if necessary. This is also used by JVMTI's GetLocalInstance method + // (via VM_GetReceiver) to retrieve the receiver from a native wrapper frame. + BasicLock* get_native_monitor(); + oop get_native_receiver(); // Find receiver for an invoke when arguments are just pushed on stack (i.e., callee stack-frame is // not setup) diff -r 36eef023306f -r 320ef6401fce src/share/vm/runtime/vframe_hp.cpp --- a/src/share/vm/runtime/vframe_hp.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/runtime/vframe_hp.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -207,8 +207,8 @@ GrowableArray *monitors = new GrowableArray(1); // Casting away const frame& fr = (frame&) _fr; - MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm), - fr.compiled_synchronized_native_monitor(nm), false, false); + MonitorInfo* info = new MonitorInfo( + fr.get_native_receiver(), fr.get_native_monitor(), false, false); monitors->push(info); return monitors; } diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/decoder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/decoder.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "prims/jvm.h" +#include "utilities/decoder.hpp" + +Decoder::decoder_status Decoder::_decoder_status = Decoder::no_error; +bool Decoder::_initialized = false; + +#ifndef _WINDOWS + +// Implementation of common functionalities among Solaris and Linux +#include "utilities/elfFile.hpp" + +ElfFile* Decoder::_opened_elf_files = NULL; + +bool Decoder::can_decode_C_frame_in_vm() { + return true; +} + +void Decoder::initialize() { + _initialized = true; +} + +void Decoder::uninitialize() { + if (_opened_elf_files != NULL) { + delete _opened_elf_files; + _opened_elf_files = NULL; + } + _initialized = false; +} + +Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) { + if (_decoder_status != no_error) { + return _decoder_status; + } + + ElfFile* file = get_elf_file(filepath); + if (_decoder_status != no_error) { + return _decoder_status; + } + + const char* symbol = file->decode(addr, offset); + if (file->get_status() == out_of_memory) { + _decoder_status = out_of_memory; + return _decoder_status; + } else if (symbol != NULL) { + if (!demangle(symbol, buf, buflen)) { + jio_snprintf(buf, buflen, "%s", symbol); + } + return no_error; + } else { + return symbol_not_found; + } +} + +ElfFile* Decoder::get_elf_file(const char* filepath) { + if (_decoder_status != no_error) { + return NULL; + } + ElfFile* file = _opened_elf_files; + while (file != NULL) { + if (file->same_elf_file(filepath)) { + return file; + } + file = file->m_next; + } + + file = new ElfFile(filepath); + if (file == NULL) { + _decoder_status = out_of_memory; + } + if (_opened_elf_files != NULL) { + file->m_next = _opened_elf_files; + } + + _opened_elf_files = file; + return file; +} + +#endif + diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/decoder.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/decoder.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1997, 2010, 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 __DECODER_HPP +#define __DECODER_HPP + +#include "memory/allocation.hpp" + +#ifdef _WINDOWS +#include +#include + +// functions needed for decoding symbols +typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD); +typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL); +typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64); +typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD); + +#else + +class ElfFile; + +#endif // _WINDOWS + + +class Decoder: public StackObj { + + public: + // status code for decoding native C frame + enum decoder_status { + no_error, // successfully decoded frames + out_of_memory, // out of memory + file_invalid, // invalid elf file + file_not_found, // could not found symbol file (on windows), such as jvm.pdb or jvm.map + helper_not_found, // could not load dbghelp.dll (Windows only) + helper_func_error, // decoding functions not found (Windows only) + helper_init_error, // SymInitialize failed (Windows only) + symbol_not_found // could not find the symbol + }; + + public: + Decoder() { initialize(); }; + ~Decoder() { uninitialize(); }; + + static bool can_decode_C_frame_in_vm(); + + static void initialize(); + static void uninitialize(); + +#ifdef _WINDOWS + static decoder_status decode(address addr, char *buf, int buflen, int *offset); +#else + static decoder_status decode(address addr, const char* filepath, char *buf, int buflen, int *offset); +#endif + + static bool demangle(const char* symbol, char *buf, int buflen); + + static decoder_status get_status() { return _decoder_status; }; + +#ifndef _WINDOWS + private: + static ElfFile* get_elf_file(const char* filepath); +#endif // _WINDOWS + + + private: + static decoder_status _decoder_status; + static bool _initialized; + +#ifdef _WINDOWS + static HMODULE _dbghelp_handle; + static bool _can_decode_in_vm; + static pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64; + static pfn_UndecorateSymbolName _pfnUndecorateSymbolName; +#else + static ElfFile* _opened_elf_files; +#endif // _WINDOWS +}; + +#endif // __DECODER_HPP diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/elfFile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/elfFile.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#ifndef _WINDOWS + +#include +#include +#include + +#include "memory/allocation.inline.hpp" +#include "utilities/decoder.hpp" +#include "utilities/elfFile.hpp" +#include "utilities/elfStringTable.hpp" +#include "utilities/elfSymbolTable.hpp" + + +ElfFile::ElfFile(const char* filepath) { + assert(filepath, "null file path"); + memset(&m_elfHdr, 0, sizeof(m_elfHdr)); + m_string_tables = NULL; + m_symbol_tables = NULL; + m_next = NULL; + m_status = Decoder::no_error; + + int len = strlen(filepath) + 1; + m_filepath = NEW_C_HEAP_ARRAY(char, len); + if (m_filepath != NULL) { + strcpy((char*)m_filepath, filepath); + m_file = fopen(filepath, "r"); + if (m_file != NULL) { + load_tables(); + } else { + m_status = Decoder::file_not_found; + } + } else { + m_status = Decoder::out_of_memory; + } +} + +ElfFile::~ElfFile() { + if (m_string_tables != NULL) { + delete m_string_tables; + } + + if (m_symbol_tables != NULL) { + delete m_symbol_tables; + } + + if (m_file != NULL) { + fclose(m_file); + } + + if (m_filepath != NULL) { + FREE_C_HEAP_ARRAY(char, m_filepath); + } + + if (m_next != NULL) { + delete m_next; + } +}; + + +//Check elf header to ensure the file is valid. +bool ElfFile::is_elf_file(Elf_Ehdr& hdr) { + return (ELFMAG0 == hdr.e_ident[EI_MAG0] && + ELFMAG1 == hdr.e_ident[EI_MAG1] && + ELFMAG2 == hdr.e_ident[EI_MAG2] && + ELFMAG3 == hdr.e_ident[EI_MAG3] && + ELFCLASSNONE != hdr.e_ident[EI_CLASS] && + ELFDATANONE != hdr.e_ident[EI_DATA]); +} + +bool ElfFile::load_tables() { + assert(m_file, "file not open"); + assert(m_status == Decoder::no_error, "already in error"); + + // read elf file header + if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) { + m_status = Decoder::file_invalid; + return false; + } + + if (!is_elf_file(m_elfHdr)) { + m_status = Decoder::file_invalid; + return false; + } + + // walk elf file's section headers, and load string tables + Elf_Shdr shdr; + if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) { + if (m_status != Decoder::no_error) return false; + + for (int index = 0; index < m_elfHdr.e_shnum; index ++) { + if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { + m_status = Decoder::file_invalid; + return false; + } + // string table + if (shdr.sh_type == SHT_STRTAB) { + ElfStringTable* table = new ElfStringTable(m_file, shdr, index); + if (table == NULL) { + m_status = Decoder::out_of_memory; + return false; + } + add_string_table(table); + } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { + ElfSymbolTable* table = new ElfSymbolTable(m_file, shdr); + if (table == NULL) { + m_status = Decoder::out_of_memory; + return false; + } + add_symbol_table(table); + } + } + } + return true; +} + +const char* ElfFile::decode(address addr, int* offset) { + // something already went wrong, just give up + if (m_status != Decoder::no_error) { + return NULL; + } + + ElfSymbolTable* symbol_table = m_symbol_tables; + int string_table_index; + int pos_in_string_table; + int off = INT_MAX; + bool found_symbol = false; + while (symbol_table != NULL) { + if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) { + found_symbol = true; + } + symbol_table = symbol_table->m_next; + } + if (!found_symbol) return NULL; + + ElfStringTable* string_table = get_string_table(string_table_index); + if (string_table == NULL) { + m_status = Decoder::file_invalid; + return NULL; + } + if (offset) *offset = off; + return string_table->string_at(pos_in_string_table); +} + + +void ElfFile::add_symbol_table(ElfSymbolTable* table) { + if (m_symbol_tables == NULL) { + m_symbol_tables = table; + } else { + table->m_next = m_symbol_tables; + m_symbol_tables = table; + } +} + +void ElfFile::add_string_table(ElfStringTable* table) { + if (m_string_tables == NULL) { + m_string_tables = table; + } else { + table->m_next = m_string_tables; + m_string_tables = table; + } +} + +ElfStringTable* ElfFile::get_string_table(int index) { + ElfStringTable* p = m_string_tables; + while (p != NULL) { + if (p->index() == index) return p; + p = p->m_next; + } + return NULL; +} + +#endif // _WINDOWS diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/elfFile.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/elfFile.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1997, 2010, 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 __ELF_FILE_HPP +#define __ELF_FILE_HPP + +#ifndef _WINDOWS + +#include +#include + +#ifdef _LP64 + +typedef Elf64_Half Elf_Half; +typedef Elf64_Word Elf_Word; +typedef Elf64_Off Elf_Off; +typedef Elf64_Addr Elf_Addr; + +typedef Elf64_Ehdr Elf_Ehdr; +typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Sym Elf_Sym; + +#define ELF_ST_TYPE ELF64_ST_TYPE + +#else + +typedef Elf32_Half Elf_Half; +typedef Elf32_Word Elf_Word; +typedef Elf32_Off Elf_Off; +typedef Elf32_Addr Elf_Addr; + + +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Sym Elf_Sym; + +#define ELF_ST_TYPE ELF32_ST_TYPE +#endif + +#include "globalDefinitions.hpp" +#include "memory/allocation.hpp" +#include "utilities/decoder.hpp" + + +class ElfStringTable; +class ElfSymbolTable; + + +// On Solaris/Linux platforms, libjvm.so does contain all private symbols. +// ElfFile is basically an elf file parser, which can lookup the symbol +// that is the nearest to the given address. +// Beware, this code is called from vm error reporting code, when vm is already +// in "error" state, so there are scenarios, lookup will fail. We want this +// part of code to be very defensive, and bait out if anything went wrong. + +class ElfFile: public CHeapObj { + friend class Decoder; + public: + ElfFile(const char* filepath); + ~ElfFile(); + + const char* decode(address addr, int* offset); + const char* filepath() { + return m_filepath; + } + + bool same_elf_file(const char* filepath) { + assert(filepath, "null file path"); + assert(m_filepath, "already out of memory"); + return (m_filepath && !strcmp(filepath, m_filepath)); + } + + Decoder::decoder_status get_status() { + return m_status; + } + + private: + // sanity check, if the file is a real elf file + bool is_elf_file(Elf_Ehdr&); + + // load string tables from the elf file + bool load_tables(); + + // string tables are stored in a linked list + void add_string_table(ElfStringTable* table); + + // symbol tables are stored in a linked list + void add_symbol_table(ElfSymbolTable* table); + + // return a string table at specified section index + ElfStringTable* get_string_table(int index); + + // look up an address and return the nearest symbol + const char* look_up(Elf_Shdr shdr, address addr, int* offset); + + protected: + ElfFile* m_next; + + private: + // file + const char* m_filepath; + FILE* m_file; + + // Elf header + Elf_Ehdr m_elfHdr; + + // symbol tables + ElfSymbolTable* m_symbol_tables; + + // string tables + ElfStringTable* m_string_tables; + + Decoder::decoder_status m_status; +}; + +#endif // _WINDOWS + +#endif // __ELF_FILE_HPP + diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/elfStringTable.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/elfStringTable.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#ifndef _WINDOWS + +#include "memory/allocation.inline.hpp" +#include "utilities/elfStringTable.hpp" + +// We will try to load whole string table into memory if we can. +// Otherwise, fallback to more expensive file operation. +ElfStringTable::ElfStringTable(FILE* file, Elf_Shdr shdr, int index) { + assert(file, "null file handle"); + m_table = NULL; + m_index = index; + m_next = NULL; + m_file = file; + m_status = Decoder::no_error; + + // try to load the string table + long cur_offset = ftell(file); + m_table = (char*)NEW_C_HEAP_ARRAY(char, shdr.sh_size); + if (m_table != NULL) { + // if there is an error, mark the error + if (fseek(file, shdr.sh_offset, SEEK_SET) || + fread((void*)m_table, shdr.sh_size, 1, file) != 1 || + fseek(file, cur_offset, SEEK_SET)) { + m_status = Decoder::file_invalid; + FREE_C_HEAP_ARRAY(char, m_table); + m_table = NULL; + } + } else { + memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr)); + } +} + +ElfStringTable::~ElfStringTable() { + if (m_table != NULL) { + FREE_C_HEAP_ARRAY(char, m_table); + } + + if (m_next != NULL) { + delete m_next; + } +} + +const char* ElfStringTable::string_at(int pos) { + if (m_status != Decoder::no_error) { + return NULL; + } + if (m_table != NULL) { + return (const char*)(m_table + pos); + } else { + long cur_pos = ftell(m_file); + if (cur_pos == -1 || + fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) || + fread(m_symbol, 1, MAX_SYMBOL_LEN, m_file) <= 0 || + fseek(m_file, cur_pos, SEEK_SET)) { + m_status = Decoder::file_invalid; + return NULL; + } + return (const char*)m_symbol; + } +} + +#endif // _WINDOWS + diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/elfStringTable.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/elfStringTable.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1997, 2010, 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 __ELF_STRING_TABLE_HPP +#define __ELF_STRING_TABLE_HPP + +#ifndef _WINDOWS + +#include "memory/allocation.hpp" +#include "utilities/decoder.hpp" +#include "utilities/elfFile.hpp" + + +// The string table represents a string table section in an elf file. +// Whenever there is enough memory, it will load whole string table as +// one blob. Otherwise, it will load string from file when requested. + +#define MAX_SYMBOL_LEN 256 + +class ElfStringTable: CHeapObj { + friend class ElfFile; + public: + ElfStringTable(FILE* file, Elf_Shdr shdr, int index); + ~ElfStringTable(); + + // section index + int index() { return m_index; }; + + // get string at specified offset + const char* string_at(int offset); + + // get status code + Decoder::decoder_status get_status() { return m_status; }; + + protected: + ElfStringTable* m_next; + + // section index + int m_index; + + // holds complete string table if can + // allocate enough memory + const char* m_table; + + // file contains string table + FILE* m_file; + + // section header + Elf_Shdr m_shdr; + + // buffer for reading individual string + char m_symbol[MAX_SYMBOL_LEN]; + + // error code + Decoder::decoder_status m_status; +}; + +#endif // _WINDOWS + +#endif // __ELF_STRING_TABLE_HPP + diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/elfSymbolTable.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/elfSymbolTable.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#ifndef _WINDOWS + +#include "memory/allocation.inline.hpp" +#include "utilities/elfSymbolTable.hpp" + +ElfSymbolTable::ElfSymbolTable(FILE* file, Elf_Shdr shdr) { + assert(file, "null file handle"); + m_symbols = NULL; + m_next = NULL; + m_file = file; + m_status = Decoder::no_error; + + // try to load the string table + long cur_offset = ftell(file); + if (cur_offset != -1) { + m_symbols = (Elf_Sym*)NEW_C_HEAP_ARRAY(char, shdr.sh_size); + if (m_symbols) { + if (fseek(file, shdr.sh_offset, SEEK_SET) || + fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 || + fseek(file, cur_offset, SEEK_SET)) { + m_status = Decoder::file_invalid; + FREE_C_HEAP_ARRAY(char, m_symbols); + m_symbols = NULL; + } + } + if (m_status == Decoder::no_error) { + memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr)); + } + } else { + m_status = Decoder::file_invalid; + } +} + +ElfSymbolTable::~ElfSymbolTable() { + if (m_symbols != NULL) { + FREE_C_HEAP_ARRAY(char, m_symbols); + } + + if (m_next != NULL) { + delete m_next; + } +} + +Decoder::decoder_status ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) { + assert(stringtableIndex, "null string table index pointer"); + assert(posIndex, "null string table offset pointer"); + assert(offset, "null offset pointer"); + + if (m_status != Decoder::no_error) { + return m_status; + } + + address pc = 0; + size_t sym_size = sizeof(Elf_Sym); + assert((m_shdr.sh_size % sym_size) == 0, "check size"); + int count = m_shdr.sh_size / sym_size; + if (m_symbols != NULL) { + for (int index = 0; index < count; index ++) { + if (STT_FUNC == ELF_ST_TYPE(m_symbols[index].st_info)) { + address sym_addr = (address)m_symbols[index].st_value; + if (sym_addr < addr && (addr - sym_addr) < *offset) { + pc = (address)m_symbols[index].st_value; + *offset = (int)(addr - pc); + *posIndex = m_symbols[index].st_name; + *stringtableIndex = m_shdr.sh_link; + } + } + } + } else { + long cur_pos; + if ((cur_pos = ftell(m_file)) == -1 || + fseek(m_file, m_shdr.sh_offset, SEEK_SET)) { + m_status = Decoder::file_invalid; + return m_status; + } + + Elf_Sym sym; + for (int index = 0; index < count; index ++) { + if (fread(&sym, sym_size, 1, m_file) == 1) { + if (STT_FUNC == ELF_ST_TYPE(sym.st_info)) { + address sym_addr = (address)sym.st_value; + if (sym_addr < addr && (addr - sym_addr) < *offset) { + pc = (address)sym.st_value; + *offset = (int)(addr - pc); + *posIndex = sym.st_name; + *stringtableIndex = m_shdr.sh_link; + } + } + } else { + m_status = Decoder::file_invalid; + return m_status; + } + } + fseek(m_file, cur_pos, SEEK_SET); + } + return m_status; +} + +#endif // _WINDOWS diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/elfSymbolTable.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/elfSymbolTable.hpp Thu Dec 16 12:56:51 2010 -0800 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1997, 2010, 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 __ELF_SYMBOL_TABLE_HPP +#define __ELF_SYMBOL_TABLE_HPP + +#ifndef _WINDOWS + + +#include "memory/allocation.hpp" +#include "utilities/decoder.hpp" +#include "utilities/elfFile.hpp" + +/* + * symbol table object represents a symbol section in an elf file. + * Whenever possible, it will load all symbols from the corresponding section + * of the elf file into memory. Otherwise, it will walk the section in file + * to look up the symbol that nearest the given address. + */ +class ElfSymbolTable: public CHeapObj { + friend class ElfFile; + public: + ElfSymbolTable(FILE* file, Elf_Shdr shdr); + ~ElfSymbolTable(); + + // search the symbol that is nearest to the specified address. + Decoder::decoder_status lookup(address addr, int* stringtableIndex, int* posIndex, int* offset); + + Decoder::decoder_status get_status() { return m_status; }; + + protected: + ElfSymbolTable* m_next; + + // holds a complete symbol table section if + // can allocate enough memory + Elf_Sym* m_symbols; + + // file contains string table + FILE* m_file; + + // section header + Elf_Shdr m_shdr; + + Decoder::decoder_status m_status; +}; + +#endif // _WINDOWS + +#endif // __ELF_SYMBOL_TABLE_HPP + + + diff -r 36eef023306f -r 320ef6401fce src/share/vm/utilities/vmError.cpp --- a/src/share/vm/utilities/vmError.cpp Thu Dec 16 09:14:34 2010 -0800 +++ b/src/share/vm/utilities/vmError.cpp Thu Dec 16 12:56:51 2010 -0800 @@ -33,6 +33,7 @@ #include "runtime/vmThread.hpp" #include "runtime/vm_operations.hpp" #include "utilities/debug.hpp" +#include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" #include "utilities/top.hpp" #include "utilities/vmError.hpp" @@ -516,8 +517,10 @@ if (fr.pc()) { st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); + // initialize decoder to decode C frames + Decoder decoder; + int count = 0; - while (count++ < StackPrintLimit) { fr.print_on_error(st, buf, sizeof(buf)); st->cr();