--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Mar 27 14:35:44 2009 -0400
@@ -347,6 +347,7 @@
for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
((Observer) iter.next()).update(null, null);
}
+
}
/** This is used by the debugging system */
--- a/hotspot/make/windows/build_vm_def.sh Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/make/windows/build_vm_def.sh Fri Mar 27 14:35:44 2009 -0400
@@ -52,6 +52,19 @@
RM="$MKS_HOME/rm.exe"
DUMPBIN="link.exe /dump"
+# When called from IDE the first param should contain the link version, otherwise may be nill
+if [ "x$1" != "x" ]; then
+LINK_VER="$1"
+fi
+
+if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" ]; then
$DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$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
+$DUMPBIN /OUT:vm3.def /symbols *.obj
+"$CAT" vm3.def | "$GREP" "??_7.*@@6B@" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def
+"$RM" -f vm3.def
+fi
+
"$CAT" vm1.def vm2.def > vm.def
"$RM" -f vm1.def vm2.def
--- a/hotspot/make/windows/create.bat Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/make/windows/create.bat Fri Mar 27 14:35:44 2009 -0400
@@ -72,12 +72,20 @@
for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i
echo **************************************************************
+set ProjectFile=vm.vcproj
if "%MSC_VER%" == "1200" (
set ProjectFile=vm.dsp
echo Will generate VC6 project {unsupported}
) else (
-set ProjectFile=vm.vcproj
-echo Will generate VC7 project
+if "%MSC_VER%" == "1400" (
+echo Will generate VC8 {Visual Studio 2005}
+) else (
+if "%MSC_VER%" == "1500" (
+echo Will generate VC9 {Visual Studio 2008}
+) else (
+echo Will generate VC7 project {Visual Studio 2003 .NET}
+)
+)
)
echo %ProjectFile%
echo **************************************************************
--- a/hotspot/make/windows/makefiles/adlc.make Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/make/windows/makefiles/adlc.make Fri Mar 27 14:35:44 2009 -0400
@@ -46,6 +46,7 @@
ADLCFLAGS=-q -T -U_LP64
!endif
+CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
CPP_INCLUDE_DIRS=\
/I "..\generated" \
--- a/hotspot/make/windows/makefiles/compile.make Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/make/windows/makefiles/compile.make Fri Mar 27 14:35:44 2009 -0400
@@ -170,8 +170,6 @@
# Manifest Tool - used in VS2005 and later to adjust manifests stored
# as resources inside build artifacts.
MT=mt.exe
-# VS2005 and later restricts the use of certain libc functions without this
-CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
!endif
!if "$(COMPILER_NAME)" == "VS2008"
@@ -183,8 +181,6 @@
# Manifest Tool - used in VS2005 and later to adjust manifests stored
# as resources inside build artifacts.
MT=mt.exe
-# VS2005 and later restricts the use of certain libc functions without this
-CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
!endif
# Compile for space above time.
--- a/hotspot/make/windows/makefiles/makedeps.make Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/make/windows/makefiles/makedeps.make Fri Mar 27 14:35:44 2009 -0400
@@ -48,6 +48,8 @@
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatform.java \
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC6.java \
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC7.java \
+ $(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC8.java \
+ $(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC9.java \
$(WorkSpace)\src\share\tools\MakeDeps\Util.java \
$(WorkSpace)\src\share\tools\MakeDeps\BuildConfig.java \
$(WorkSpace)\src\share\tools\MakeDeps\ArgsParser.java
@@ -121,7 +123,7 @@
-additionalFile includeDB_gc_shared \
-additionalFile includeDB_gc_serial \
-additionalGeneratedFile $(HOTSPOTBUILDSPACE)\%f\%b vm.def \
- -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh" \
+ -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
$(MakeDepsIncludesPRIVATE)
# Add in build-specific options
--- a/hotspot/make/windows/makefiles/rules.make Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/make/windows/makefiles/rules.make Fri Mar 27 14:35:44 2009 -0400
@@ -42,10 +42,23 @@
BOOT_JAVA_HOME=
!endif
+ProjectFile=vm.vcproj
+
!if "$(MSC_VER)" == "1200"
+
VcVersion=VC6
ProjectFile=vm.dsp
+
+!elseif "$(MSC_VER)" == "1400"
+
+VcVersion=VC8
+
+!elseif "$(MSC_VER)" == "1500"
+
+VcVersion=VC9
+
!else
+
VcVersion=VC7
-ProjectFile=vm.vcproj
+
!endif
--- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -2269,15 +2269,16 @@
// All it does is to check if there are enough free pages
// left at the time of mmap(). This could be a potential
// problem.
-bool os::commit_memory(char* addr, size_t size) {
- uintptr_t res = (uintptr_t) ::mmap(addr, size,
- PROT_READ|PROT_WRITE|PROT_EXEC,
+bool os::commit_memory(char* addr, size_t size, bool exec) {
+ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+ uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
return res != (uintptr_t) MAP_FAILED;
}
-bool os::commit_memory(char* addr, size_t size, size_t alignment_hint) {
- return commit_memory(addr, size);
+bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+ bool exec) {
+ return commit_memory(addr, size, exec);
}
void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
@@ -2417,8 +2418,7 @@
unsigned long* os::Linux::_numa_all_nodes;
bool os::uncommit_memory(char* addr, size_t size) {
- return ::mmap(addr, size,
- PROT_READ|PROT_WRITE|PROT_EXEC,
+ return ::mmap(addr, size, PROT_NONE,
MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0)
!= MAP_FAILED;
}
@@ -2441,7 +2441,9 @@
flags |= MAP_FIXED;
}
- addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE|PROT_EXEC,
+ // Map uncommitted pages PROT_READ and PROT_WRITE, change access
+ // to PROT_EXEC if executable when we commit the page.
+ addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE,
flags, -1, 0);
if (addr != MAP_FAILED) {
@@ -2582,7 +2584,9 @@
#define SHM_HUGETLB 04000
#endif
-char* os::reserve_memory_special(size_t bytes, char* req_addr) {
+char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
+ // "exec" is passed in but not used. Creating the shared image for
+ // the code cache doesn't have an SHM_X executable permission to check.
assert(UseLargePages, "only for large pages");
key_t key = IPC_PRIVATE;
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -2623,15 +2623,16 @@
return page_size;
}
-bool os::commit_memory(char* addr, size_t bytes) {
+bool os::commit_memory(char* addr, size_t bytes, bool exec) {
+ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
size_t size = bytes;
return
- NULL != Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED,
- PROT_READ | PROT_WRITE | PROT_EXEC);
-}
-
-bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint) {
- if (commit_memory(addr, bytes)) {
+ NULL != Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
+}
+
+bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint,
+ bool exec) {
+ if (commit_memory(addr, bytes, exec)) {
if (UseMPSS && alignment_hint > (size_t)vm_page_size()) {
// If the large page size has been set and the VM
// is using large pages, use the large page size
@@ -3220,7 +3221,9 @@
return true;
}
-char* os::reserve_memory_special(size_t bytes, char* addr) {
+char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
+ // "exec" is passed in but not used. Creating the shared image for
+ // the code cache doesn't have an SHM_X executable permission to check.
assert(UseLargePages && UseISM, "only for ISM large pages");
size_t size = bytes;
--- a/hotspot/src/os/windows/vm/os_windows.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -2189,7 +2189,8 @@
if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {
addr = (address)((uintptr_t)addr &
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
- os::commit_memory( (char *)addr, thread->stack_base() - addr );
+ os::commit_memory((char *)addr, thread->stack_base() - addr,
+ false );
return EXCEPTION_CONTINUE_EXECUTION;
}
else
@@ -2565,8 +2566,7 @@
assert((size_t)addr % os::vm_allocation_granularity() == 0,
"reserve alignment");
assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
- char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE,
- PAGE_EXECUTE_READWRITE);
+ char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
assert(res == NULL || addr == NULL || addr == res,
"Unexpected address from reserve.");
return res;
@@ -2595,7 +2595,7 @@
return true;
}
-char* os::reserve_memory_special(size_t bytes, char* addr) {
+char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
if (UseLargePagesIndividualAllocation) {
if (TracePageSizes && Verbose) {
@@ -2618,7 +2618,7 @@
p_buf = (char *) VirtualAlloc(addr,
size_of_reserve, // size of Reserve
MEM_RESERVE,
- PAGE_EXECUTE_READWRITE);
+ PAGE_READWRITE);
// If reservation failed, return NULL
if (p_buf == NULL) return NULL;
@@ -2659,7 +2659,13 @@
p_new = (char *) VirtualAlloc(next_alloc_addr,
bytes_to_rq,
MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES,
- PAGE_EXECUTE_READWRITE);
+ PAGE_READWRITE);
+ if (p_new != NULL && exec) {
+ DWORD oldprot;
+ // Windows doc says to use VirtualProtect to get execute permissions
+ VirtualProtect(next_alloc_addr, bytes_to_rq,
+ PAGE_EXECUTE_READWRITE, &oldprot);
+ }
}
if (p_new == NULL) {
@@ -2688,10 +2694,12 @@
} else {
// normal policy just allocate it all at once
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
- char * res = (char *)VirtualAlloc(NULL,
- bytes,
- flag,
- PAGE_EXECUTE_READWRITE);
+ char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_READWRITE);
+ if (res != NULL && exec) {
+ DWORD oldprot;
+ // Windows doc says to use VirtualProtect to get execute permissions
+ VirtualProtect(res, bytes, PAGE_EXECUTE_READWRITE, &oldprot);
+ }
return res;
}
}
@@ -2703,7 +2711,7 @@
void os::print_statistics() {
}
-bool os::commit_memory(char* addr, size_t bytes) {
+bool os::commit_memory(char* addr, size_t bytes, bool exec) {
if (bytes == 0) {
// Don't bother the OS with noops.
return true;
@@ -2712,11 +2720,19 @@
assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");
// Don't attempt to print anything if the OS call fails. We're
// probably low on resources, so the print itself may cause crashes.
- return VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE) != NULL;
+ bool result = VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) != 0;
+ if (result != NULL && exec) {
+ DWORD oldprot;
+ // Windows doc says to use VirtualProtect to get execute permissions
+ return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot) != 0;
+ } else {
+ return result;
+ }
}
-bool os::commit_memory(char* addr, size_t size, size_t alignment_hint) {
- return commit_memory(addr, size);
+bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+ bool exec) {
+ return commit_memory(addr, size, exec);
}
bool os::uncommit_memory(char* addr, size_t bytes) {
@@ -2750,7 +2766,7 @@
// Strange enough, but on Win32 one can change protection only for committed
// memory, not a big deal anyway, as bytes less or equal than 64K
- if (!is_committed && !commit_memory(addr, bytes)) {
+ if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) {
fatal("cannot commit protection page");
}
// One cannot use os::guard_memory() here, as on Win32 guard page
@@ -3248,10 +3264,10 @@
#endif
if (!UseMembar) {
- address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE);
guarantee( mem_serialize_page != NULL, "Reserve Failed for memory serialize page");
- return_page = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+ return_page = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_READWRITE);
guarantee( return_page != NULL, "Commit Failed for memory serialize page");
os::set_memory_serialize_page( mem_serialize_page );
--- a/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java Fri Mar 27 14:35:44 2009 -0400
@@ -27,6 +27,8 @@
public class WinGammaPlatformVC7 extends WinGammaPlatform {
+ String projectVersion() {return "7.10";};
+
public void writeProjectFile(String projectFileName, String projectName,
Vector allConfigs) throws IOException {
System.out.println();
@@ -40,7 +42,7 @@
"VisualStudioProject",
new String[] {
"ProjectType", "Visual C++",
- "Version", "7.10",
+ "Version", projectVersion(),
"Name", projectName,
"ProjectGUID", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}",
"SccProjectName", "",
@@ -417,7 +419,9 @@
new String[] {
"Name", "VCPreLinkEventTool",
"Description", BuildConfig.getFieldString(null, "PrelinkDescription"),
- "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace('\t', '\n'))
+ //Caution: String.replace(String,String) is available from JDK5 onwards only
+ "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace
+ ("\t", "
"))
}
);
@@ -542,25 +546,41 @@
}
class CompilerInterfaceVC7 extends CompilerInterface {
- Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
- Vector rv = new Vector();
+ void getBaseCompilerFlags_common(Vector defines, Vector includes, String outDir,Vector rv) {
// advanced M$ IDE (2003) can only recognize name if it's first or
// second attribute in the tag - go guess
addAttr(rv, "Name", "VCCLCompilerTool");
addAttr(rv, "AdditionalIncludeDirectories", Util.join(",", includes));
- addAttr(rv, "PreprocessorDefinitions", Util.join(";", defines).replace("\"","""));
- addAttr(rv, "UsePrecompiledHeader", "3");
- addAttr(rv, "PrecompiledHeaderThrough", "incls"+Util.sep+"_precompiled.incl");
+ addAttr(rv, "PreprocessorDefinitions",
+ Util.join(";", defines).replace("\"","""));
+ addAttr(rv, "PrecompiledHeaderThrough",
+ "incls"+Util.sep+"_precompiled.incl");
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");
+ // Set /nologo optin
addAttr(rv, "SuppressStartupBanner", "TRUE");
+ // Surpass the default /Tc or /Tp. 0 is compileAsDefault
addAttr(rv, "CompileAs", "0");
+ // Set /W3 option. 3 is warningLevel_3
addAttr(rv, "WarningLevel", "3");
+ // Set /WX option,
addAttr(rv, "WarnAsError", "TRUE");
+ // Set /GS option
addAttr(rv, "BufferSecurityCheck", "FALSE");
+ // Set /Zi option. 3 is debugEnabled
+ addAttr(rv, "DebugInformationFormat", "3");
+ }
+ Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
+ Vector rv = new Vector();
+
+ getBaseCompilerFlags_common(defines,includes, outDir, rv);
+ // Set /Yu option. 3 is pchUseUsingSpecific
+ // Note: Starting VC8 pchUseUsingSpecific is 2 !!!
+ addAttr(rv, "UsePrecompiledHeader", "3");
+ // Set /EHsc- option
addAttr(rv, "ExceptionHandling", "FALSE");
return rv;
@@ -579,27 +599,39 @@
"/export:jio_vsnprintf ");
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");
+ // Set /SUBSYSTEM option. 2 is subSystemWindows
addAttr(rv, "SubSystem", "2");
addAttr(rv, "BaseAddress", "0x8000000");
addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
+ // Set /MACHINE option. 1 is machineX86
addAttr(rv, "TargetMachine", "1");
return rv;
}
+ void getDebugCompilerFlags_common(String opt,Vector rv) {
+
+ // Set /On option
+ addAttr(rv, "Optimization", opt);
+ // Set /FR option. 1 is brAllInfo
+ addAttr(rv, "BrowseInformation", "1");
+ addAttr(rv, "BrowseInformationFile", "$(IntDir)" + Util.sep);
+ // Set /MD option. 2 is rtMultiThreadedDLL
+ addAttr(rv, "RuntimeLibrary", "2");
+ // Set /Oy- option
+ addAttr(rv, "OmitFramePointers", "FALSE");
+
+ }
+
Vector getDebugCompilerFlags(String opt) {
Vector rv = new Vector();
- addAttr(rv, "Optimization", opt);
- addAttr(rv, "OptimizeForProcessor", "1");
- addAttr(rv, "DebugInformationFormat", "3");
- addAttr(rv, "RuntimeLibrary", "2");
- addAttr(rv, "BrowseInformation", "1");
- addAttr(rv, "BrowseInformationFile", "$(IntDir)" + Util.sep);
+ getDebugCompilerFlags_common(opt,rv);
return rv;
}
@@ -607,18 +639,29 @@
Vector getDebugLinkerFlags() {
Vector rv = new Vector();
- addAttr(rv, "GenerateDebugInformation", "TRUE");
+ addAttr(rv, "GenerateDebugInformation", "TRUE"); // == /DEBUG option
return rv;
}
+ void getProductCompilerFlags_common(Vector rv) {
+ // Set /O2 option. 2 is optimizeMaxSpeed
+ addAttr(rv, "Optimization", "2");
+ // Set /Oy- option
+ addAttr(rv, "OmitFramePointers", "FALSE");
+ }
+
Vector getProductCompilerFlags() {
Vector rv = new Vector();
- addAttr(rv, "Optimization", "2");
+ getProductCompilerFlags_common(rv);
+ // Set /Ob option. 1 is expandOnlyInline
addAttr(rv, "InlineFunctionExpansion", "1");
+ // Set /GF option.
addAttr(rv, "StringPooling", "TRUE");
+ // Set /MD option. 2 is rtMultiThreadedDLL
addAttr(rv, "RuntimeLibrary", "2");
+ // Set /Gy option
addAttr(rv, "EnableFunctionLevelLinking", "TRUE");
return rv;
@@ -627,7 +670,9 @@
Vector getProductLinkerFlags() {
Vector rv = new Vector();
+ // Set /OPT:REF option. 2 is optReferences
addAttr(rv, "OptimizeReferences", "2");
+ // Set /OPT:optFolding option. 2 is optFolding
addAttr(rv, "EnableCOMDATFolding", "2");
return rv;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC8.java Fri Mar 27 14:35:44 2009 -0400
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class WinGammaPlatformVC8 extends WinGammaPlatformVC7 {
+
+ String projectVersion() {return "8.00";};
+
+}
+
+class CompilerInterfaceVC8 extends CompilerInterfaceVC7 {
+
+ Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
+ Vector rv = new Vector();
+
+ getBaseCompilerFlags_common(defines,includes, outDir, rv);
+ // Set /Yu option. 2 is pchUseUsingSpecific
+ addAttr(rv, "UsePrecompiledHeader", "2");
+ // Set /EHsc- option. 0 is cppExceptionHandlingNo
+ addAttr(rv, "ExceptionHandling", "0");
+
+ return rv;
+ }
+
+
+ Vector getDebugCompilerFlags(String opt) {
+ Vector rv = new Vector();
+
+ getDebugCompilerFlags_common(opt,rv);
+
+ return rv;
+ }
+
+ Vector getProductCompilerFlags() {
+ Vector rv = new Vector();
+
+ getProductCompilerFlags_common(rv);
+
+ return rv;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC9.java Fri Mar 27 14:35:44 2009 -0400
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class WinGammaPlatformVC9 extends WinGammaPlatformVC8 {
+
+ String projectVersion() {return "9.00";};
+
+}
+
+class CompilerInterfaceVC9 extends CompilerInterfaceVC8 {
+}
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -2747,9 +2747,10 @@
super_klass(),
methods(),
access_flags,
- class_loader(),
- class_name(),
- local_interfaces());
+ class_loader,
+ class_name,
+ local_interfaces(),
+ CHECK_(nullHandle));
// Size of Java itable (in words)
itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces);
@@ -3229,7 +3230,7 @@
// print out the superclass.
const char * from = Klass::cast(this_klass())->external_name();
if (this_klass->java_super() != NULL) {
- tty->print("RESOLVE %s %s\n", from, instanceKlass::cast(this_klass->java_super())->external_name());
+ tty->print("RESOLVE %s %s (super)\n", from, instanceKlass::cast(this_klass->java_super())->external_name());
}
// print out each of the interface classes referred to by this class.
objArrayHandle local_interfaces(THREAD, this_klass->local_interfaces());
@@ -3239,7 +3240,7 @@
klassOop k = klassOop(local_interfaces->obj_at(i));
instanceKlass* to_class = instanceKlass::cast(k);
const char * to = to_class->external_name();
- tty->print("RESOLVE %s %s\n", from, to);
+ tty->print("RESOLVE %s %s (interface)\n", from, to);
}
}
}
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Mar 27 14:35:44 2009 -0400
@@ -378,7 +378,7 @@
template(unknown_class_name, "<Unknown>") \
\
/* used to identify class loaders handling parallel class loading */ \
- template(parallelCapable_name, "parallelLockMap;") \
+ template(parallelCapable_name, "parallelLockMap") \
\
/* JVM monitoring and management support */ \
template(java_lang_StackTraceElement_array, "[Ljava/lang/StackTraceElement;") \
--- a/hotspot/src/share/vm/interpreter/invocationCounter.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/interpreter/invocationCounter.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -47,6 +47,8 @@
// executed many more times before re-entering the VM.
int old_count = count();
int new_count = MIN2(old_count, (int) (CompileThreshold / 2));
+ // prevent from going to zero, to distinguish from never-executed methods
+ if (new_count == 0) new_count = 1;
if (old_count != new_count) set(state(), new_count);
}
--- a/hotspot/src/share/vm/memory/heap.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/memory/heap.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -112,7 +112,7 @@
const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 :
MAX2(page_size, granularity);
- ReservedSpace rs(r_size, rs_align, rs_align > 0);
+ ReservedCodeSpace rs(r_size, rs_align, rs_align > 0);
os::trace_page_sizes("code heap", committed_size, reserved_size, page_size,
rs.base(), rs.size());
if (!_memory.initialize(rs, c_size)) {
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -1859,6 +1859,25 @@
}
}
+// Returns true iff super_method can be overridden by a method in targetclassname
+// See JSL 3rd edition 8.4.6.1
+// Assumes name-signature match
+// "this" is instanceKlass of super_method which must exist
+// note that the instanceKlass of the method in the targetclassname has not always been created yet
+bool instanceKlass::is_override(methodHandle super_method, Handle targetclassloader, symbolHandle targetclassname, TRAPS) {
+ // Private methods can not be overridden
+ if (super_method->is_private()) {
+ return false;
+ }
+ // If super method is accessible, then override
+ if ((super_method->is_protected()) ||
+ (super_method->is_public())) {
+ return true;
+ }
+ // Package-private methods are not inherited outside of package
+ assert(super_method->is_package_private(), "must be package private");
+ return(is_same_class_package(targetclassloader(), targetclassname()));
+}
jint instanceKlass::compute_modifier_flags(TRAPS) const {
klassOop k = as_klassOop();
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Mar 27 14:35:44 2009 -0400
@@ -303,6 +303,9 @@
inner_class_next_offset = 4
};
+ // method override check
+ bool is_override(methodHandle super_method, Handle targetclassloader, symbolHandle targetclassname, TRAPS);
+
// package
bool is_same_class_package(klassOop class2);
bool is_same_class_package(oop classloader2, symbolOop classname2);
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -45,9 +45,10 @@
klassOop super,
objArrayOop methods,
AccessFlags class_flags,
- oop classloader,
- symbolOop classname,
- objArrayOop local_interfaces
+ Handle classloader,
+ symbolHandle classname,
+ objArrayOop local_interfaces,
+ TRAPS
) {
No_Safepoint_Verifier nsv;
@@ -64,9 +65,9 @@
int len = methods->length();
for (int i = 0; i < len; i++) {
assert(methods->obj_at(i)->is_method(), "must be a methodOop");
- methodOop m = methodOop(methods->obj_at(i));
+ methodHandle mh(THREAD, methodOop(methods->obj_at(i)));
- if (needs_new_vtable_entry(m, super, classloader, classname, class_flags)) {
+ if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) {
vtable_length += vtableEntry::size(); // we need a new entry
}
}
@@ -117,6 +118,7 @@
superVtable->copy_vtable_to(table());
#ifndef PRODUCT
if (PrintVtables && Verbose) {
+ ResourceMark rm;
tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length);
}
#endif
@@ -159,13 +161,13 @@
int len = methods()->length();
int initialized = super_vtable_len;
- // update_super_vtable can stop for gc - ensure using handles
+ // update_inherited_vtable can stop for gc - ensure using handles
for (int i = 0; i < len; i++) {
HandleMark hm(THREAD);
assert(methods()->obj_at(i)->is_method(), "must be a methodOop");
methodHandle mh(THREAD, (methodOop)methods()->obj_at(i));
- bool needs_new_entry = update_super_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK);
+ bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK);
if (needs_new_entry) {
put_method_at(mh(), initialized);
@@ -177,7 +179,7 @@
// add miranda methods; it will also update the value of initialized
fill_in_mirandas(initialized);
- // In class hierachieswhere the accesibility is not increasing (i.e., going from private ->
+ // In class hierarchies where the accessibility is not increasing (i.e., going from private ->
// package_private -> publicprotected), the vtable might actually be smaller than our initial
// calculation.
assert(initialized <= _length, "vtable initialization failed");
@@ -188,26 +190,49 @@
}
}
-// Interates through the vtables to find the broadest access level. This
-// will always be monotomic for valid Java programs - but not neccesarily
-// for incompatible class files.
-klassVtable::AccessType klassVtable::vtable_accessibility_at(int i) {
- // This vtable is not implementing the specific method
- if (i >= length()) return acc_private;
+// Called for cases where a method does not override its superclass' vtable entry
+// For bytecodes not produced by javac together it is possible that a method does not override
+// the superclass's method, but might indirectly override a super-super class's vtable entry
+// If none found, return a null superk, else return the superk of the method this does override
+instanceKlass* klassVtable::find_transitive_override(instanceKlass* initialsuper, methodHandle target_method,
+ int vtable_index, Handle target_loader, symbolHandle target_classname, Thread * THREAD) {
+ instanceKlass* superk = initialsuper;
+ while (superk != NULL && superk->super() != NULL) {
+ instanceKlass* supersuperklass = instanceKlass::cast(superk->super());
+ klassVtable* ssVtable = supersuperklass->vtable();
+ if (vtable_index < ssVtable->length()) {
+ methodOop super_method = ssVtable->method_at(vtable_index);
+#ifndef PRODUCT
+ symbolHandle name(THREAD,target_method()->name());
+ symbolHandle signature(THREAD,target_method()->signature());
+ assert(super_method->name() == name() && super_method->signature() == signature(), "vtable entry name/sig mismatch");
+#endif
+ if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) {
+#ifndef PRODUCT
+ if (PrintVtables && Verbose) {
+ ResourceMark rm(THREAD);
+ tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ",
+ supersuperklass->internal_name(),
+ _klass->internal_name(), (target_method() != NULL) ?
+ target_method()->name()->as_C_string() : "<NULL>", vtable_index);
+ super_method->access_flags().print_on(tty);
+ tty->print("overriders flags: ");
+ target_method->access_flags().print_on(tty);
+ tty->cr();
+ }
+#endif /*PRODUCT*/
+ break; // return found superk
+ }
+ } else {
+ // super class has no vtable entry here, stop transitive search
+ superk = (instanceKlass*)NULL;
+ break;
+ }
+ // if no override found yet, continue to search up
+ superk = instanceKlass::cast(superk->super());
+ }
- // Compute AccessType for current method. public or protected we are done.
- methodOop m = method_at(i);
- if (m->is_protected() || m->is_public()) return acc_publicprotected;
-
- AccessType acc = m->is_package_private() ? acc_package_private : acc_private;
-
- // Compute AccessType for method in super classes
- klassOop super = klass()->super();
- AccessType super_acc = (super != NULL) ? instanceKlass::cast(klass()->super())->vtable()->vtable_accessibility_at(i)
- : acc_private;
-
- // Merge
- return (AccessType)MAX2((int)acc, (int)super_acc);
+ return superk;
}
@@ -215,7 +240,8 @@
// OR return true if a new vtable entry is required
// Only called for instanceKlass's, i.e. not for arrays
// If that changed, could not use _klass as handle for klass
-bool klassVtable::update_super_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS) {
+bool klassVtable::update_inherited_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len,
+ bool checkconstraints, TRAPS) {
ResourceMark rm;
bool allocate_new = true;
assert(klass->oop_is_instance(), "must be instanceKlass");
@@ -242,58 +268,35 @@
}
// private methods always have a new entry in the vtable
+ // specification interpretation since classic has
+ // private methods not overriding
if (target_method()->is_private()) {
return allocate_new;
}
// search through the vtable and update overridden entries
// Since check_signature_loaders acquires SystemDictionary_lock
- // which can block for gc, once we are in this loop, use handles, not
- // unhandled oops unless they are reinitialized for each loop
- // handles for name, signature, klass, target_method
- // not for match_method, holder
+ // which can block for gc, once we are in this loop, use handles
+ // For classfiles built with >= jdk7, we now look for transitive overrides
symbolHandle name(THREAD,target_method()->name());
symbolHandle signature(THREAD,target_method()->signature());
+ Handle target_loader(THREAD, _klass->class_loader());
+ symbolHandle target_classname(THREAD, _klass->name());
for(int i = 0; i < super_vtable_len; i++) {
- methodOop match_method = method_at(i);
+ methodOop super_method = method_at(i);
// Check if method name matches
- if (match_method->name() == name() && match_method->signature() == signature()) {
-
- instanceKlass* holder = (THREAD, instanceKlass::cast(match_method->method_holder()));
-
- // Check if the match_method is accessable from current class
-
- bool same_package_init = false;
- bool same_package_flag = false;
- bool simple_match = match_method->is_public() || match_method->is_protected();
- if (!simple_match) {
- same_package_init = true;
- same_package_flag = holder->is_same_class_package(_klass->class_loader(), _klass->name());
+ if (super_method->name() == name() && super_method->signature() == signature()) {
- simple_match = match_method->is_package_private() && same_package_flag;
- }
- // match_method is the superclass' method. Note we can't override
- // and shouldn't access superclass' ACC_PRIVATE methods
- // (although they have been copied into our vtable)
- // A simple form of this statement is:
- // if ( (match_method->is_public() || match_method->is_protected()) ||
- // (match_method->is_package_private() && holder->is_same_class_package(klass->class_loader(), klass->name()))) {
- //
- // The complexity is introduced it avoid recomputing 'is_same_class_package' which is expensive.
- if (simple_match) {
- // Check if target_method and match_method has same level of accessibility. The accesibility of the
- // match method is the "most-general" visibility of all entries at it's particular vtable index for
- // all superclasses. This check must be done before we override the current entry in the vtable.
- AccessType at = vtable_accessibility_at(i);
- bool same_access = false;
+ // get super_klass for method_holder for the found method
+ instanceKlass* super_klass = instanceKlass::cast(super_method->method_holder());
- if ( (at == acc_publicprotected && (target_method()->is_public() || target_method()->is_protected())
- || (at == acc_package_private && (target_method()->is_package_private() &&
- (( same_package_init && same_package_flag) ||
- (!same_package_init && holder->is_same_class_package(_klass->class_loader(), _klass->name()))))))) {
- same_access = true;
- }
+ if ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) ||
+ ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION)
+ && ((super_klass = find_transitive_override(super_klass, target_method, i, target_loader,
+ target_classname, THREAD)) != (instanceKlass*)NULL))) {
+ // overriding, so no new entry
+ allocate_new = false;
if (checkconstraints) {
// Override vtable entry if passes loader constraint check
@@ -302,15 +305,12 @@
// have already made any needed loader constraints.
// Since loader constraints are transitive, it is enough
// to link to the first super, and we get all the others.
- symbolHandle signature(THREAD, target_method()->signature());
- Handle this_loader(THREAD, _klass->class_loader());
- instanceKlassHandle super_klass(THREAD, _klass->super());
Handle super_loader(THREAD, super_klass->class_loader());
- if (this_loader() != super_loader()) {
+ if (target_loader() != super_loader()) {
ResourceMark rm(THREAD);
char* failed_type_name =
- SystemDictionary::check_signature_loaders(signature, this_loader,
+ SystemDictionary::check_signature_loaders(signature, target_loader,
super_loader, true,
CHECK_(false));
if (failed_type_name != NULL) {
@@ -320,7 +320,7 @@
"(instance of %s), have different Class objects for the type "
"%s used in the signature";
char* sig = target_method()->name_and_sig_as_C_string();
- const char* loader1 = SystemDictionary::loader_name(this_loader());
+ const char* loader1 = SystemDictionary::loader_name(target_loader());
char* current = _klass->name()->as_C_string();
const char* loader2 = SystemDictionary::loader_name(super_loader());
size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
@@ -331,59 +331,46 @@
THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false);
}
}
- }
- put_method_at(target_method(), i);
-
+ }
- if (same_access) {
- // target and match has same accessiblity - share entry
- allocate_new = false;
- target_method()->set_vtable_index(i);
+ put_method_at(target_method(), i);
+ target_method()->set_vtable_index(i);
#ifndef PRODUCT
- if (PrintVtables && Verbose) {
- AccessType targetacc;
- if (target_method()->is_protected() ||
- target_method()->is_public()) {
- targetacc = acc_publicprotected;
- } else {
- targetacc = target_method()->is_package_private() ? acc_package_private : acc_private;
- }
- tty->print_cr("overriding with %s::%s index %d, original flags: %x overriders flags: %x",
- _klass->internal_name(), (target_method() != NULL) ?
- target_method()->name()->as_C_string() : "<NULL>", i,
- at, targetacc);
- }
+ if (PrintVtables && Verbose) {
+ tty->print("overriding with %s::%s index %d, original flags: ",
+ _klass->internal_name(), (target_method() != NULL) ?
+ target_method()->name()->as_C_string() : "<NULL>", i);
+ super_method->access_flags().print_on(tty);
+ tty->print("overriders flags: ");
+ target_method->access_flags().print_on(tty);
+ tty->cr();
+ }
#endif /*PRODUCT*/
- } else {
+ } else {
+ // allocate_new = true; default. We might override one entry,
+ // but not override another. Once we override one, not need new
#ifndef PRODUCT
- if (PrintVtables && Verbose) {
- AccessType targetacc;
- if (target_method()->is_protected() ||
- target_method()->is_public()) {
- targetacc = acc_publicprotected;
- } else {
- targetacc = target_method()->is_package_private() ? acc_package_private : acc_private;
- }
- tty->print_cr("override %s %s::%s at index %d, original flags: %x overriders flags: %x",
- allocate_new ? "+ new" : "only",
- _klass->internal_name(), (target_method() != NULL) ?
- target_method()->name()->as_C_string() : "<NULL>", i,
- at, targetacc);
- }
+ if (PrintVtables && Verbose) {
+ tty->print("NOT overriding with %s::%s index %d, original flags: ",
+ _klass->internal_name(), (target_method() != NULL) ?
+ target_method()->name()->as_C_string() : "<NULL>", i);
+ super_method->access_flags().print_on(tty);
+ tty->print("overriders flags: ");
+ target_method->access_flags().print_on(tty);
+ tty->cr();
+ }
#endif /*PRODUCT*/
- }
}
}
}
return allocate_new;
}
-
-
void klassVtable::put_method_at(methodOop m, int index) {
assert(m->is_oop_or_null(), "Not an oop or null");
#ifndef PRODUCT
if (PrintVtables && Verbose) {
+ ResourceMark rm;
tty->print_cr("adding %s::%s at index %d", _klass->internal_name(),
(m != NULL) ? m->name()->as_C_string() : "<NULL>", index);
}
@@ -397,19 +384,23 @@
// by "classloader" and "classname".
// NOTE: The logic used here is very similar to the one used for computing
// the vtables indices for a method. We cannot directly use that function because,
-// when the Universe is boostrapping, a super's vtable might not be initialized.
-bool klassVtable::needs_new_vtable_entry(methodOop target_method,
+// we allocate the instanceKlass at load time, and that requires that the
+// superclass has been loaded.
+// However, the vtable entries are filled in at link time, and therefore
+// the superclass' vtable may not yet have been filled in.
+bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
klassOop super,
- oop classloader,
- symbolOop classname,
- AccessFlags class_flags) {
- if ((class_flags.is_final() || target_method->is_final()) ||
+ Handle classloader,
+ symbolHandle classname,
+ AccessFlags class_flags,
+ TRAPS) {
+ if ((class_flags.is_final() || target_method()->is_final()) ||
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
- (target_method->is_static()) ||
+ (target_method()->is_static()) ||
// static methods don't need to be in vtable
- (target_method->name() == vmSymbols::object_initializer_name())
+ (target_method()->name() == vmSymbols::object_initializer_name())
// <init> is never called dynamically-bound
) {
return false;
@@ -421,55 +412,58 @@
}
// private methods always have a new entry in the vtable
- if (target_method->is_private()) {
+ // specification interpretation since classic has
+ // private methods not overriding
+ if (target_method()->is_private()) {
return true;
}
// search through the super class hierarchy to see if we need
// a new entry
- symbolOop name = target_method->name();
- symbolOop signature = target_method->signature();
+ ResourceMark rm;
+ symbolOop name = target_method()->name();
+ symbolOop signature = target_method()->signature();
klassOop k = super;
- methodOop match_method = NULL;
+ methodOop super_method = NULL;
instanceKlass *holder = NULL;
+ methodOop recheck_method = NULL;
while (k != NULL) {
// lookup through the hierarchy for a method with matching name and sign.
- match_method = instanceKlass::cast(k)->lookup_method(name, signature);
- if (match_method == NULL) {
+ super_method = instanceKlass::cast(k)->lookup_method(name, signature);
+ if (super_method == NULL) {
break; // we still have to search for a matching miranda method
}
// get the class holding the matching method
- holder = instanceKlass::cast(match_method->method_holder());
-
- if (!match_method->is_static()) { // we want only instance method matches
- if ((target_method->is_public() || target_method->is_protected()) &&
- (match_method->is_public() || match_method->is_protected())) {
- // target and match are public/protected; we do not need a new entry
+ // make sure you use that class for is_override
+ instanceKlass* superk = instanceKlass::cast(super_method->method_holder());
+ // we want only instance method matches
+ // pretend private methods are not in the super vtable
+ // since we do override around them: e.g. a.m pub/b.m private/c.m pub,
+ // ignore private, c.m pub does override a.m pub
+ // For classes that were not javac'd together, we also do transitive overriding around
+ // methods that have less accessibility
+ if ((!super_method->is_static()) &&
+ (!super_method->is_private())) {
+ if (superk->is_override(super_method, classloader, classname, THREAD)) {
return false;
- }
-
- if (target_method->is_package_private() &&
- match_method->is_package_private() &&
- holder->is_same_class_package(classloader, classname)) {
- // target and match are P private; we do not need a new entry
- return false;
+ // else keep looking for transitive overrides
}
}
- k = holder->super(); // haven't found a match yet; continue to look
+ // Start with lookup result and continue to search up
+ k = superk->super(); // haven't found an override match yet; continue to look
}
// if the target method is public or protected it may have a matching
// miranda method in the super, whose entry it should re-use.
- if (target_method->is_public() || target_method->is_protected()) {
- instanceKlass *sk = instanceKlass::cast(super);
- if (sk->has_miranda_methods()) {
- if (sk->lookup_method_in_all_interfaces(name, signature) != NULL) {
- return false; // found a matching miranda; we do not need a new entry
- }
+ // Actually, to handle cases that javac would not generate, we need
+ // this check for all access permissions.
+ instanceKlass *sk = instanceKlass::cast(super);
+ if (sk->has_miranda_methods()) {
+ if (sk->lookup_method_in_all_interfaces(name, signature) != NULL) {
+ return false; // found a matching miranda; we do not need a new entry
}
}
-
return true; // found no match; we need a new entry
}
@@ -884,7 +878,7 @@
_klass->name()->as_C_string());
- // Interate through all interfaces
+ // Iterate through all interfaces
int i;
for(i = 0; i < num_interfaces; i++) {
itableOffsetEntry* ioe = offset_entry(i);
@@ -1012,6 +1006,7 @@
new_method->name()->as_C_string(),
new_method->signature()->as_C_string()));
}
+ break;
}
ime++;
}
--- a/hotspot/src/share/vm/oops/klassVtable.hpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp Fri Mar 27 14:35:44 2009 -0400
@@ -70,8 +70,9 @@
// conputes vtable length (in words) and the number of miranda methods
static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods,
klassOop super, objArrayOop methods,
- AccessFlags class_flags, oop classloader,
- symbolOop classname, objArrayOop local_interfaces);
+ AccessFlags class_flags, Handle classloader,
+ symbolHandle classname, objArrayOop local_interfaces,
+ TRAPS);
// RedefineClasses() API support:
// If any entry of this vtable points to any of old_methods,
@@ -111,14 +112,16 @@
protected:
friend class vtableEntry;
private:
+ enum { VTABLE_TRANSITIVE_OVERRIDE_VERSION = 51 } ;
void copy_vtable_to(vtableEntry* start);
int initialize_from_super(KlassHandle super);
int index_of(methodOop m, int len) const; // same as index_of, but search only up to len
void put_method_at(methodOop m, int index);
- static bool needs_new_vtable_entry(methodOop m, klassOop super, oop classloader, symbolOop classname, AccessFlags access_flags);
- AccessType vtable_accessibility_at(int i);
+ static bool needs_new_vtable_entry(methodHandle m, klassOop super, Handle classloader, symbolHandle classname, AccessFlags access_flags, TRAPS);
- bool update_super_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS);
+ bool update_inherited_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS);
+ instanceKlass* find_transitive_override(instanceKlass* initialsuper, methodHandle target_method, int vtable_index,
+ Handle target_loader, symbolHandle target_classname, Thread* THREAD);
// support for miranda methods
bool is_miranda_entry_at(int i);
--- a/hotspot/src/share/vm/prims/jni.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/prims/jni.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -301,6 +301,10 @@
klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader,
Handle(), &st, CHECK_NULL);
+ if (TraceClassResolution && k != NULL) {
+ trace_class_resolution(k);
+ }
+
cls = (jclass)JNIHandles::make_local(
env, Klass::cast(k)->java_mirror());
return cls;
@@ -365,6 +369,10 @@
result = find_class_from_class_loader(env, sym, true, loader,
protection_domain, true, thread);
+ if (TraceClassResolution && result != NULL) {
+ trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
+ }
+
// If we were the first invocation of jni_FindClass, we enable compilation again
// rather than just allowing invocation counter to overflow and decay.
// Controlled by flag DelayCompilationDuringStartup.
@@ -2646,7 +2654,12 @@
Handle protection_domain; // null protection domain
symbolHandle sym = oopFactory::new_symbol_handle(name, CHECK_NULL);
- return find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
+ jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
+
+ if (TraceClassResolution && result != NULL) {
+ trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
+ }
+ return result;
}
// These lookups are done with the NULL (bootstrap) ClassLoader to
--- a/hotspot/src/share/vm/prims/jvm.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -64,6 +64,7 @@
ResourceMark rm;
int line_number = -1;
const char * source_file = NULL;
+ const char * trace = "explicit";
klassOop caller = NULL;
JavaThread* jthread = JavaThread::current();
if (jthread->has_last_Java_frame()) {
@@ -107,12 +108,21 @@
(last_caller->name() == vmSymbols::loadClassInternal_name() ||
last_caller->name() == vmSymbols::loadClass_name())) {
found_it = true;
+ } else if (!vfst.at_end()) {
+ if (vfst.method()->is_native()) {
+ // JNI call
+ found_it = true;
+ }
}
if (found_it && !vfst.at_end()) {
// found the caller
caller = vfst.method()->method_holder();
line_number = vfst.method()->line_number_from_bci(vfst.bci());
- symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name();
+ if (line_number == -1) {
+ // show method name if it's a native method
+ trace = vfst.method()->name_and_sig_as_C_string();
+ }
+ symbolOop s = instanceKlass::cast(caller)->source_file_name();
if (s != NULL) {
source_file = s->as_C_string();
}
@@ -124,15 +134,15 @@
const char * to = Klass::cast(to_class)->external_name();
// print in a single call to reduce interleaving between threads
if (source_file != NULL) {
- tty->print("RESOLVE %s %s %s:%d (explicit)\n", from, to, source_file, line_number);
+ tty->print("RESOLVE %s %s %s:%d (%s)\n", from, to, source_file, line_number, trace);
} else {
- tty->print("RESOLVE %s %s (explicit)\n", from, to);
+ tty->print("RESOLVE %s %s (%s)\n", from, to, trace);
}
}
}
}
-static void trace_class_resolution(klassOop to_class) {
+void trace_class_resolution(klassOop to_class) {
EXCEPTION_MARK;
trace_class_resolution_impl(to_class, THREAD);
if (HAS_PENDING_EXCEPTION) {
@@ -3213,8 +3223,12 @@
}
Handle h_loader(THREAD, loader);
Handle h_prot (THREAD, protection_domain);
- return find_class_from_class_loader(env, name, true, h_loader, h_prot,
- false, thread);
+ jclass result = find_class_from_class_loader(env, name, true, h_loader, h_prot,
+ false, thread);
+ if (TraceClassResolution && result != NULL) {
+ trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
+ }
+ return result;
JVM_END
--- a/hotspot/src/share/vm/prims/jvm_misc.hpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/prims/jvm_misc.hpp Fri Mar 27 14:35:44 2009 -0400
@@ -27,6 +27,7 @@
jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS);
+void trace_class_resolution(klassOop to_class);
/*
* Support for Serialization and RMI. Currently used by HotSpot only.
--- a/hotspot/src/share/vm/runtime/os.hpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/runtime/os.hpp Fri Mar 27 14:35:44 2009 -0400
@@ -202,8 +202,10 @@
static char* attempt_reserve_memory_at(size_t bytes, char* addr);
static void split_reserved_memory(char *base, size_t size,
size_t split, bool realloc);
- static bool commit_memory(char* addr, size_t bytes);
- static bool commit_memory(char* addr, size_t size, size_t alignment_hint);
+ static bool commit_memory(char* addr, size_t bytes,
+ bool executable = false);
+ static bool commit_memory(char* addr, size_t size, size_t alignment_hint,
+ bool executable = false);
static bool uncommit_memory(char* addr, size_t bytes);
static bool release_memory(char* addr, size_t bytes);
@@ -243,7 +245,8 @@
static char* non_memory_address_word();
// reserve, commit and pin the entire memory region
- static char* reserve_memory_special(size_t size, char* addr = NULL);
+ static char* reserve_memory_special(size_t size, char* addr = NULL,
+ bool executable = false);
static bool release_memory_special(char* addr, size_t bytes);
static bool large_page_init();
static size_t large_page_size();
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Fri Mar 27 14:35:44 2009 -0400
@@ -28,7 +28,7 @@
// ReservedSpace
ReservedSpace::ReservedSpace(size_t size) {
- initialize(size, 0, false, NULL, 0);
+ initialize(size, 0, false, NULL, 0, false);
}
ReservedSpace::ReservedSpace(size_t size, size_t alignment,
@@ -36,7 +36,13 @@
char* requested_address,
const size_t noaccess_prefix) {
initialize(size+noaccess_prefix, alignment, large, requested_address,
- noaccess_prefix);
+ noaccess_prefix, false);
+}
+
+ReservedSpace::ReservedSpace(size_t size, size_t alignment,
+ bool large,
+ bool executable) {
+ initialize(size, alignment, large, NULL, 0, executable);
}
char *
@@ -132,7 +138,8 @@
const bool try_reserve_special = UseLargePages &&
prefix_align == os::large_page_size();
if (!os::can_commit_large_page_memory() && try_reserve_special) {
- initialize(size, prefix_align, true, requested_address, noaccess_prefix);
+ initialize(size, prefix_align, true, requested_address, noaccess_prefix,
+ false);
return;
}
@@ -141,6 +148,7 @@
_alignment = 0;
_special = false;
_noaccess_prefix = 0;
+ _executable = false;
// Assert that if noaccess_prefix is used, it is the same as prefix_align.
assert(noaccess_prefix == 0 ||
@@ -189,7 +197,8 @@
void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
char* requested_address,
- const size_t noaccess_prefix) {
+ const size_t noaccess_prefix,
+ bool executable) {
const size_t granularity = os::vm_allocation_granularity();
assert((size & granularity - 1) == 0,
"size not aligned to os::vm_allocation_granularity()");
@@ -201,6 +210,7 @@
_base = NULL;
_size = 0;
_special = false;
+ _executable = executable;
_alignment = 0;
_noaccess_prefix = 0;
if (size == 0) {
@@ -214,7 +224,7 @@
if (special) {
- base = os::reserve_memory_special(size, requested_address);
+ base = os::reserve_memory_special(size, requested_address, executable);
if (base != NULL) {
// Check alignment constraints
@@ -284,7 +294,7 @@
ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
- bool special) {
+ bool special, bool executable) {
assert((size % os::vm_allocation_granularity()) == 0,
"size not allocation aligned");
_base = base;
@@ -292,6 +302,7 @@
_alignment = alignment;
_noaccess_prefix = 0;
_special = special;
+ _executable = executable;
}
@@ -299,9 +310,10 @@
bool split, bool realloc) {
assert(partition_size <= size(), "partition failed");
if (split) {
- os::split_reserved_memory(_base, _size, partition_size, realloc);
+ os::split_reserved_memory(base(), size(), partition_size, realloc);
}
- ReservedSpace result(base(), partition_size, alignment, special());
+ ReservedSpace result(base(), partition_size, alignment, special(),
+ executable());
return result;
}
@@ -310,7 +322,7 @@
ReservedSpace::last_part(size_t partition_size, size_t alignment) {
assert(partition_size <= size(), "partition failed");
ReservedSpace result(base() + partition_size, size() - partition_size,
- alignment, special());
+ alignment, special(), executable());
return result;
}
@@ -348,6 +360,7 @@
_size = 0;
_noaccess_prefix = 0;
_special = false;
+ _executable = false;
}
}
@@ -396,6 +409,14 @@
protect_noaccess_prefix(prefix_size+suffix_size);
}
+// Reserve space for code segment. Same as Java heap only we mark this as
+// executable.
+ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
+ size_t rs_align,
+ bool large) :
+ ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
+}
+
// VirtualSpace
VirtualSpace::VirtualSpace() {
@@ -413,6 +434,7 @@
_middle_alignment = 0;
_upper_alignment = 0;
_special = false;
+ _executable = false;
}
@@ -426,6 +448,7 @@
_high = low();
_special = rs.special();
+ _executable = rs.executable();
// When a VirtualSpace begins life at a large size, make all future expansion
// and shrinking occur aligned to a granularity of large pages. This avoids
@@ -483,6 +506,7 @@
_middle_alignment = 0;
_upper_alignment = 0;
_special = false;
+ _executable = false;
}
@@ -592,7 +616,7 @@
assert(low_boundary() <= lower_high() &&
lower_high() + lower_needs <= lower_high_boundary(),
"must not expand beyond region");
- if (!os::commit_memory(lower_high(), lower_needs)) {
+ if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
debug_only(warning("os::commit_memory failed"));
return false;
} else {
@@ -603,7 +627,8 @@
assert(lower_high_boundary() <= middle_high() &&
middle_high() + middle_needs <= middle_high_boundary(),
"must not expand beyond region");
- if (!os::commit_memory(middle_high(), middle_needs, middle_alignment())) {
+ if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
+ _executable)) {
debug_only(warning("os::commit_memory failed"));
return false;
}
@@ -613,7 +638,7 @@
assert(middle_high_boundary() <= upper_high() &&
upper_high() + upper_needs <= upper_high_boundary(),
"must not expand beyond region");
- if (!os::commit_memory(upper_high(), upper_needs)) {
+ if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
debug_only(warning("os::commit_memory failed"));
return false;
} else {
--- a/hotspot/src/share/vm/runtime/virtualspace.hpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/runtime/virtualspace.hpp Fri Mar 27 14:35:44 2009 -0400
@@ -32,12 +32,15 @@
size_t _noaccess_prefix;
size_t _alignment;
bool _special;
+ bool _executable;
// ReservedSpace
- ReservedSpace(char* base, size_t size, size_t alignment, bool special);
+ ReservedSpace(char* base, size_t size, size_t alignment, bool special,
+ bool executable);
void initialize(size_t size, size_t alignment, bool large,
char* requested_address,
- const size_t noaccess_prefix);
+ const size_t noaccess_prefix,
+ bool executable);
// Release parts of an already-reserved memory region [addr, addr + len) to
// get a new region that has "compound alignment." Return the start of the
@@ -75,16 +78,16 @@
const size_t suffix_size, const size_t suffix_align,
char* requested_address,
const size_t noaccess_prefix = 0);
+ ReservedSpace(size_t size, size_t alignment, bool large, bool executable);
// Accessors
- char* base() const { return _base; }
- size_t size() const { return _size; }
- size_t alignment() const { return _alignment; }
- bool special() const { return _special; }
-
- size_t noaccess_prefix() const { return _noaccess_prefix; }
-
- bool is_reserved() const { return _base != NULL; }
+ char* base() const { return _base; }
+ size_t size() const { return _size; }
+ size_t alignment() const { return _alignment; }
+ bool special() const { return _special; }
+ bool executable() const { return _executable; }
+ size_t noaccess_prefix() const { return _noaccess_prefix; }
+ bool is_reserved() const { return _base != NULL; }
void release();
// Splitting
@@ -126,6 +129,13 @@
char* requested_address);
};
+// Class encapsulating behavior specific memory space for Code
+class ReservedCodeSpace : public ReservedSpace {
+ public:
+ // Constructor
+ ReservedCodeSpace(size_t r_size, size_t rs_align, bool large);
+};
+
// VirtualSpace is data structure for committing a previously reserved address range in smaller chunks.
class VirtualSpace VALUE_OBJ_CLASS_SPEC {
@@ -143,6 +153,9 @@
// os::commit_memory() or os::uncommit_memory().
bool _special;
+ // Need to know if commit should be executable.
+ bool _executable;
+
// MPSS Support
// Each virtualspace region has a lower, middle, and upper region.
// Each region has an end boundary and a high pointer which is the
--- a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp Wed Mar 25 10:36:08 2009 -0400
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp Fri Mar 27 14:35:44 2009 -0400
@@ -153,14 +153,6 @@
//----------------------------------------------------------------------------------------------------
// Miscellaneous
-inline int vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
- // If number of characters written == count, Windows doesn't write a
- // terminating NULL, so we do it ourselves.
- int ret = _vsnprintf(buf, count, fmt, argptr);
- if (count > 0) buf[count-1] = '\0';
- return ret;
-}
-
// Visual Studio 2005 deprecates POSIX names - use ISO C++ names instead
#if _MSC_VER >= 1400
#define open _open
@@ -180,6 +172,17 @@
#pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union (needed in windows.h)
#pragma warning( disable : 4511 ) // copy constructor could not be generated
#pragma warning( disable : 4291 ) // no matching operator delete found; memory will not be freed if initialization thows an exception
+#if _MSC_VER >= 1400
+#pragma warning( disable : 4996 ) // unsafe string functions. Same as define _CRT_SECURE_NO_WARNINGS/_CRT_SECURE_NO_DEPRICATE
+#endif
+
+inline int vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
+ // If number of characters written == count, Windows doesn't write a
+ // terminating NULL, so we do it ourselves.
+ int ret = _vsnprintf(buf, count, fmt, argptr);
+ if (count > 0) buf[count-1] = '\0';
+ return ret;
+}
// Portability macros
#define PRAGMA_INTERFACE