From 86dac44dac393c57cb72921d815ff1b6a29f5022 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Fri, 23 Mar 2012 11:50:33 -0700 Subject: [PATCH 01/51] 7102323: RFE: enable Full Debug Symbols Phase 1 on Solaris Add support for ENABLE_FULL_DEBUG_SYMBOLS and ZIP_DEBUGINFO_FILES build flags. Add support for .diz files. Reviewed-by: dholmes, ohair, sspitsyn --- hotspot/make/Makefile | 22 +++ hotspot/make/linux/Makefile | 4 +- hotspot/make/linux/makefiles/buildtree.make | 8 +- hotspot/make/linux/makefiles/defs.make | 95 +++++++----- hotspot/make/linux/makefiles/gcc.make | 4 +- hotspot/make/linux/makefiles/jsig.make | 14 +- hotspot/make/linux/makefiles/saproc.make | 12 +- hotspot/make/linux/makefiles/vm.make | 16 +- hotspot/make/solaris/Makefile | 4 +- hotspot/make/solaris/makefiles/buildtree.make | 8 +- hotspot/make/solaris/makefiles/defs.make | 140 +++++++++++------- hotspot/make/solaris/makefiles/dtrace.make | 52 +++++-- hotspot/make/solaris/makefiles/jsig.make | 14 +- hotspot/make/solaris/makefiles/saproc.make | 14 +- .../make/solaris/makefiles/sparcWorks.make | 6 +- hotspot/make/solaris/makefiles/vm.make | 16 +- hotspot/make/windows/build.make | 6 +- hotspot/make/windows/makefiles/compile.make | 11 +- hotspot/make/windows/makefiles/debug.make | 8 +- hotspot/make/windows/makefiles/defs.make | 58 ++++++-- hotspot/make/windows/makefiles/fastdebug.make | 8 +- hotspot/make/windows/makefiles/product.make | 8 +- hotspot/make/windows/makefiles/sa.make | 24 ++- 23 files changed, 406 insertions(+), 146 deletions(-) diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile index 8bebef46972..5492205e4e2 100644 --- a/hotspot/make/Makefile +++ b/hotspot/make/Makefile @@ -298,6 +298,8 @@ $(EXPORT_LIB_DIR)/%.lib: $(MISC_DIR)/%.lib $(install-file) # Other libraries (like SA) +$(EXPORT_JRE_BIN_DIR)/%.diz: $(MISC_DIR)/%.diz + $(install-file) $(EXPORT_JRE_BIN_DIR)/%.dll: $(MISC_DIR)/%.dll $(install-file) $(EXPORT_JRE_BIN_DIR)/%.pdb: $(MISC_DIR)/%.pdb @@ -306,6 +308,8 @@ $(EXPORT_JRE_BIN_DIR)/%.map: $(MISC_DIR)/%.map $(install-file) # Client files always come from C1 area +$(EXPORT_CLIENT_DIR)/%.diz: $(C1_DIR)/%.diz + $(install-file) $(EXPORT_CLIENT_DIR)/%.dll: $(C1_DIR)/%.dll $(install-file) $(EXPORT_CLIENT_DIR)/%.pdb: $(C1_DIR)/%.pdb @@ -314,6 +318,8 @@ $(EXPORT_CLIENT_DIR)/%.map: $(C1_DIR)/%.map $(install-file) # Server files always come from C2 area +$(EXPORT_SERVER_DIR)/%.diz: $(C2_DIR)/%.diz + $(install-file) $(EXPORT_SERVER_DIR)/%.dll: $(C2_DIR)/%.dll $(install-file) $(EXPORT_SERVER_DIR)/%.pdb: $(C2_DIR)/%.pdb @@ -322,6 +328,8 @@ $(EXPORT_SERVER_DIR)/%.map: $(C2_DIR)/%.map $(install-file) # Kernel files always come from kernel area +$(EXPORT_KERNEL_DIR)/%.diz: $(KERNEL_DIR)/%.diz + $(install-file) $(EXPORT_KERNEL_DIR)/%.dll: $(KERNEL_DIR)/%.dll $(install-file) $(EXPORT_KERNEL_DIR)/%.pdb: $(KERNEL_DIR)/%.pdb @@ -371,6 +379,20 @@ $(EXPORT_SERVER_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo $(install-file) $(EXPORT_SERVER_DIR)/64/%.debuginfo: $(C2_DIR)/%.debuginfo $(install-file) + +# ZIP'ed debug info for shared library +$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C1_DIR)/%.diz + $(install-file) +$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C2_DIR)/%.diz + $(install-file) +$(EXPORT_CLIENT_DIR)/%.diz: $(C1_DIR)/%.diz + $(install-file) +$(EXPORT_CLIENT_DIR)/64/%.diz: $(C1_DIR)/%.diz + $(install-file) +$(EXPORT_SERVER_DIR)/%.diz: $(C2_DIR)/%.diz + $(install-file) +$(EXPORT_SERVER_DIR)/64/%.diz: $(C2_DIR)/%.diz + $(install-file) endif endif diff --git a/hotspot/make/linux/Makefile b/hotspot/make/linux/Makefile index 22dcd5369d2..4c1854f124f 100644 --- a/hotspot/make/linux/Makefile +++ b/hotspot/make/linux/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012, 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 @@ -210,7 +210,7 @@ TARGETS_SHARK = $(addsuffix shark,$(TARGETS)) BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) HOTSPOT_BUILD_VERSION=$(HOTSPOT_BUILD_VERSION) JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -BUILDTREE_VARS += OBJCOPY=$(OBJCOPY) STRIP_POLICY=$(STRIP_POLICY) +BUILDTREE_VARS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) OBJCOPY=$(OBJCOPY) STRIP_POLICY=$(STRIP_POLICY) ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES) ZIPEXE=$(ZIPEXE) BUILDTREE = $(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_VARS) diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make index 5bc29368e5e..0581fac90e2 100644 --- a/hotspot/make/linux/makefiles/buildtree.make +++ b/hotspot/make/linux/makefiles/buildtree.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, 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 @@ -235,10 +235,16 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "$(call gamma-path,commonsrc,os/posix/vm)"; \ [ -n "$(CFLAGS_BROWSE)" ] && \ echo && echo "CFLAGS_BROWSE = $(CFLAGS_BROWSE)"; \ + [ -n "$(ENABLE_FULL_DEBUG_SYMBOLS)" ] && \ + echo && echo "ENABLE_FULL_DEBUG_SYMBOLS = $(ENABLE_FULL_DEBUG_SYMBOLS)"; \ [ -n "$(OBJCOPY)" ] && \ echo && echo "OBJCOPY = $(OBJCOPY)"; \ [ -n "$(STRIP_POLICY)" ] && \ echo && echo "STRIP_POLICY = $(STRIP_POLICY)"; \ + [ -n "$(ZIP_DEBUGINFO_FILES)" ] && \ + echo && echo "ZIP_DEBUGINFO_FILES = $(ZIP_DEBUGINFO_FILES)"; \ + [ -n "$(ZIPEXE)" ] && \ + echo && echo "ZIPEXE = $(ZIPEXE)"; \ [ -n "$(HOTSPOT_EXTRA_SYSDEFS)" ] && \ echo && \ echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \ diff --git a/hotspot/make/linux/makefiles/defs.make b/hotspot/make/linux/makefiles/defs.make index df5b8e4fa59..632a99b6a5c 100644 --- a/hotspot/make/linux/makefiles/defs.make +++ b/hotspot/make/linux/makefiles/defs.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012, 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 @@ -129,32 +129,40 @@ else endif ifeq ($(JDK6_OR_EARLIER),0) - # Full Debug Symbols is supported on JDK7 or newer + # Full Debug Symbols is supported on JDK7 or newer. + # Default is enabled with .debuginfo files ZIP'ed to save space. - # Default OBJCOPY comes from GNU Binutils on Linux: - DEF_OBJCOPY=/usr/bin/objcopy - ifdef CROSS_COMPILE_ARCH - # don't try to generate .debuginfo files when cross compiling - _JUNK_ := $(shell \ - echo >&2 "INFO: cross compiling for ARCH $(CROSS_COMPILE_ARCH)," \ - "skipping .debuginfo generation.") - OBJCOPY= - else - OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) - ifneq ($(ALT_OBJCOPY),) - _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") - # disable .debuginfo support by setting ALT_OBJCOPY to a non-existent path - OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) + ENABLE_FULL_DEBUG_SYMBOLS ?= 1 + # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later + + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + # Default OBJCOPY comes from GNU Binutils on Linux: + DEF_OBJCOPY=/usr/bin/objcopy + ifdef CROSS_COMPILE_ARCH + # don't try to generate .debuginfo files when cross compiling + _JUNK_ := $(shell \ + echo >&2 "INFO: cross compiling for ARCH $(CROSS_COMPILE_ARCH)," \ + "skipping .debuginfo generation.") + OBJCOPY= + else + OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) + ifneq ($(ALT_OBJCOPY),) + _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") + OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) + endif endif + else + OBJCOPY= endif - + ifeq ($(OBJCOPY),) _JUNK_ := $(shell \ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.") + ENABLE_FULL_DEBUG_SYMBOLS=0 else _JUNK_ := $(shell \ echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.") - + # Library stripping policies for .debuginfo configs: # all_strip - strips everything from the library # min_strip - strips most stuff from the library; leaves minimum symbols @@ -163,15 +171,17 @@ ifeq ($(JDK6_OR_EARLIER),0) # Oracle security policy requires "all_strip". A waiver was granted on # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE. # - DEF_STRIP_POLICY="min_strip" - ifeq ($(ALT_STRIP_POLICY),) - STRIP_POLICY=$(DEF_STRIP_POLICY) - else - STRIP_POLICY=$(ALT_STRIP_POLICY) - endif - + # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled. + # + STRIP_POLICY ?= min_strip + _JUNK_ := $(shell \ echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)") + + ZIP_DEBUGINFO_FILES ?= 1 + + _JUNK_ := $(shell \ + echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)") endif endif @@ -187,8 +197,12 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html # client and server subdirectories have symbolic links to ../libjsig.so EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX) -ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.diz + else + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo + endif endif EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client @@ -196,8 +210,12 @@ EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client ifndef BUILD_CLIENT_ONLY EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX) - ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.diz + else + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo + endif endif endif @@ -205,8 +223,12 @@ ifneq ($(ZERO_BUILD), true) ifeq ($(ARCH_DATA_MODEL), 32) EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX) - ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.diz + else + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo + endif endif endif endif @@ -217,9 +239,14 @@ ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \ $(EXPORT_LIB_DIR)/sa-jdi.jar ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \ $(EXPORT_LIB_DIR)/sa-jdi.jar -ifneq ($(OBJCOPY),) - ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo - ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz + ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz + else + ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo + ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo + endif endif ADD_SA_BINARIES/ppc = ADD_SA_BINARIES/ia64 = diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make index 0188ed772d5..7ad7e43d64e 100644 --- a/hotspot/make/linux/makefiles/gcc.make +++ b/hotspot/make/linux/makefiles/gcc.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012, 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 @@ -224,7 +224,7 @@ ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) DEBUG_CFLAGS += -gstabs endif -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) FASTDEBUG_CFLAGS/ia64 = -g FASTDEBUG_CFLAGS/amd64 = -g FASTDEBUG_CFLAGS/arm = -g diff --git a/hotspot/make/linux/makefiles/jsig.make b/hotspot/make/linux/makefiles/jsig.make index 9408e4961d4..1d013fcb1f6 100644 --- a/hotspot/make/linux/makefiles/jsig.make +++ b/hotspot/make/linux/makefiles/jsig.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -32,12 +32,15 @@ JSIG_G = $(JSIG)$(G_SUFFIX) LIBJSIG_G = lib$(JSIG_G).so LIBJSIG_DEBUGINFO = lib$(JSIG).debuginfo +LIBJSIG_DIZ = lib$(JSIG).diz LIBJSIG_G_DEBUGINFO = lib$(JSIG_G).debuginfo +LIBJSIG_G_DIZ = lib$(JSIG_G).diz JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG) DEST_JSIG_DEBUGINFO = $(JDK_LIBDIR)/$(LIBJSIG_DEBUGINFO) +DEST_JSIG_DIZ = $(JDK_LIBDIR)/$(LIBJSIG_DIZ) LIBJSIG_MAPFILE = $(MAKEFILES_DIR)/mapfile-vers-jsig @@ -58,7 +61,7 @@ $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl $(QUIETLY) [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -70,12 +73,19 @@ ifneq ($(OBJCOPY),) endif endif [ -f $(LIBJSIG_G_DEBUGINFO) ] || { ln -s $(LIBJSIG_DEBUGINFO) $(LIBJSIG_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJSIG_DIZ) $(LIBJSIG_DEBUGINFO) $(LIBJSIG_G_DEBUGINFO) + $(RM) $(LIBJSIG_DEBUGINFO) $(LIBJSIG_G_DEBUGINFO) + [ -f $(LIBJSIG_G_DIZ) ] || { ln -s $(LIBJSIG_DIZ) $(LIBJSIG_G_DIZ); } + endif endif install_jsig: $(LIBJSIG) @echo "Copying $(LIBJSIG) to $(DEST_JSIG)" $(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ cp -f $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) + $(QUIETLY) test -f $(LIBJSIG_DIZ) && \ + cp -f $(LIBJSIG_DIZ) $(DEST_JSIG_DIZ) $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done" .PHONY: install_jsig diff --git a/hotspot/make/linux/makefiles/saproc.make b/hotspot/make/linux/makefiles/saproc.make index 36a06aeae08..09beebd7f71 100644 --- a/hotspot/make/linux/makefiles/saproc.make +++ b/hotspot/make/linux/makefiles/saproc.make @@ -33,7 +33,9 @@ SAPROC_G = $(SAPROC)$(G_SUFFIX) LIBSAPROC_G = lib$(SAPROC_G).so LIBSAPROC_DEBUGINFO = lib$(SAPROC).debuginfo +LIBSAPROC_DIZ = lib$(SAPROC).diz LIBSAPROC_G_DEBUGINFO = lib$(SAPROC_G).debuginfo +LIBSAPROC_G_DIZ = lib$(SAPROC_G).diz AGENT_DIR = $(GAMMADIR)/agent @@ -50,6 +52,7 @@ SAMAPFILE = $(SASRCDIR)/mapfile DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC) DEST_SAPROC_DEBUGINFO = $(JDK_LIBDIR)/$(LIBSAPROC_DEBUGINFO) +DEST_SAPROC_DIZ = $(JDK_LIBDIR)/$(LIBSAPROC_DIZ) # DEBUG_BINARIES overrides everything, use full -g debug information ifeq ($(DEBUG_BINARIES), true) @@ -87,7 +90,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE) -o $@ \ -lthread_db $(QUIETLY) [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -99,6 +102,11 @@ ifneq ($(OBJCOPY),) endif endif [ -f $(LIBSAPROC_G_DEBUGINFO) ] || { ln -s $(LIBSAPROC_DEBUGINFO) $(LIBSAPROC_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBSAPROC_DIZ) $(LIBSAPROC_DEBUGINFO) $(LIBSAPROC_G_DEBUGINFO) + $(RM) $(LIBSAPROC_DEBUGINFO) $(LIBSAPROC_G_DEBUGINFO) + [ -f $(LIBSAPROC_G_DIZ) ] || { ln -s $(LIBSAPROC_DIZ) $(LIBSAPROC_G_DIZ); } + endif endif install_saproc: $(BUILDLIBSAPROC) @@ -106,6 +114,8 @@ install_saproc: $(BUILDLIBSAPROC) echo "Copying $(LIBSAPROC) to $(DEST_SAPROC)"; \ test -f $(LIBSAPROC_DEBUGINFO) && \ cp -f $(LIBSAPROC_DEBUGINFO) $(DEST_SAPROC_DEBUGINFO); \ + test -f $(LIBSAPROC_DIZ) && \ + cp -f $(LIBSAPROC_DIZ) $(DEST_SAPROC_DIZ); \ cp -f $(LIBSAPROC) $(DEST_SAPROC) && echo "Done"; \ fi diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make index 462f2789bfa..c372af91bfa 100644 --- a/hotspot/make/linux/makefiles/vm.make +++ b/hotspot/make/linux/makefiles/vm.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012, 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 @@ -61,7 +61,7 @@ Src_Dirs_I += $(GENERATED) INCLUDES += $(PRECOMPILED_HEADER_DIR:%=-I%) $(Src_Dirs_I:%=-I%) # SYMFLAG is used by {jsig,saproc}.make -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) # always build with debug info when we can create .debuginfo files SYMFLAG = -g else @@ -139,7 +139,9 @@ LIBJVM = lib$(JVM).so LIBJVM_G = lib$(JVM)$(G_SUFFIX).so LIBJVM_DEBUGINFO = lib$(JVM).debuginfo +LIBJVM_DIZ = lib$(JVM).diz LIBJVM_G_DEBUGINFO = lib$(JVM)$(G_SUFFIX).debuginfo +LIBJVM_G_DIZ = lib$(JVM)$(G_SUFFIX).diz SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt @@ -331,7 +333,7 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT) fi \ } ifeq ($(CROSS_COMPILE_ARCH),) - ifneq ($(OBJCOPY),) + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -343,17 +345,25 @@ ifeq ($(CROSS_COMPILE_ARCH),) endif endif $(QUIETLY) [ -f $(LIBJVM_G_DEBUGINFO) ] || ln -s $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO) + $(RM) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO) + [ -f $(LIBJVM_G_DIZ) ] || { ln -s $(LIBJVM_DIZ) $(LIBJVM_G_DIZ); } + endif endif endif DEST_SUBDIR = $(JDK_LIBDIR)/$(VM_SUBDIR) DEST_JVM = $(DEST_SUBDIR)/$(LIBJVM) DEST_JVM_DEBUGINFO = $(DEST_SUBDIR)/$(LIBJVM_DEBUGINFO) +DEST_JVM_DIZ = $(DEST_SUBDIR)/$(LIBJVM_DIZ) install_jvm: $(LIBJVM) @echo "Copying $(LIBJVM) to $(DEST_JVM)" $(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ cp -f $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) + $(QUIETLY) test -f $(LIBJVM_DIZ) && \ + cp -f $(LIBJVM_DIZ) $(DEST_JVM_DIZ) $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done" #---------------------------------------------------------------------- diff --git a/hotspot/make/solaris/Makefile b/hotspot/make/solaris/Makefile index e1f32c4cf35..ae6b2be6b23 100644 --- a/hotspot/make/solaris/Makefile +++ b/hotspot/make/solaris/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2012, 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 @@ -168,7 +168,7 @@ TARGETS_KERNEL = $(addsuffix kernel,$(TARGETS)) BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) HOTSPOT_BUILD_VERSION=$(HOTSPOT_BUILD_VERSION) JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -BUILDTREE_VARS += OBJCOPY=$(OBJCOPY) STRIP_POLICY=$(STRIP_POLICY) +BUILDTREE_VARS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) OBJCOPY=$(OBJCOPY) STRIP_POLICY=$(STRIP_POLICY) ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES) ZIPEXE=$(ZIPEXE) BUILDTREE = $(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_VARS) diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make index 129a4849431..808de3bf183 100644 --- a/hotspot/make/solaris/makefiles/buildtree.make +++ b/hotspot/make/solaris/makefiles/buildtree.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012, 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 @@ -228,10 +228,16 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "$(call gamma-path,commonsrc,os/posix/vm)"; \ [ -n "$(CFLAGS_BROWSE)" ] && \ echo && echo "CFLAGS_BROWSE = $(CFLAGS_BROWSE)"; \ + [ -n "$(ENABLE_FULL_DEBUG_SYMBOLS)" ] && \ + echo && echo "ENABLE_FULL_DEBUG_SYMBOLS = $(ENABLE_FULL_DEBUG_SYMBOLS)"; \ [ -n "$(OBJCOPY)" ] && \ echo && echo "OBJCOPY = $(OBJCOPY)"; \ [ -n "$(STRIP_POLICY)" ] && \ echo && echo "STRIP_POLICY = $(STRIP_POLICY)"; \ + [ -n "$(ZIP_DEBUGINFO_FILES)" ] && \ + echo && echo "ZIP_DEBUGINFO_FILES = $(ZIP_DEBUGINFO_FILES)"; \ + [ -n "$(ZIPEXE)" ] && \ + echo && echo "ZIPEXE = $(ZIPEXE)"; \ [ -n "$(HOTSPOT_EXTRA_SYSDEFS)" ] && \ echo && \ echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \ diff --git a/hotspot/make/solaris/makefiles/defs.make b/hotspot/make/solaris/makefiles/defs.make index f4b6ea3796f..3674d48e475 100644 --- a/hotspot/make/solaris/makefiles/defs.make +++ b/hotspot/make/solaris/makefiles/defs.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012, 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 @@ -74,45 +74,47 @@ else endif ifeq ($(JDK6_OR_EARLIER),0) - # Full Debug Symbols is supported on JDK7 or newer + # Full Debug Symbols is supported on JDK7 or newer. + # Default is enabled with .debuginfo files ZIP'ed to save space. -ifdef ENABLE_FULL_DEBUG_SYMBOLS - # Only check for Full Debug Symbols support on Solaris if it is - # specifically enabled. Hopefully, it can be enabled by default - # once the .debuginfo size issues are worked out. - - # Default OBJCOPY comes from the SUNWbinutils package: - DEF_OBJCOPY=/usr/sfw/bin/gobjcopy - ifeq ($(VM_PLATFORM),solaris_amd64) - # On Solaris AMD64/X64, gobjcopy is not happy and fails: - # - # usr/sfw/bin/gobjcopy --add-gnu-debuglink=.debuginfo .so - # BFD: stKPaiop: Not enough room for program headers, try linking with -N - # /usr/sfw/bin/gobjcopy: stKPaiop: Bad value - # BFD: stKPaiop: Not enough room for program headers, try linking with -N - # /usr/sfw/bin/gobjcopy: libsaproc.debuginfo: Bad value - # BFD: stKPaiop: Not enough room for program headers, try linking with -N - # /usr/sfw/bin/gobjcopy: stKPaiop: Bad value - _JUNK_ := $(shell \ - echo >&2 "INFO: $(DEF_OBJCOPY) is not working on Solaris AMD64/X64") - OBJCOPY= - else - OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) - ifneq ($(ALT_OBJCOPY),) - _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") - # disable .debuginfo support by setting ALT_OBJCOPY to a non-existent path - OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) + ENABLE_FULL_DEBUG_SYMBOLS ?= 1 + # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later + + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + # Default OBJCOPY comes from the SUNWbinutils package: + DEF_OBJCOPY=/usr/sfw/bin/gobjcopy + ifeq ($(VM_PLATFORM),solaris_amd64) + # On Solaris AMD64/X64, gobjcopy is not happy and fails: + # + # usr/sfw/bin/gobjcopy --add-gnu-debuglink=.debuginfo .so + # BFD: stKPaiop: Not enough room for program headers, try linking with -N + # /usr/sfw/bin/gobjcopy: stKPaiop: Bad value + # BFD: stKPaiop: Not enough room for program headers, try linking with -N + # /usr/sfw/bin/gobjcopy: libsaproc.debuginfo: Bad value + # BFD: stKPaiop: Not enough room for program headers, try linking with -N + # /usr/sfw/bin/gobjcopy: stKPaiop: Bad value + _JUNK_ := $(shell \ + echo >&2 "INFO: $(DEF_OBJCOPY) is not working on Solaris AMD64/X64") + OBJCOPY= + else + OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY)) + ifneq ($(ALT_OBJCOPY),) + _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)") + OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY)) + endif endif + else + OBJCOPY= endif -endif - + ifeq ($(OBJCOPY),) _JUNK_ := $(shell \ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.") + ENABLE_FULL_DEBUG_SYMBOLS=0 else _JUNK_ := $(shell \ echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.") - + # Library stripping policies for .debuginfo configs: # all_strip - strips everything from the library # min_strip - strips most stuff from the library; leaves minimum symbols @@ -121,14 +123,17 @@ endif # Oracle security policy requires "all_strip". A waiver was granted on # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE. # - DEF_STRIP_POLICY="min_strip" - ifeq ($(ALT_STRIP_POLICY),) - STRIP_POLICY=$(DEF_STRIP_POLICY) - else - STRIP_POLICY=$(ALT_STRIP_POLICY) - endif + # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled. + # + STRIP_POLICY ?= min_strip + _JUNK_ := $(shell \ echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)") + + ZIP_DEBUGINFO_FILES ?= 1 + + _JUNK_ := $(shell \ + echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)") endif endif @@ -144,8 +149,12 @@ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html # client and server subdirectories have symbolic links to ../libjsig.$(LIBRARY_SUFFIX) EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX) -ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.diz + else + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo + endif endif EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server @@ -156,10 +165,16 @@ EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX) EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX) EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX) - ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo - EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.debuginfo - EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.debuginfo + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.diz + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.diz + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.diz + else + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.debuginfo + EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.debuginfo + endif endif endif ifeq ($(ARCH_DATA_MODEL), 32) @@ -169,25 +184,42 @@ ifeq ($(ARCH_DATA_MODEL), 32) EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX) EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX) EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX) - ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.debuginfo - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.debuginfo - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.diz + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.diz + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.diz + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.diz + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.diz + else + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.debuginfo + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.debuginfo + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo + endif endif ifneq ($(BUILD_CLIENT_ONLY), true) EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX) EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX) - ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.debuginfo - EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.debuginfo + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.diz + EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.diz + else + EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.debuginfo + EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.debuginfo + endif endif endif endif EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) -ifneq ($(OBJCOPY),) - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz + else + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo + endif endif EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar diff --git a/hotspot/make/solaris/makefiles/dtrace.make b/hotspot/make/solaris/makefiles/dtrace.make index 8c02735ff1a..6b15fc2f185 100644 --- a/hotspot/make/solaris/makefiles/dtrace.make +++ b/hotspot/make/solaris/makefiles/dtrace.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -41,15 +41,19 @@ JVM_DB = libjvm_db LIBJVM_DB = libjvm_db.so LIBJVM_DB_G = libjvm$(G_SUFFIX)_db.so -LIBJVM_DB_DEBUGINFO = libjvm_db.debuginfo +LIBJVM_DB_DEBUGINFO = libjvm_db.debuginfo +LIBJVM_DB_DIZ = libjvm_db.diz LIBJVM_DB_G_DEBUGINFO = libjvm$(G_SUFFIX)_db.debuginfo +LIBJVM_DB_G_DIZ = libjvm$(G_SUFFIX)_db.diz JVM_DTRACE = jvm_dtrace LIBJVM_DTRACE = libjvm_dtrace.so LIBJVM_DTRACE_G = libjvm$(G_SUFFIX)_dtrace.so -LIBJVM_DTRACE_DEBUGINFO = libjvm_dtrace.debuginfo +LIBJVM_DTRACE_DEBUGINFO = libjvm_dtrace.debuginfo +LIBJVM_DTRACE_DIZ = libjvm_dtrace.diz LIBJVM_DTRACE_G_DEBUGINFO = libjvm$(G_SUFFIX)_dtrace.debuginfo +LIBJVM_DTRACE_G_DIZ = libjvm$(G_SUFFIX)_dtrace.diz JVMOFFS = JvmOffsets JVMOFFS.o = $(JVMOFFS).o @@ -95,10 +99,14 @@ XLIBJVM_DB_G = 64/$(LIBJVM_DB_G) XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE) XLIBJVM_DTRACE_G = 64/$(LIBJVM_DTRACE_G) -XLIBJVM_DB_DEBUGINFO = 64/$(LIBJVM_DB_DEBUGINFO) -XLIBJVM_DB_G_DEBUGINFO = 64/$(LIBJVM_DB_G_DEBUGINFO) -XLIBJVM_DTRACE_DEBUGINFO = 64/$(LIBJVM_DTRACE_DEBUGINFO) +XLIBJVM_DB_DEBUGINFO = 64/$(LIBJVM_DB_DEBUGINFO) +XLIBJVM_DB_DIZ = 64/$(LIBJVM_DB_DIZ) +XLIBJVM_DB_G_DEBUGINFO = 64/$(LIBJVM_DB_G_DEBUGINFO) +XLIBJVM_DB_G_DIZ = 64/$(LIBJVM_DB_G_DIZ) +XLIBJVM_DTRACE_DEBUGINFO = 64/$(LIBJVM_DTRACE_DEBUGINFO) +XLIBJVM_DTRACE_DIZ = 64/$(LIBJVM_DTRACE_DIZ) XLIBJVM_DTRACE_G_DEBUGINFO = 64/$(LIBJVM_DTRACE_G_DEBUGINFO) +XLIBJVM_DTRACE_G_DIZ = 64/$(LIBJVM_DTRACE_G_DIZ) $(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE) @echo Making $@ @@ -106,7 +114,7 @@ $(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE) $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc [ -f $(XLIBJVM_DB_G) ] || { ln -s $(LIBJVM_DB) $(XLIBJVM_DB_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DB_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DB_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -117,7 +125,12 @@ ifneq ($(OBJCOPY),) # implied else here is no stripping at all endif endif - [ -f $(XLIBJVM_DB_G_DEBUGINFO) ] || { ln -s $(LIBJVM_DB_DEBUGINFO) $(XLIBJVM_DB_G_DEBUGINFO); } + [ -f $(XLIBJVM_DB_G_DEBUGINFO) ] || { ln -s $(XLIBJVM_DB_DEBUGINFO) $(XLIBJVM_DB_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(XLIBJVM_DB_DIZ) $(XLIBJVM_DB_DEBUGINFO) $(XLIBJVM_DB_G_DEBUGINFO) + $(RM) $(XLIBJVM_DB_DEBUGINFO) $(XLIBJVM_DB_G_DEBUGINFO) + [ -f $(XLIBJVM_DB_G_DIZ) ] || { ln -s $(XLIBJVM_DB_DIZ) $(XLIBJVM_DB_G_DIZ); } + endif endif $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @@ -126,7 +139,7 @@ $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRAC $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor [ -f $(XLIBJVM_DTRACE_G) ] || { ln -s $(LIBJVM_DTRACE) $(XLIBJVM_DTRACE_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DTRACE_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -137,7 +150,12 @@ ifneq ($(OBJCOPY),) # implied else here is no stripping at all endif endif - [ -f $(XLIBJVM_DTRACE_G_DEBUGINFO) ] || { ln -s $(LIBJVM_DTRACE_DEBUGINFO) $(XLIBJVM_DTRACE_G_DEBUGINFO); } + [ -f $(XLIBJVM_DTRACE_G_DEBUGINFO) ] || { ln -s $(XLIBJVM_DTRACE_DEBUGINFO) $(XLIBJVM_DTRACE_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(XLIBJVM_DTRACE_DIZ) $(XLIBJVM_DTRACE_DEBUGINFO) $(XLIBJVM_DTRACE_G_DEBUGINFO) + $(RM) $(XLIBJVM_DTRACE_DEBUGINFO) $(XLIBJVM_DTRACE_G_DEBUGINFO) + [ -f $(XLIBJVM_DTRACE_G_DIZ) ] || { ln -s $(XLIBJVM_DTRACE_DIZ) $(XLIBJVM_DTRACE_G_DIZ); } + endif endif endif # ifneq ("${ISA}","${BUILDARCH}") @@ -185,7 +203,7 @@ $(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_D $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc [ -f $(LIBJVM_DB_G) ] || { ln -s $@ $(LIBJVM_DB_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DB_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -197,6 +215,11 @@ ifneq ($(OBJCOPY),) endif endif [ -f $(LIBJVM_DB_G_DEBUGINFO) ] || { ln -s $(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJVM_DB_DIZ) $(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB_G_DEBUGINFO) + $(RM) $(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB_G_DEBUGINFO) + [ -f $(LIBJVM_DB_G_DIZ) ] || { ln -s $(LIBJVM_DB_DIZ) $(LIBJVM_DB_G_DIZ); } + endif endif $(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @@ -204,7 +227,7 @@ $(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SR $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor [ -f $(LIBJVM_DTRACE_G) ] || { ln -s $@ $(LIBJVM_DTRACE_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -216,6 +239,11 @@ ifneq ($(OBJCOPY),) endif endif [ -f $(LIBJVM_DTRACE_G_DEBUGINFO) ] || { ln -s $(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJVM_DTRACE_DIZ) $(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE_G_DEBUGINFO) + $(RM) $(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE_G_DEBUGINFO) + [ -f $(LIBJVM_DTRACE_G_DIZ) ] || { ln -s $(LIBJVM_DTRACE_DIZ) $(LIBJVM_DTRACE_G_DIZ); } + endif endif $(DTRACE).d: $(DTRACE_SRCDIR)/hotspot.d $(DTRACE_SRCDIR)/hotspot_jni.d \ diff --git a/hotspot/make/solaris/makefiles/jsig.make b/hotspot/make/solaris/makefiles/jsig.make index 9002077f440..6cc40754107 100644 --- a/hotspot/make/solaris/makefiles/jsig.make +++ b/hotspot/make/solaris/makefiles/jsig.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -32,12 +32,15 @@ JSIG_G = $(JSIG)$(G_SUFFIX) LIBJSIG_G = lib$(JSIG_G).so LIBJSIG_DEBUGINFO = lib$(JSIG).debuginfo +LIBJSIG_DIZ = lib$(JSIG).diz LIBJSIG_G_DEBUGINFO = lib$(JSIG_G).debuginfo +LIBJSIG_G_DIZ = lib$(JSIG_G).diz JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG) DEST_JSIG_DEBUGINFO = $(JDK_LIBDIR)/$(LIBJSIG_DEBUGINFO) +DEST_JSIG_DIZ = $(JDK_LIBDIR)/$(LIBJSIG_DIZ) LIBJSIG_MAPFILE = $(MAKEFILES_DIR)/mapfile-vers-jsig @@ -54,7 +57,7 @@ $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ $(LFLAGS_JSIG) -o $@ $< -ldl [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -66,12 +69,19 @@ ifneq ($(OBJCOPY),) endif endif [ -f $(LIBJSIG_G_DEBUGINFO) ] || { ln -s $(LIBJSIG_DEBUGINFO) $(LIBJSIG_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJSIG_DIZ) $(LIBJSIG_DEBUGINFO) $(LIBJSIG_G_DEBUGINFO) + $(RM) $(LIBJSIG_DEBUGINFO) $(LIBJSIG_G_DEBUGINFO) + [ -f $(LIBJSIG_G_DIZ) ] || { ln -s $(LIBJSIG_DIZ) $(LIBJSIG_G_DIZ); } + endif endif install_jsig: $(LIBJSIG) @echo "Copying $(LIBJSIG) to $(DEST_JSIG)" $(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ cp -f $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) + $(QUIETLY) test -f $(LIBJSIG_DIZ) && \ + cp -f $(LIBJSIG_DIZ) $(DEST_JSIG_DIZ) $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done" .PHONY: install_jsig diff --git a/hotspot/make/solaris/makefiles/saproc.make b/hotspot/make/solaris/makefiles/saproc.make index f76e668fe67..d4c305c6839 100644 --- a/hotspot/make/solaris/makefiles/saproc.make +++ b/hotspot/make/solaris/makefiles/saproc.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, 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 @@ -33,7 +33,9 @@ SAPROC_G = $(SAPROC)$(G_SUFFIX) LIBSAPROC_G = lib$(SAPROC_G).so LIBSAPROC_DEBUGINFO = lib$(SAPROC).debuginfo +LIBSAPROC_DIZ = lib$(SAPROC).diz LIBSAPROC_G_DEBUGINFO = lib$(SAPROC_G).debuginfo +LIBSAPROC_G_DIZ = lib$(SAPROC_G).diz AGENT_DIR = $(GAMMADIR)/agent @@ -45,6 +47,7 @@ SAMAPFILE = $(SASRCDIR)/mapfile DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC) DEST_SAPROC_DEBUGINFO = $(JDK_LIBDIR)/$(LIBSAPROC_DEBUGINFO) +DEST_SAPROC_DIZ = $(JDK_LIBDIR)/$(LIBSAPROC_DIZ) # if $(AGENT_DIR) does not exist, we don't build SA @@ -105,7 +108,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE) -o $@ \ -ldl -ldemangle -lthread -lc [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); } -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -117,6 +120,11 @@ ifneq ($(OBJCOPY),) endif endif [ -f $(LIBSAPROC_G_DEBUGINFO) ] || { ln -s $(LIBSAPROC_DEBUGINFO) $(LIBSAPROC_G_DEBUGINFO); } + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBSAPROC_DIZ) $(LIBSAPROC_DEBUGINFO) $(LIBSAPROC_G_DEBUGINFO) + $(RM) $(LIBSAPROC_DEBUGINFO) $(LIBSAPROC_G_DEBUGINFO) + [ -f $(LIBSAPROC_G_DIZ) ] || { ln -s $(LIBSAPROC_DIZ) $(LIBSAPROC_G_DIZ); } + endif endif install_saproc: $(BULDLIBSAPROC) @@ -124,6 +132,8 @@ install_saproc: $(BULDLIBSAPROC) echo "Copying $(LIBSAPROC) to $(DEST_SAPROC)"; \ test -f $(LIBSAPROC_DEBUGINFO) && \ cp -f $(LIBSAPROC_DEBUGINFO) $(DEST_SAPROC_DEBUGINFO); \ + test -f $(LIBSAPROC_DIZ) && \ + cp -f $(LIBSAPROC_DIZ) $(DEST_SAPROC_DIZ); \ cp -f $(LIBSAPROC) $(DEST_SAPROC) && echo "Done"; \ fi diff --git a/hotspot/make/solaris/makefiles/sparcWorks.make b/hotspot/make/solaris/makefiles/sparcWorks.make index 8baf3c1d427..6fb4f549e17 100644 --- a/hotspot/make/solaris/makefiles/sparcWorks.make +++ b/hotspot/make/solaris/makefiles/sparcWorks.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2012, 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 @@ -484,12 +484,12 @@ endif # The -g0 setting allows the C++ frontend to inline, which is a big win. # The -xs setting disables 'lazy debug info' which puts everything in # the .so instead of requiring the '.o' files. -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) OPT_CFLAGS += -g0 -xs endif DEBUG_CFLAGS = -g FASTDEBUG_CFLAGS = -g0 -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) DEBUG_CFLAGS += -xs FASTDEBUG_CFLAGS += -xs endif diff --git a/hotspot/make/solaris/makefiles/vm.make b/hotspot/make/solaris/makefiles/vm.make index 9cb81062f7f..f91f533e3ac 100644 --- a/hotspot/make/solaris/makefiles/vm.make +++ b/hotspot/make/solaris/makefiles/vm.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2012, 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 @@ -56,7 +56,7 @@ Src_Dirs_I += $(GENERATED) INCLUDES += $(Src_Dirs_I:%=-I%) # SYMFLAG is used by {dtrace,jsig,saproc}.make. -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) # always build with debug info when we can create .debuginfo files # and disable 'lazy debug info' so the .so has everything. SYMFLAG = -g -xs @@ -152,7 +152,9 @@ LIBJVM = lib$(JVM).so LIBJVM_G = lib$(JVM)$(G_SUFFIX).so LIBJVM_DEBUGINFO = lib$(JVM).debuginfo +LIBJVM_DIZ = lib$(JVM).diz LIBJVM_G_DEBUGINFO = lib$(JVM)$(G_SUFFIX).debuginfo +LIBJVM_G_DIZ = lib$(JVM)$(G_SUFFIX).diz SPECIAL_PATHS:=adlc c1 dist gc_implementation opto shark libadt @@ -283,7 +285,7 @@ ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),) $(QUIETLY) rm -f $@.1 && ln -s $@ $@.1 $(QUIETLY) [ -f $(LIBJVM_G) ] || ln -s $@ $(LIBJVM_G) $(QUIETLY) [ -f $(LIBJVM_G).1 ] || ln -s $@.1 $(LIBJVM_G).1 -ifneq ($(OBJCOPY),) +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@ ifeq ($(STRIP_POLICY),all_strip) @@ -295,6 +297,11 @@ ifneq ($(OBJCOPY),) endif endif $(QUIETLY) [ -f $(LIBJVM_G_DEBUGINFO) ] || ln -s $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + $(ZIPEXE) -q -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO) + $(RM) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO) + [ -f $(LIBJVM_G_DIZ) ] || { ln -s $(LIBJVM_DIZ) $(LIBJVM_G_DIZ); } + endif endif endif # filter -sbfast -xsbfast @@ -302,11 +309,14 @@ endif # filter -sbfast -xsbfast DEST_SUBDIR = $(JDK_LIBDIR)/$(VM_SUBDIR) DEST_JVM = $(DEST_SUBDIR)/$(LIBJVM) DEST_JVM_DEBUGINFO = $(DEST_SUBDIR)/$(LIBJVM_DEBUGINFO) +DEST_JVM_DIZ = $(DEST_SUBDIR)/$(LIBJVM_DIZ) install_jvm: $(LIBJVM) @echo "Copying $(LIBJVM) to $(DEST_JVM)" $(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ cp -f $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) + $(QUIETLY) test -f $(LIBJVM_DIZ) && \ + cp -f $(LIBJVM_DIZ) $(DEST_JVM_DIZ) $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done" #---------------------------------------------------------------------- diff --git a/hotspot/make/windows/build.make b/hotspot/make/windows/build.make index 8ec004d4903..90d2e5e42c7 100644 --- a/hotspot/make/windows/build.make +++ b/hotspot/make/windows/build.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2012, 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 @@ -298,6 +298,10 @@ $(variantDir)\local.make: checks @ echo Platform_arch=$(Platform_arch) >> $@ @ echo Platform_arch_model=$(Platform_arch_model) >> $@ @ sh $(WorkSpace)/make/windows/get_msc_ver.sh >> $@ + @ if "$(ENABLE_FULL_DEBUG_SYMBOLS)" NEQ "" echo ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) >> $@ + @ if "$(ZIP_DEBUGINFO_FILES)" NEQ "" echo ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES) >> $@ + @ if "$(RM)" NEQ "" echo RM=$(RM) >> $@ + @ if "$(ZIPEXE)" NEQ "" echo ZIPEXE=$(ZIPEXE) >> $@ checks: checkVariant checkWorkSpace checkSA diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make index 1c9855c15dc..19baea392fe 100644 --- a/hotspot/make/windows/makefiles/compile.make +++ b/hotspot/make/windows/makefiles/compile.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -52,8 +52,10 @@ CXX=cl.exe # These are always used in all compiles CXX_FLAGS=/nologo /W3 /WX -# Let's add debug information always too. +# Let's add debug information when Full Debug Symbols is enabled +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" CXX_FLAGS=$(CXX_FLAGS) /Zi +!endif # Based on BUILDARCH we add some flags and select the default compiler name !if "$(BUILDARCH)" == "ia64" @@ -229,7 +231,10 @@ LD=link.exe LD_FLAGS= $(LD_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \ uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \ - /opt:ICF,8 /map /debug + /opt:ICF,8 +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" +LD_FLAGS= $(LD_FLAGS) /map /debug +!endif !if $(MSC_VER) >= 1600 diff --git a/hotspot/make/windows/makefiles/debug.make b/hotspot/make/windows/makefiles/debug.make index 510bb9e9d15..97b5c0609d3 100644 --- a/hotspot/make/windows/makefiles/debug.make +++ b/hotspot/make/windows/makefiles/debug.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2012, 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 @@ -61,6 +61,12 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def # separately. Use ";#2" for .dll and ";#1" for .exe: $(MT) /manifest $@.manifest /outputresource:$@;#2 !endif +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" +!if "$(ZIP_DEBUGINFO_FILES)" == "1" + $(ZIPEXE) -q $*.diz $*.map $*.pdb + $(RM) $*.map $*.pdb +!endif +!endif !include $(WorkSpace)/make/windows/makefiles/shared.make !include $(WorkSpace)/make/windows/makefiles/sa.make diff --git a/hotspot/make/windows/makefiles/defs.make b/hotspot/make/windows/makefiles/defs.make index c1be7d2c863..0e1a31ade77 100644 --- a/hotspot/make/windows/makefiles/defs.make +++ b/hotspot/make/windows/makefiles/defs.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012, 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 @@ -107,6 +107,22 @@ ifneq ($(shell $(ECHO) $(PROCESSOR_IDENTIFIER) | $(GREP) EM64T),) endif endif +# Full Debug Symbols has been enabled on Windows since JDK1.4.1 so +# there is no need for an "earlier than JDK7 check". +# Default is enabled with debug info files ZIP'ed to save space. + +ENABLE_FULL_DEBUG_SYMBOLS ?= 1 +MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) + +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ZIP_DEBUGINFO_FILES ?= 1 +else + ZIP_DEBUGINFO_FILES=0 +endif +MAKE_ARGS += ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES) +MAKE_ARGS += RM="$(RM)" +MAKE_ARGS += ZIPEXE=$(ZIPEXE) + JDK_INCLUDE_SUBDIR=win32 # Library suffix @@ -179,25 +195,49 @@ EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX) -EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb -EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map +ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.diz + else + EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb + EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map + endif +endif EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib ifeq ($(ARCH_DATA_MODEL), 32) EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.$(LIBRARY_SUFFIX) - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.diz + else + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map + endif + endif # kernel vm EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.$(LIBRARY_SUFFIX) - EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb - EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.map + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.diz + else + EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb + EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.map + endif + endif endif ifeq ($(BUILD_WIN_SA), 1) EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX) - EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb - EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map + ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.diz + else + EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb + EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map + endif + endif EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar # Must pass this down to nmake. MAKE_ARGS += BUILD_WIN_SA=1 diff --git a/hotspot/make/windows/makefiles/fastdebug.make b/hotspot/make/windows/makefiles/fastdebug.make index 3895ecd78ba..0fc2329dfd9 100644 --- a/hotspot/make/windows/makefiles/fastdebug.make +++ b/hotspot/make/windows/makefiles/fastdebug.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, 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 @@ -61,6 +61,12 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def # separately. Use ";#2" for .dll and ";#1" for .exe: $(MT) /manifest $@.manifest /outputresource:$@;#2 !endif +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" +!if "$(ZIP_DEBUGINFO_FILES)" == "1" + $(ZIPEXE) -q $*.diz $*.map $*.pdb + $(RM) $*.map $*.pdb +!endif +!endif !include $(WorkSpace)/make/windows/makefiles/shared.make !include $(WorkSpace)/make/windows/makefiles/sa.make diff --git a/hotspot/make/windows/makefiles/product.make b/hotspot/make/windows/makefiles/product.make index ebbd53832af..2b21d1ceb58 100644 --- a/hotspot/make/windows/makefiles/product.make +++ b/hotspot/make/windows/makefiles/product.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, 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 @@ -72,6 +72,12 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def # separately. Use ";#2" for .dll and ";#1" for .exe: $(MT) /manifest $@.manifest /outputresource:$@;#2 !endif +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" +!if "$(ZIP_DEBUGINFO_FILES)" == "1" + $(ZIPEXE) -q $*.diz $*.map $*.pdb + $(RM) $*.map $*.pdb +!endif +!endif !include $(WorkSpace)/make/windows/makefiles/shared.make !include $(WorkSpace)/make/windows/makefiles/sa.make diff --git a/hotspot/make/windows/makefiles/sa.make b/hotspot/make/windows/makefiles/sa.make index 2bea4da64ba..9d52c58f3d5 100644 --- a/hotspot/make/windows/makefiles/sa.make +++ b/hotspot/make/windows/makefiles/sa.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012, 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 @@ -94,13 +94,19 @@ SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 $(GX_OPTION) /Od /D "WIN32" /D "WIN SA_LD_FLAGS = bufferoverflowU.lib !endif !else -SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" +SA_CFLAGS = $(SA_CFLAGS) /ZI +!endif !endif !if "$(MT)" != "" SA_LD_FLAGS = /manifest $(SA_LD_FLAGS) !endif SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp -SA_LFLAGS = $(SA_LD_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE) +SA_LFLAGS = $(SA_LD_FLAGS) /nologo /subsystem:console /machine:$(MACHINE) +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" +SA_LFLAGS = $(SA_LFLAGS) /map /debug +!endif # Note that we do not keep sawindbj.obj around as it would then # get included in the dumpbin command in build_vm_def.sh @@ -114,14 +120,20 @@ $(SAWINDBG): $(SASRCFILE) /I"$(BootStrapDir)/include" /I"$(BootStrapDir)/include/win32" /I"$(GENERATED)" $(SA_CFLAGS) $(SASRCFILE) - /out:sawindbg.obj + /out:$*.obj << set LIB=$(SA_LIB)$(LIB) - $(LD) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS) + $(LD) /out:$@ /DLL $*.obj dbgeng.lib $(SA_LFLAGS) !if "$(MT)" != "" $(MT) /manifest $(@F).manifest /outputresource:$(@F);#2 !endif - -@rm -f sawindbg.obj +!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" +!if "$(ZIP_DEBUGINFO_FILES)" == "1" + $(ZIPEXE) -q $*.diz $*.map $*.pdb + $(RM) $*.map $*.pdb +!endif +!endif + -@rm -f $*.obj cleanall : rm -rf $(GENERATED:\=/)/saclasses From f5558edf7bc468ab6ad483a7ee354fb3fd98078c Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 29 Mar 2012 19:46:24 -0700 Subject: [PATCH 02/51] 7131629: Generalize the CMS free list code Make the FreeChunk, FreeList, TreeList, and BinaryTreeDictionary classes usable outside CMS. Reviewed-by: brutisso, johnc, jwilhelm --- .../concurrentMarkSweep/cmsPermGen.cpp | 2 +- .../concurrentMarkSweep/cmsPermGen.hpp | 4 +- .../compactibleFreeListSpace.cpp | 66 +-- .../compactibleFreeListSpace.hpp | 22 +- .../concurrentMarkSweepGeneration.cpp | 2 +- .../concurrentMarkSweepGeneration.hpp | 6 +- .../concurrentMarkSweep/freeChunk.cpp | 3 +- .../concurrentMarkSweep/vmStructs_cms.hpp | 22 +- .../binaryTreeDictionary.cpp | 504 ++++++++++-------- .../binaryTreeDictionary.hpp | 185 ++++--- .../freeBlockDictionary.cpp | 16 +- .../freeBlockDictionary.hpp | 23 +- .../freeList.cpp | 102 ++-- .../freeList.hpp | 60 +-- .../src/share/vm/memory/generationSpec.cpp | 6 +- .../src/share/vm/precompiled/precompiled.hpp | 3 - hotspot/src/share/vm/runtime/vmStructs.cpp | 2 +- 17 files changed, 579 insertions(+), 449 deletions(-) rename hotspot/src/share/vm/{gc_implementation/concurrentMarkSweep => memory}/binaryTreeDictionary.cpp (72%) rename hotspot/src/share/vm/{gc_implementation/concurrentMarkSweep => memory}/binaryTreeDictionary.hpp (60%) rename hotspot/src/share/vm/{gc_implementation/concurrentMarkSweep => memory}/freeBlockDictionary.cpp (76%) rename hotspot/src/share/vm/{gc_implementation/concurrentMarkSweep => memory}/freeBlockDictionary.hpp (80%) rename hotspot/src/share/vm/{gc_implementation/concurrentMarkSweep => memory}/freeList.cpp (84%) rename hotspot/src/share/vm/{gc_implementation/concurrentMarkSweep => memory}/freeList.hpp (86%) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp index bdcbb467c8b..1c479e594b5 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp @@ -38,7 +38,7 @@ CMSPermGen::CMSPermGen(ReservedSpace rs, size_t initial_byte_size, CardTableRS* ct, - FreeBlockDictionary::DictionaryChoice dictionaryChoice) { + FreeBlockDictionary::DictionaryChoice dictionaryChoice) { CMSPermGenGen* g = new CMSPermGenGen(rs, initial_byte_size, -1, ct); if (g == NULL) { diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp index 6d464f7170d..51519750d25 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp @@ -45,7 +45,7 @@ class CMSPermGen: public PermGen { public: CMSPermGen(ReservedSpace rs, size_t initial_byte_size, - CardTableRS* ct, FreeBlockDictionary::DictionaryChoice); + CardTableRS* ct, FreeBlockDictionary::DictionaryChoice); HeapWord* mem_allocate(size_t size); @@ -65,7 +65,7 @@ public: // regarding not using adaptive free lists for a perm gen. ConcurrentMarkSweepGeneration(rs, initial_byte_size, // MinPermHeapExapnsion level, ct, false /* use adaptive freelists */, - (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice) + (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice) {} void initialize_performance_counters(); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 4f78ce5dcf7..8263a42cb14 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -69,7 +69,7 @@ void CompactibleFreeListSpace::set_cms_values() { // Constructor CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr, bool use_adaptive_freelists, - FreeBlockDictionary::DictionaryChoice dictionaryChoice) : + FreeBlockDictionary::DictionaryChoice dictionaryChoice) : _dictionaryChoice(dictionaryChoice), _adaptive_freelists(use_adaptive_freelists), _bt(bs, mr), @@ -87,6 +87,8 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, CMSConcMarkMultiple), _collector(NULL) { + assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize, + "FreeChunk is larger than expected"); _bt.set_space(this); initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); // We have all of "mr", all of which we place in the dictionary @@ -96,13 +98,13 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, // implementation, namely, the simple binary tree (splaying // temporarily disabled). switch (dictionaryChoice) { - case FreeBlockDictionary::dictionarySplayTree: - case FreeBlockDictionary::dictionarySkipList: + case FreeBlockDictionary::dictionarySplayTree: + case FreeBlockDictionary::dictionarySkipList: default: warning("dictionaryChoice: selected option not understood; using" " default BinaryTreeDictionary implementation instead."); - case FreeBlockDictionary::dictionaryBinaryTree: - _dictionary = new BinaryTreeDictionary(mr); + case FreeBlockDictionary::dictionaryBinaryTree: + _dictionary = new BinaryTreeDictionary(mr, use_adaptive_freelists); break; } assert(_dictionary != NULL, "CMS dictionary initialization"); @@ -448,7 +450,7 @@ const { reportIndexedFreeListStatistics(); gclog_or_tty->print_cr("Layout of Indexed Freelists"); gclog_or_tty->print_cr("---------------------------"); - FreeList::print_labels_on(st, "size"); + FreeList::print_labels_on(st, "size"); for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { _indexedFreeList[i].print_on(gclog_or_tty); for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; @@ -1331,7 +1333,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) { size_t currSize = numWords + MinChunkSize; assert(currSize % MinObjAlignment == 0, "currSize should be aligned"); for (i = currSize; i < IndexSetSize; i += IndexSetStride) { - FreeList* fl = &_indexedFreeList[i]; + FreeList* fl = &_indexedFreeList[i]; if (fl->head()) { ret = getFromListGreater(fl, numWords); assert(ret == NULL || ret->isFree(), "Should be returning a free chunk"); @@ -1714,7 +1716,7 @@ CompactibleFreeListSpace::returnChunkToDictionary(FreeChunk* chunk) { _dictionary->returnChunk(chunk); #ifndef PRODUCT if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { - TreeChunk::as_TreeChunk(chunk)->list()->verify_stats(); + TreeChunk::as_TreeChunk(chunk)->list()->verify_stats(); } #endif // PRODUCT } @@ -1862,11 +1864,11 @@ FreeChunk* CompactibleFreeListSpace::bestFitSmall(size_t numWords) { the excess is >= MIN_CHUNK. */ size_t start = align_object_size(numWords + MinChunkSize); if (start < IndexSetSize) { - FreeList* it = _indexedFreeList; + FreeList* it = _indexedFreeList; size_t hint = _indexedFreeList[start].hint(); while (hint < IndexSetSize) { assert(hint % MinObjAlignment == 0, "hint should be aligned"); - FreeList *fl = &_indexedFreeList[hint]; + FreeList *fl = &_indexedFreeList[hint]; if (fl->surplus() > 0 && fl->head() != NULL) { // Found a list with surplus, reset original hint // and split out a free chunk which is returned. @@ -1885,7 +1887,7 @@ FreeChunk* CompactibleFreeListSpace::bestFitSmall(size_t numWords) { } /* Requires fl->size >= numWords + MinChunkSize */ -FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl, +FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl, size_t numWords) { FreeChunk *curr = fl->head(); size_t oldNumWords = curr->size(); @@ -2167,7 +2169,7 @@ void CompactibleFreeListSpace::beginSweepFLCensus( assert_locked(); size_t i; for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { - FreeList* fl = &_indexedFreeList[i]; + FreeList* fl = &_indexedFreeList[i]; if (PrintFLSStatistics > 1) { gclog_or_tty->print("size[%d] : ", i); } @@ -2186,7 +2188,7 @@ void CompactibleFreeListSpace::setFLSurplus() { assert_locked(); size_t i; for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { - FreeList *fl = &_indexedFreeList[i]; + FreeList *fl = &_indexedFreeList[i]; fl->set_surplus(fl->count() - (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent)); } @@ -2197,7 +2199,7 @@ void CompactibleFreeListSpace::setFLHints() { size_t i; size_t h = IndexSetSize; for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) { - FreeList *fl = &_indexedFreeList[i]; + FreeList *fl = &_indexedFreeList[i]; fl->set_hint(h); if (fl->surplus() > 0) { h = i; @@ -2209,7 +2211,7 @@ void CompactibleFreeListSpace::clearFLCensus() { assert_locked(); size_t i; for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { - FreeList *fl = &_indexedFreeList[i]; + FreeList *fl = &_indexedFreeList[i]; fl->set_prevSweep(fl->count()); fl->set_coalBirths(0); fl->set_coalDeaths(0); @@ -2236,7 +2238,7 @@ void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { if (size < SmallForDictionary) { - FreeList *fl = &_indexedFreeList[size]; + FreeList *fl = &_indexedFreeList[size]; return (fl->coalDesired() < 0) || ((int)fl->count() > fl->coalDesired()); } else { @@ -2246,14 +2248,14 @@ bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { void CompactibleFreeListSpace::smallCoalBirth(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); - FreeList *fl = &_indexedFreeList[size]; + FreeList *fl = &_indexedFreeList[size]; fl->increment_coalBirths(); fl->increment_surplus(); } void CompactibleFreeListSpace::smallCoalDeath(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); - FreeList *fl = &_indexedFreeList[size]; + FreeList *fl = &_indexedFreeList[size]; fl->increment_coalDeaths(); fl->decrement_surplus(); } @@ -2280,14 +2282,14 @@ void CompactibleFreeListSpace::coalDeath(size_t size) { void CompactibleFreeListSpace::smallSplitBirth(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); - FreeList *fl = &_indexedFreeList[size]; + FreeList *fl = &_indexedFreeList[size]; fl->increment_splitBirths(); fl->increment_surplus(); } void CompactibleFreeListSpace::smallSplitDeath(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); - FreeList *fl = &_indexedFreeList[size]; + FreeList *fl = &_indexedFreeList[size]; fl->increment_splitDeaths(); fl->decrement_surplus(); } @@ -2530,7 +2532,7 @@ void CompactibleFreeListSpace::check_free_list_consistency() const { assert(_dictionary->minSize() <= IndexSetSize, "Some sizes can't be allocated without recourse to" " linear allocation buffers"); - assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk), + assert(BinaryTreeDictionary::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk), "else MIN_TREE_CHUNK_SIZE is wrong"); assert((IndexSetStride == 2 && IndexSetStart == 4) || // 32-bit (IndexSetStride == 1 && IndexSetStart == 3), "just checking"); // 64-bit @@ -2543,15 +2545,15 @@ void CompactibleFreeListSpace::check_free_list_consistency() const { void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { assert_lock_strong(&_freelistLock); - FreeList total; + FreeList total; gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); - FreeList::print_labels_on(gclog_or_tty, "size"); + FreeList::print_labels_on(gclog_or_tty, "size"); size_t totalFree = 0; for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { - const FreeList *fl = &_indexedFreeList[i]; + const FreeList *fl = &_indexedFreeList[i]; totalFree += fl->count() * fl->size(); if (i % (40*IndexSetStride) == 0) { - FreeList::print_labels_on(gclog_or_tty, "size"); + FreeList::print_labels_on(gclog_or_tty, "size"); } fl->print_on(gclog_or_tty); total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() ); @@ -2634,7 +2636,7 @@ HeapWord* CFLS_LAB::alloc(size_t word_sz) { res = _cfls->getChunkFromDictionaryExact(word_sz); if (res == NULL) return NULL; } else { - FreeList* fl = &_indexedFreeList[word_sz]; + FreeList* fl = &_indexedFreeList[word_sz]; if (fl->count() == 0) { // Attempt to refill this local free list. get_from_global_pool(word_sz, fl); @@ -2654,7 +2656,7 @@ HeapWord* CFLS_LAB::alloc(size_t word_sz) { // Get a chunk of blocks of the right size and update related // book-keeping stats -void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) { +void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) { // Get the #blocks we want to claim size_t n_blks = (size_t)_blocks_to_claim[word_sz].average(); assert(n_blks > 0, "Error"); @@ -2736,7 +2738,7 @@ void CFLS_LAB::retire(int tid) { if (num_retire > 0) { _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]); // Reset this list. - _indexedFreeList[i] = FreeList(); + _indexedFreeList[i] = FreeList(); _indexedFreeList[i].set_size(i); } } @@ -2750,7 +2752,7 @@ void CFLS_LAB::retire(int tid) { } } -void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) { +void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) { assert(fl->count() == 0, "Precondition."); assert(word_sz < CompactibleFreeListSpace::IndexSetSize, "Precondition"); @@ -2766,12 +2768,12 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n (cur_sz < CompactibleFreeListSpace::IndexSetSize) && (CMSSplitIndexedFreeListBlocks || k <= 1); k++, cur_sz = k * word_sz) { - FreeList fl_for_cur_sz; // Empty. + FreeList fl_for_cur_sz; // Empty. fl_for_cur_sz.set_size(cur_sz); { MutexLockerEx x(_indexedFreeListParLocks[cur_sz], Mutex::_no_safepoint_check_flag); - FreeList* gfl = &_indexedFreeList[cur_sz]; + FreeList* gfl = &_indexedFreeList[cur_sz]; if (gfl->count() != 0) { // nn is the number of chunks of size cur_sz that // we'd need to split k-ways each, in order to create @@ -2848,7 +2850,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n while (n > 0) { fc = dictionary()->getChunk(MAX2(n * word_sz, _dictionary->minSize()), - FreeBlockDictionary::atLeast); + FreeBlockDictionary::atLeast); if (fc != NULL) { _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk dictionary()->dictCensusUpdate(fc->size(), diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp index c8ffba5265f..35eb1bfac3d 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @@ -25,10 +25,10 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_COMPACTIBLEFREELISTSPACE_HPP #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_COMPACTIBLEFREELISTSPACE_HPP -#include "gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp" -#include "gc_implementation/concurrentMarkSweep/freeList.hpp" #include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp" +#include "memory/binaryTreeDictionary.hpp" #include "memory/blockOffsetTable.inline.hpp" +#include "memory/freeList.hpp" #include "memory/space.hpp" // Classes in support of keeping track of promotions into a non-Contiguous @@ -129,10 +129,10 @@ class CompactibleFreeListSpace: public CompactibleSpace { // Linear allocation blocks LinearAllocBlock _smallLinearAllocBlock; - FreeBlockDictionary::DictionaryChoice _dictionaryChoice; - FreeBlockDictionary* _dictionary; // ptr to dictionary for large size blocks + FreeBlockDictionary::DictionaryChoice _dictionaryChoice; + FreeBlockDictionary* _dictionary; // ptr to dictionary for large size blocks - FreeList _indexedFreeList[IndexSetSize]; + FreeList _indexedFreeList[IndexSetSize]; // indexed array for small size blocks // allocation stategy bool _fitStrategy; // Use best fit strategy. @@ -169,7 +169,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { // If the count of "fl" is negative, it's absolute value indicates a // number of free chunks that had been previously "borrowed" from global // list of size "word_sz", and must now be decremented. - void par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl); + void par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl); // Allocation helper functions // Allocate using a strategy that takes from the indexed free lists @@ -215,7 +215,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { // and return it. The split off remainder is returned to // the free lists. The old name for getFromListGreater // was lookInListGreater. - FreeChunk* getFromListGreater(FreeList* fl, size_t numWords); + FreeChunk* getFromListGreater(FreeList* fl, size_t numWords); // Get a chunk in the indexed free list or dictionary, // by considering a larger chunk and splitting it. FreeChunk* getChunkFromGreater(size_t numWords); @@ -286,10 +286,10 @@ class CompactibleFreeListSpace: public CompactibleSpace { // Constructor... CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr, bool use_adaptive_freelists, - FreeBlockDictionary::DictionaryChoice); + FreeBlockDictionary::DictionaryChoice); // accessors bool bestFitFirst() { return _fitStrategy == FreeBlockBestFitFirst; } - FreeBlockDictionary* dictionary() const { return _dictionary; } + FreeBlockDictionary* dictionary() const { return _dictionary; } HeapWord* nearLargestChunk() const { return _nearLargestChunk; } void set_nearLargestChunk(HeapWord* v) { _nearLargestChunk = v; } @@ -622,7 +622,7 @@ class CFLS_LAB : public CHeapObj { CompactibleFreeListSpace* _cfls; // Our local free lists. - FreeList _indexedFreeList[CompactibleFreeListSpace::IndexSetSize]; + FreeList _indexedFreeList[CompactibleFreeListSpace::IndexSetSize]; // Initialized from a command-line arg. @@ -635,7 +635,7 @@ class CFLS_LAB : public CHeapObj { size_t _num_blocks [CompactibleFreeListSpace::IndexSetSize]; // Internal work method - void get_from_global_pool(size_t word_sz, FreeList* fl); + void get_from_global_pool(size_t word_sz, FreeList* fl); public: CFLS_LAB(CompactibleFreeListSpace* cfls); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index db8da2846ee..bedd9aa0971 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -188,7 +188,7 @@ class CMSParGCThreadState: public CHeapObj { ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration( ReservedSpace rs, size_t initial_byte_size, int level, CardTableRS* ct, bool use_adaptive_freelists, - FreeBlockDictionary::DictionaryChoice dictionaryChoice) : + FreeBlockDictionary::DictionaryChoice dictionaryChoice) : CardGeneration(rs, initial_byte_size, level, ct), _dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))), _debug_collection_type(Concurrent_collection_type) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp index a097c5bb3de..a84253888b0 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp @@ -25,10 +25,10 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP -#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp" #include "gc_implementation/shared/gSpaceCounters.hpp" #include "gc_implementation/shared/gcStats.hpp" #include "gc_implementation/shared/generationCounters.hpp" +#include "memory/freeBlockDictionary.hpp" #include "memory/generation.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/virtualspace.hpp" @@ -1106,7 +1106,7 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size, int level, CardTableRS* ct, bool use_adaptive_freelists, - FreeBlockDictionary::DictionaryChoice); + FreeBlockDictionary::DictionaryChoice); // Accessors CMSCollector* collector() const { return _collector; } @@ -1328,7 +1328,7 @@ class ASConcurrentMarkSweepGeneration : public ConcurrentMarkSweepGeneration { ASConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size, int level, CardTableRS* ct, bool use_adaptive_freelists, - FreeBlockDictionary::DictionaryChoice + FreeBlockDictionary::DictionaryChoice dictionaryChoice) : ConcurrentMarkSweepGeneration(rs, initial_byte_size, level, ct, use_adaptive_freelists, dictionaryChoice) {} diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp index 84702b6400f..d0693ab1da2 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp @@ -23,7 +23,8 @@ */ #include "precompiled.hpp" -#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp" +#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" +#include "memory/freeBlockDictionary.hpp" #include "utilities/copy.hpp" #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp index 34460c19d87..dc5de36685e 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp @@ -44,11 +44,11 @@ nonstatic_field(FreeChunk, _next, FreeChunk*) \ nonstatic_field(FreeChunk, _prev, FreeChunk*) \ nonstatic_field(LinearAllocBlock, _word_size, size_t) \ - nonstatic_field(FreeList, _size, size_t) \ - nonstatic_field(FreeList, _count, ssize_t) \ - nonstatic_field(BinaryTreeDictionary, _totalSize, size_t) \ - nonstatic_field(CompactibleFreeListSpace, _dictionary, FreeBlockDictionary*) \ - nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList) \ + nonstatic_field(FreeList, _size, size_t) \ + nonstatic_field(FreeList, _count, ssize_t) \ + nonstatic_field(BinaryTreeDictionary,_totalSize, size_t) \ + nonstatic_field(CompactibleFreeListSpace, _dictionary, FreeBlockDictionary*) \ + nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList) \ nonstatic_field(CompactibleFreeListSpace, _smallLinearAllocBlock, LinearAllocBlock) @@ -70,13 +70,13 @@ declare_toplevel_type(CompactibleFreeListSpace*) \ declare_toplevel_type(CMSCollector*) \ declare_toplevel_type(FreeChunk*) \ - declare_toplevel_type(BinaryTreeDictionary*) \ - declare_toplevel_type(FreeBlockDictionary*) \ - declare_toplevel_type(FreeList*) \ - declare_toplevel_type(FreeList) \ + declare_toplevel_type(BinaryTreeDictionary*) \ + declare_toplevel_type(FreeBlockDictionary*) \ + declare_toplevel_type(FreeList*) \ + declare_toplevel_type(FreeList) \ declare_toplevel_type(LinearAllocBlock) \ - declare_toplevel_type(FreeBlockDictionary) \ - declare_type(BinaryTreeDictionary, FreeBlockDictionary) + declare_toplevel_type(FreeBlockDictionary) \ + declare_type(BinaryTreeDictionary, FreeBlockDictionary) #define VM_INT_CONSTANTS_CMS(declare_constant) \ declare_constant(Generation::ConcurrentMarkSweep) \ diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp similarity index 72% rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp rename to hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index 63afa40defe..98bd273ad8e 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -23,25 +23,29 @@ */ #include "precompiled.hpp" -#include "gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp" #include "gc_implementation/shared/allocationStats.hpp" -#include "gc_implementation/shared/spaceDecorator.hpp" -#include "memory/space.inline.hpp" +#include "memory/binaryTreeDictionary.hpp" #include "runtime/globals.hpp" #include "utilities/ostream.hpp" +#ifndef SERIALGC +#include "gc_implementation/shared/spaceDecorator.hpp" +#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" +#endif // SERIALGC //////////////////////////////////////////////////////////////////////////////// // A binary tree based search structure for free blocks. // This is currently used in the Concurrent Mark&Sweep implementation. //////////////////////////////////////////////////////////////////////////////// -TreeChunk* TreeChunk::as_TreeChunk(FreeChunk* fc) { +template +TreeChunk* TreeChunk::as_TreeChunk(Chunk* fc) { // Do some assertion checking here. - return (TreeChunk*) fc; + return (TreeChunk*) fc; } -void TreeChunk::verifyTreeChunkList() const { - TreeChunk* nextTC = (TreeChunk*)next(); +template +void TreeChunk::verifyTreeChunkList() const { + TreeChunk* nextTC = (TreeChunk*)next(); if (prev() != NULL) { // interior list node shouldn'r have tree fields guarantee(embedded_list()->parent() == NULL && embedded_list()->left() == NULL && embedded_list()->right() == NULL, "should be clear"); @@ -54,10 +58,11 @@ void TreeChunk::verifyTreeChunkList() const { } -TreeList* TreeList::as_TreeList(TreeChunk* tc) { +template +TreeList* TreeList::as_TreeList(TreeChunk* tc) { // This first free chunk in the list will be the tree list. - assert(tc->size() >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk"); - TreeList* tl = tc->embedded_list(); + assert(tc->size() >= BinaryTreeDictionary::min_tree_chunk_size, "Chunk is too small for a TreeChunk"); + TreeList* tl = tc->embedded_list(); tc->set_list(tl); #ifdef ASSERT tl->set_protecting_lock(NULL); @@ -74,9 +79,10 @@ TreeList* TreeList::as_TreeList(TreeChunk* tc) { return tl; } -TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) { - TreeChunk* tc = (TreeChunk*) addr; - assert(size >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk"); +template +TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) { + TreeChunk* tc = (TreeChunk*) addr; + assert(size >= BinaryTreeDictionary::min_tree_chunk_size, "Chunk is too small for a TreeChunk"); // The space in the heap will have been mangled initially but // is not remangled when a free chunk is returned to the free list // (since it is used to maintain the chunk on the free list). @@ -89,14 +95,15 @@ TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) { tc->setSize(size); tc->linkPrev(NULL); tc->linkNext(NULL); - TreeList* tl = TreeList::as_TreeList(tc); + TreeList* tl = TreeList::as_TreeList(tc); return tl; } -TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { +template +TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { - TreeList* retTL = this; - FreeChunk* list = head(); + TreeList* retTL = this; + Chunk* list = head(); assert(!list || list != list->next(), "Chunk on list twice"); assert(tc != NULL, "Chunk being removed is NULL"); assert(parent() == NULL || this == parent()->left() || @@ -105,13 +112,13 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); - FreeChunk* prevFC = tc->prev(); - TreeChunk* nextTC = TreeChunk::as_TreeChunk(tc->next()); + Chunk* prevFC = tc->prev(); + TreeChunk* nextTC = TreeChunk::as_TreeChunk(tc->next()); assert(list != NULL, "should have at least the target chunk"); // Is this the first item on the list? if (tc == list) { - // The "getChunk..." functions for a TreeList will not return the + // The "getChunk..." functions for a TreeList will not return the // first chunk in the list unless it is the last chunk in the list // because the first chunk is also acting as the tree node. // When coalescing happens, however, the first chunk in the a tree @@ -120,8 +127,8 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { // allocated when the sweeper yields (giving up the free list lock) // to allow mutator activity. If this chunk is the first in the // list and is not the last in the list, do the work to copy the - // TreeList from the first chunk to the next chunk and update all - // the TreeList pointers in the chunks in the list. + // TreeList from the first chunk to the next chunk and update all + // the TreeList pointers in the chunks in the list. if (nextTC == NULL) { assert(prevFC == NULL, "Not last chunk in the list"); set_tail(NULL); @@ -134,11 +141,11 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { // This can be slow for a long list. Consider having // an option that does not allow the first chunk on the // list to be coalesced. - for (TreeChunk* curTC = nextTC; curTC != NULL; - curTC = TreeChunk::as_TreeChunk(curTC->next())) { + for (TreeChunk* curTC = nextTC; curTC != NULL; + curTC = TreeChunk::as_TreeChunk(curTC->next())) { curTC->set_list(retTL); } - // Fix the parent to point to the new TreeList. + // Fix the parent to point to the new TreeList. if (retTL->parent() != NULL) { if (this == retTL->parent()->left()) { retTL->parent()->setLeft(retTL); @@ -169,9 +176,9 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { prevFC->linkAfter(nextTC); } - // Below this point the embeded TreeList being used for the + // Below this point the embeded TreeList being used for the // tree node may have changed. Don't use "this" - // TreeList*. + // TreeList*. // chunk should still be a free chunk (bit set in _prev) assert(!retTL->head() || retTL->size() == retTL->head()->size(), "Wrong sized chunk in list"); @@ -181,7 +188,7 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { tc->set_list(NULL); bool prev_found = false; bool next_found = false; - for (FreeChunk* curFC = retTL->head(); + for (Chunk* curFC = retTL->head(); curFC != NULL; curFC = curFC->next()) { assert(curFC != tc, "Chunk is still in list"); if (curFC == prevFC) { @@ -207,7 +214,9 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { "list invariant"); return retTL; } -void TreeList::returnChunkAtTail(TreeChunk* chunk) { + +template +void TreeList::returnChunkAtTail(TreeChunk* chunk) { assert(chunk != NULL, "returning NULL chunk"); assert(chunk->list() == this, "list should be set for chunk"); assert(tail() != NULL, "The tree list is embedded in the first chunk"); @@ -216,12 +225,12 @@ void TreeList::returnChunkAtTail(TreeChunk* chunk) { assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); - FreeChunk* fc = tail(); + Chunk* fc = tail(); fc->linkAfter(chunk); link_tail(chunk); assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list"); - increment_count(); + FreeList::increment_count(); debug_only(increment_returnedBytes_by(chunk->size()*sizeof(HeapWord));) assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); @@ -229,9 +238,10 @@ void TreeList::returnChunkAtTail(TreeChunk* chunk) { // Add this chunk at the head of the list. "At the head of the list" // is defined to be after the chunk pointer to by head(). This is -// because the TreeList is embedded in the first TreeChunk in the -// list. See the definition of TreeChunk. -void TreeList::returnChunkAtHead(TreeChunk* chunk) { +// because the TreeList is embedded in the first TreeChunk in the +// list. See the definition of TreeChunk. +template +void TreeList::returnChunkAtHead(TreeChunk* chunk) { assert(chunk->list() == this, "list should be set for chunk"); assert(head() != NULL, "The tree list is embedded in the first chunk"); assert(chunk != NULL, "returning NULL chunk"); @@ -239,7 +249,7 @@ void TreeList::returnChunkAtHead(TreeChunk* chunk) { assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); - FreeChunk* fc = head()->next(); + Chunk* fc = head()->next(); if (fc != NULL) { chunk->linkAfter(fc); } else { @@ -248,26 +258,28 @@ void TreeList::returnChunkAtHead(TreeChunk* chunk) { } head()->linkAfter(chunk); assert(!head() || size() == head()->size(), "Wrong sized chunk in list"); - increment_count(); + FreeList::increment_count(); debug_only(increment_returnedBytes_by(chunk->size()*sizeof(HeapWord));) assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); } -TreeChunk* TreeList::head_as_TreeChunk() { - assert(head() == NULL || TreeChunk::as_TreeChunk(head())->list() == this, +template +TreeChunk* TreeList::head_as_TreeChunk() { + assert(head() == NULL || TreeChunk::as_TreeChunk(head())->list() == this, "Wrong type of chunk?"); - return TreeChunk::as_TreeChunk(head()); + return TreeChunk::as_TreeChunk(head()); } -TreeChunk* TreeList::first_available() { +template +TreeChunk* TreeList::first_available() { assert(head() != NULL, "The head of the list cannot be NULL"); - FreeChunk* fc = head()->next(); - TreeChunk* retTC; + Chunk* fc = head()->next(); + TreeChunk* retTC; if (fc == NULL) { retTC = head_as_TreeChunk(); } else { - retTC = TreeChunk::as_TreeChunk(fc); + retTC = TreeChunk::as_TreeChunk(fc); } assert(retTC->list() == this, "Wrong type of chunk."); return retTC; @@ -276,32 +288,41 @@ TreeChunk* TreeList::first_available() { // Returns the block with the largest heap address amongst // those in the list for this size; potentially slow and expensive, // use with caution! -TreeChunk* TreeList::largest_address() { +template +TreeChunk* TreeList::largest_address() { assert(head() != NULL, "The head of the list cannot be NULL"); - FreeChunk* fc = head()->next(); - TreeChunk* retTC; + Chunk* fc = head()->next(); + TreeChunk* retTC; if (fc == NULL) { retTC = head_as_TreeChunk(); } else { // walk down the list and return the one with the highest // heap address among chunks of this size. - FreeChunk* last = fc; + Chunk* last = fc; while (fc->next() != NULL) { if ((HeapWord*)last < (HeapWord*)fc) { last = fc; } fc = fc->next(); } - retTC = TreeChunk::as_TreeChunk(last); + retTC = TreeChunk::as_TreeChunk(last); } assert(retTC->list() == this, "Wrong type of chunk."); return retTC; } -BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, bool splay): - _splay(splay) +template +BinaryTreeDictionary::BinaryTreeDictionary(bool adaptive_freelists, bool splay) : + _splay(splay), _adaptive_freelists(adaptive_freelists), + _totalSize(0), _totalFreeBlocks(0), _root(0) {} + +template +BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, + bool adaptive_freelists, + bool splay): + _adaptive_freelists(adaptive_freelists), _splay(splay) { - assert(mr.byte_size() > MIN_TREE_CHUNK_SIZE, "minimum chunk size"); + assert(mr.word_size() >= BinaryTreeDictionary::min_tree_chunk_size, "minimum chunk size"); reset(mr); assert(root()->left() == NULL, "reset check failed"); @@ -312,27 +333,32 @@ BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, bool splay): assert(totalFreeBlocks() == 1, "reset check failed"); } -void BinaryTreeDictionary::inc_totalSize(size_t inc) { +template +void BinaryTreeDictionary::inc_totalSize(size_t inc) { _totalSize = _totalSize + inc; } -void BinaryTreeDictionary::dec_totalSize(size_t dec) { +template +void BinaryTreeDictionary::dec_totalSize(size_t dec) { _totalSize = _totalSize - dec; } -void BinaryTreeDictionary::reset(MemRegion mr) { - assert(mr.byte_size() > MIN_TREE_CHUNK_SIZE, "minimum chunk size"); - set_root(TreeList::as_TreeList(mr.start(), mr.word_size())); +template +void BinaryTreeDictionary::reset(MemRegion mr) { + assert(mr.word_size() >= BinaryTreeDictionary::min_tree_chunk_size, "minimum chunk size"); + set_root(TreeList::as_TreeList(mr.start(), mr.word_size())); set_totalSize(mr.word_size()); set_totalFreeBlocks(1); } -void BinaryTreeDictionary::reset(HeapWord* addr, size_t byte_size) { +template +void BinaryTreeDictionary::reset(HeapWord* addr, size_t byte_size) { MemRegion mr(addr, heap_word_size(byte_size)); reset(mr); } -void BinaryTreeDictionary::reset() { +template +void BinaryTreeDictionary::reset() { set_root(NULL); set_totalSize(0); set_totalFreeBlocks(0); @@ -346,12 +372,13 @@ void BinaryTreeDictionary::reset() { // (zig, zig-zig or zig-zag). A chunk of the appropriate size is then returned // if available, and if it's the last chunk, the node is deleted. A deteleted // node is replaced in place by its tree successor. -TreeChunk* -BinaryTreeDictionary::getChunkFromTree(size_t size, Dither dither, bool splay) +template +TreeChunk* +BinaryTreeDictionary::getChunkFromTree(size_t size, enum FreeBlockDictionary::Dither dither, bool splay) { - TreeList *curTL, *prevTL; - TreeChunk* retTC = NULL; - assert(size >= MIN_TREE_CHUNK_SIZE, "minimum chunk size"); + TreeList *curTL, *prevTL; + TreeChunk* retTC = NULL; + assert(size >= BinaryTreeDictionary::min_tree_chunk_size, "minimum chunk size"); if (FLSVerifyDictionary) { verifyTree(); } @@ -370,6 +397,9 @@ BinaryTreeDictionary::getChunkFromTree(size_t size, Dither dither, bool splay) } } if (curTL == NULL) { // couldn't find exact match + + if (dither == FreeBlockDictionary::exactly) return NULL; + // try and find the next larger size by walking back up the search path for (curTL = prevTL; curTL != NULL;) { if (curTL->size() >= size) break; @@ -380,14 +410,14 @@ BinaryTreeDictionary::getChunkFromTree(size_t size, Dither dither, bool splay) } if (curTL != NULL) { assert(curTL->size() >= size, "size inconsistency"); - if (UseCMSAdaptiveFreeLists) { + if (adaptive_freelists()) { // A candidate chunk has been found. If it is already under // populated, get a chunk associated with the hint for this // chunk. if (curTL->surplus() <= 0) { /* Use the hint to find a size with a surplus, and reset the hint. */ - TreeList* hintTL = curTL; + TreeList* hintTL = curTL; while (hintTL->hint() != 0) { assert(hintTL->hint() == 0 || hintTL->hint() > hintTL->size(), "hint points in the wrong direction"); @@ -435,8 +465,9 @@ BinaryTreeDictionary::getChunkFromTree(size_t size, Dither dither, bool splay) return retTC; } -TreeList* BinaryTreeDictionary::findList(size_t size) const { - TreeList* curTL; +template +TreeList* BinaryTreeDictionary::findList(size_t size) const { + TreeList* curTL; for (curTL = root(); curTL != NULL;) { if (curTL->size() == size) { // exact match break; @@ -453,9 +484,10 @@ TreeList* BinaryTreeDictionary::findList(size_t size) const { } -bool BinaryTreeDictionary::verifyChunkInFreeLists(FreeChunk* tc) const { +template +bool BinaryTreeDictionary::verifyChunkInFreeLists(Chunk* tc) const { size_t size = tc->size(); - TreeList* tl = findList(size); + TreeList* tl = findList(size); if (tl == NULL) { return false; } else { @@ -463,8 +495,9 @@ bool BinaryTreeDictionary::verifyChunkInFreeLists(FreeChunk* tc) const { } } -FreeChunk* BinaryTreeDictionary::findLargestDict() const { - TreeList *curTL = root(); +template +Chunk* BinaryTreeDictionary::findLargestDict() const { + TreeList *curTL = root(); if (curTL != NULL) { while(curTL->right() != NULL) curTL = curTL->right(); return curTL->largest_address(); @@ -477,14 +510,15 @@ FreeChunk* BinaryTreeDictionary::findLargestDict() const { // chunk in a list on a tree node, just unlink it. // If it is the last chunk in the list (the next link is NULL), // remove the node and repair the tree. -TreeChunk* -BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { +template +TreeChunk* +BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { assert(tc != NULL, "Should not call with a NULL chunk"); assert(tc->isFree(), "Header is not marked correctly"); - TreeList *newTL, *parentTL; - TreeChunk* retTC; - TreeList* tl = tc->list(); + TreeList *newTL, *parentTL; + TreeChunk* retTC; + TreeList* tl = tc->list(); debug_only( bool removing_only_chunk = false; if (tl == _root) { @@ -504,8 +538,8 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { retTC = tc; // Removing this chunk can have the side effect of changing the node - // (TreeList*) in the tree. If the node is the root, update it. - TreeList* replacementTL = tl->removeChunkReplaceIfNeeded(tc); + // (TreeList*) in the tree. If the node is the root, update it. + TreeList* replacementTL = tl->removeChunkReplaceIfNeeded(tc); assert(tc->isFree(), "Chunk should still be free"); assert(replacementTL->parent() == NULL || replacementTL == replacementTL->parent()->left() || @@ -519,8 +553,8 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { if (tl != replacementTL) { assert(replacementTL->head() != NULL, "If the tree list was replaced, it should not be a NULL list"); - TreeList* rhl = replacementTL->head_as_TreeChunk()->list(); - TreeList* rtl = TreeChunk::as_TreeChunk(replacementTL->tail())->list(); + TreeList* rhl = replacementTL->head_as_TreeChunk()->list(); + TreeList* rtl = TreeChunk::as_TreeChunk(replacementTL->tail())->list(); assert(rhl == replacementTL, "Broken head"); assert(rtl == replacementTL, "Broken tail"); assert(replacementTL->size() == tc->size(), "Broken size"); @@ -610,20 +644,21 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { verifyTree(); } assert(!removing_only_chunk || _root == NULL, "root should be NULL"); - return TreeChunk::as_TreeChunk(retTC); + return TreeChunk::as_TreeChunk(retTC); } // Remove the leftmost node (lm) in the tree and return it. // If lm has a right child, link it to the left node of // the parent of lm. -TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* tl) { +template +TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* tl) { assert(tl != NULL && tl->parent() != NULL, "really need a proper sub-tree"); // locate the subtree minimum by walking down left branches - TreeList* curTL = tl; + TreeList* curTL = tl; for (; curTL->left() != NULL; curTL = curTL->left()); // obviously curTL now has at most one child, a right child if (curTL != root()) { // Should this test just be removed? - TreeList* parentTL = curTL->parent(); + TreeList* parentTL = curTL->parent(); if (parentTL->left() == curTL) { // curTL is a left child parentTL->setLeft(curTL->right()); } else { @@ -658,7 +693,8 @@ TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* tl) { // while getting a reasonably efficient search tree (we think). // [Measurements will be needed to (in)validate this expectation.] -void BinaryTreeDictionary::semiSplayStep(TreeList* tc) { +template +void BinaryTreeDictionary::semiSplayStep(TreeList* tc) { // apply a semi-splay step at the given node: // . if root, norting needs to be done // . if child of root, splay once @@ -668,16 +704,15 @@ void BinaryTreeDictionary::semiSplayStep(TreeList* tc) { "tree operations may be inefficient ***"); } -void BinaryTreeDictionary::insertChunkInTree(FreeChunk* fc) { - TreeList *curTL, *prevTL; +template +void BinaryTreeDictionary::insertChunkInTree(Chunk* fc) { + TreeList *curTL, *prevTL; size_t size = fc->size(); - assert(size >= MIN_TREE_CHUNK_SIZE, "too small to be a TreeList"); + assert(size >= BinaryTreeDictionary::min_tree_chunk_size, "too small to be a TreeList"); if (FLSVerifyDictionary) { verifyTree(); } - // XXX: do i need to clear the FreeChunk fields, let me do it just in case - // Revisit this later fc->clearNext(); fc->linkPrev(NULL); @@ -694,9 +729,9 @@ void BinaryTreeDictionary::insertChunkInTree(FreeChunk* fc) { curTL = curTL->right(); } } - TreeChunk* tc = TreeChunk::as_TreeChunk(fc); + TreeChunk* tc = TreeChunk::as_TreeChunk(fc); // This chunk is being returned to the binary tree. Its embedded - // TreeList should be unused at this point. + // TreeList should be unused at this point. tc->initialize(); if (curTL != NULL) { // exact match tc->set_list(curTL); @@ -704,8 +739,8 @@ void BinaryTreeDictionary::insertChunkInTree(FreeChunk* fc) { } else { // need a new node in tree tc->clearNext(); tc->linkPrev(NULL); - TreeList* newTL = TreeList::as_TreeList(tc); - assert(((TreeChunk*)tc)->list() == newTL, + TreeList* newTL = TreeList::as_TreeList(tc); + assert(((TreeChunk*)tc)->list() == newTL, "List was not initialized correctly"); if (prevTL == NULL) { // we are the only tree node assert(root() == NULL, "control point invariant"); @@ -733,27 +768,30 @@ void BinaryTreeDictionary::insertChunkInTree(FreeChunk* fc) { } } -size_t BinaryTreeDictionary::maxChunkSize() const { - verify_par_locked(); - TreeList* tc = root(); +template +size_t BinaryTreeDictionary::maxChunkSize() const { + FreeBlockDictionary::verify_par_locked(); + TreeList* tc = root(); if (tc == NULL) return 0; for (; tc->right() != NULL; tc = tc->right()); return tc->size(); } -size_t BinaryTreeDictionary::totalListLength(TreeList* tl) const { +template +size_t BinaryTreeDictionary::totalListLength(TreeList* tl) const { size_t res; res = tl->count(); #ifdef ASSERT size_t cnt; - FreeChunk* tc = tl->head(); + Chunk* tc = tl->head(); for (cnt = 0; tc != NULL; tc = tc->next(), cnt++); assert(res == cnt, "The count is not being maintained correctly"); #endif return res; } -size_t BinaryTreeDictionary::totalSizeInTree(TreeList* tl) const { +template +size_t BinaryTreeDictionary::totalSizeInTree(TreeList* tl) const { if (tl == NULL) return 0; return (tl->size() * totalListLength(tl)) + @@ -761,7 +799,8 @@ size_t BinaryTreeDictionary::totalSizeInTree(TreeList* tl) const { totalSizeInTree(tl->right()); } -double BinaryTreeDictionary::sum_of_squared_block_sizes(TreeList* const tl) const { +template +double BinaryTreeDictionary::sum_of_squared_block_sizes(TreeList* const tl) const { if (tl == NULL) { return 0.0; } @@ -772,7 +811,8 @@ double BinaryTreeDictionary::sum_of_squared_block_sizes(TreeList* const tl) cons return curr; } -size_t BinaryTreeDictionary::totalFreeBlocksInTree(TreeList* tl) const { +template +size_t BinaryTreeDictionary::totalFreeBlocksInTree(TreeList* tl) const { if (tl == NULL) return 0; return totalListLength(tl) + @@ -780,24 +820,28 @@ size_t BinaryTreeDictionary::totalFreeBlocksInTree(TreeList* tl) const { totalFreeBlocksInTree(tl->right()); } -size_t BinaryTreeDictionary::numFreeBlocks() const { +template +size_t BinaryTreeDictionary::numFreeBlocks() const { assert(totalFreeBlocksInTree(root()) == totalFreeBlocks(), "_totalFreeBlocks inconsistency"); return totalFreeBlocks(); } -size_t BinaryTreeDictionary::treeHeightHelper(TreeList* tl) const { +template +size_t BinaryTreeDictionary::treeHeightHelper(TreeList* tl) const { if (tl == NULL) return 0; return 1 + MAX2(treeHeightHelper(tl->left()), treeHeightHelper(tl->right())); } -size_t BinaryTreeDictionary::treeHeight() const { +template +size_t BinaryTreeDictionary::treeHeight() const { return treeHeightHelper(root()); } -size_t BinaryTreeDictionary::totalNodesHelper(TreeList* tl) const { +template +size_t BinaryTreeDictionary::totalNodesHelper(TreeList* tl) const { if (tl == NULL) { return 0; } @@ -805,12 +849,14 @@ size_t BinaryTreeDictionary::totalNodesHelper(TreeList* tl) const { totalNodesHelper(tl->right()); } -size_t BinaryTreeDictionary::totalNodesInTree(TreeList* tl) const { +template +size_t BinaryTreeDictionary::totalNodesInTree(TreeList* tl) const { return totalNodesHelper(root()); } -void BinaryTreeDictionary::dictCensusUpdate(size_t size, bool split, bool birth){ - TreeList* nd = findList(size); +template +void BinaryTreeDictionary::dictCensusUpdate(size_t size, bool split, bool birth){ + TreeList* nd = findList(size); if (nd) { if (split) { if (birth) { @@ -837,10 +883,11 @@ void BinaryTreeDictionary::dictCensusUpdate(size_t size, bool split, bool birth) // for the LinAB is not in the dictionary. } -bool BinaryTreeDictionary::coalDictOverPopulated(size_t size) { +template +bool BinaryTreeDictionary::coalDictOverPopulated(size_t size) { if (FLSAlwaysCoalesceLarge) return true; - TreeList* list_of_size = findList(size); + TreeList* list_of_size = findList(size); // None of requested size implies overpopulated. return list_of_size == NULL || list_of_size->coalDesired() <= 0 || list_of_size->count() > list_of_size->coalDesired(); @@ -852,16 +899,18 @@ bool BinaryTreeDictionary::coalDictOverPopulated(size_t size) { // do_tree() walks the nodes in the binary tree applying do_list() // to each list at each node. +template class TreeCensusClosure : public StackObj { protected: - virtual void do_list(FreeList* fl) = 0; + virtual void do_list(FreeList* fl) = 0; public: - virtual void do_tree(TreeList* tl) = 0; + virtual void do_tree(TreeList* tl) = 0; }; -class AscendTreeCensusClosure : public TreeCensusClosure { +template +class AscendTreeCensusClosure : public TreeCensusClosure { public: - void do_tree(TreeList* tl) { + void do_tree(TreeList* tl) { if (tl != NULL) { do_tree(tl->left()); do_list(tl); @@ -870,9 +919,10 @@ class AscendTreeCensusClosure : public TreeCensusClosure { } }; -class DescendTreeCensusClosure : public TreeCensusClosure { +template +class DescendTreeCensusClosure : public TreeCensusClosure { public: - void do_tree(TreeList* tl) { + void do_tree(TreeList* tl) { if (tl != NULL) { do_tree(tl->right()); do_list(tl); @@ -883,7 +933,8 @@ class DescendTreeCensusClosure : public TreeCensusClosure { // For each list in the tree, calculate the desired, desired // coalesce, count before sweep, and surplus before sweep. -class BeginSweepClosure : public AscendTreeCensusClosure { +template +class BeginSweepClosure : public AscendTreeCensusClosure { double _percentage; float _inter_sweep_current; float _inter_sweep_estimate; @@ -898,7 +949,7 @@ class BeginSweepClosure : public AscendTreeCensusClosure { _inter_sweep_estimate(inter_sweep_estimate), _intra_sweep_estimate(intra_sweep_estimate) { } - void do_list(FreeList* fl) { + void do_list(FreeList* fl) { double coalSurplusPercent = _percentage; fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate); fl->set_coalDesired((ssize_t)((double)fl->desired() * coalSurplusPercent)); @@ -911,17 +962,19 @@ class BeginSweepClosure : public AscendTreeCensusClosure { // Similar to TreeCensusClosure but searches the // tree and returns promptly when found. +template class TreeSearchClosure : public StackObj { protected: - virtual bool do_list(FreeList* fl) = 0; + virtual bool do_list(FreeList* fl) = 0; public: - virtual bool do_tree(TreeList* tl) = 0; + virtual bool do_tree(TreeList* tl) = 0; }; #if 0 // Don't need this yet but here for symmetry. +template class AscendTreeSearchClosure : public TreeSearchClosure { public: - bool do_tree(TreeList* tl) { + bool do_tree(TreeList* tl) { if (tl != NULL) { if (do_tree(tl->left())) return true; if (do_list(tl)) return true; @@ -932,9 +985,10 @@ class AscendTreeSearchClosure : public TreeSearchClosure { }; #endif -class DescendTreeSearchClosure : public TreeSearchClosure { +template +class DescendTreeSearchClosure : public TreeSearchClosure { public: - bool do_tree(TreeList* tl) { + bool do_tree(TreeList* tl) { if (tl != NULL) { if (do_tree(tl->right())) return true; if (do_list(tl)) return true; @@ -946,14 +1000,15 @@ class DescendTreeSearchClosure : public TreeSearchClosure { // Searches the tree for a chunk that ends at the // specified address. -class EndTreeSearchClosure : public DescendTreeSearchClosure { +template +class EndTreeSearchClosure : public DescendTreeSearchClosure { HeapWord* _target; - FreeChunk* _found; + Chunk* _found; public: EndTreeSearchClosure(HeapWord* target) : _target(target), _found(NULL) {} - bool do_list(FreeList* fl) { - FreeChunk* item = fl->head(); + bool do_list(FreeList* fl) { + Chunk* item = fl->head(); while (item != NULL) { if (item->end() == _target) { _found = item; @@ -963,20 +1018,22 @@ class EndTreeSearchClosure : public DescendTreeSearchClosure { } return false; } - FreeChunk* found() { return _found; } + Chunk* found() { return _found; } }; -FreeChunk* BinaryTreeDictionary::find_chunk_ends_at(HeapWord* target) const { - EndTreeSearchClosure etsc(target); +template +Chunk* BinaryTreeDictionary::find_chunk_ends_at(HeapWord* target) const { + EndTreeSearchClosure etsc(target); bool found_target = etsc.do_tree(root()); assert(found_target || etsc.found() == NULL, "Consistency check"); assert(!found_target || etsc.found() != NULL, "Consistency check"); return etsc.found(); } -void BinaryTreeDictionary::beginSweepDictCensus(double coalSurplusPercent, +template +void BinaryTreeDictionary::beginSweepDictCensus(double coalSurplusPercent, float inter_sweep_current, float inter_sweep_estimate, float intra_sweep_estimate) { - BeginSweepClosure bsc(coalSurplusPercent, inter_sweep_current, + BeginSweepClosure bsc(coalSurplusPercent, inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); bsc.do_tree(root()); @@ -984,76 +1041,85 @@ void BinaryTreeDictionary::beginSweepDictCensus(double coalSurplusPercent, // Closures and methods for calculating total bytes returned to the // free lists in the tree. -NOT_PRODUCT( - class InitializeDictReturnedBytesClosure : public AscendTreeCensusClosure { +#ifndef PRODUCT +template +class InitializeDictReturnedBytesClosure : public AscendTreeCensusClosure { public: - void do_list(FreeList* fl) { - fl->set_returnedBytes(0); - } - }; - - void BinaryTreeDictionary::initializeDictReturnedBytes() { - InitializeDictReturnedBytesClosure idrb; - idrb.do_tree(root()); + void do_list(FreeList* fl) { + fl->set_returnedBytes(0); } +}; - class ReturnedBytesClosure : public AscendTreeCensusClosure { - size_t _dictReturnedBytes; - public: - ReturnedBytesClosure() { _dictReturnedBytes = 0; } - void do_list(FreeList* fl) { - _dictReturnedBytes += fl->returnedBytes(); - } - size_t dictReturnedBytes() { return _dictReturnedBytes; } - }; +template +void BinaryTreeDictionary::initializeDictReturnedBytes() { + InitializeDictReturnedBytesClosure idrb; + idrb.do_tree(root()); +} - size_t BinaryTreeDictionary::sumDictReturnedBytes() { - ReturnedBytesClosure rbc; - rbc.do_tree(root()); - - return rbc.dictReturnedBytes(); +template +class ReturnedBytesClosure : public AscendTreeCensusClosure { + size_t _dictReturnedBytes; + public: + ReturnedBytesClosure() { _dictReturnedBytes = 0; } + void do_list(FreeList* fl) { + _dictReturnedBytes += fl->returnedBytes(); } + size_t dictReturnedBytes() { return _dictReturnedBytes; } +}; - // Count the number of entries in the tree. - class treeCountClosure : public DescendTreeCensusClosure { - public: - uint count; - treeCountClosure(uint c) { count = c; } - void do_list(FreeList* fl) { - count++; - } - }; +template +size_t BinaryTreeDictionary::sumDictReturnedBytes() { + ReturnedBytesClosure rbc; + rbc.do_tree(root()); - size_t BinaryTreeDictionary::totalCount() { - treeCountClosure ctc(0); - ctc.do_tree(root()); - return ctc.count; + return rbc.dictReturnedBytes(); +} + +// Count the number of entries in the tree. +template +class treeCountClosure : public DescendTreeCensusClosure { + public: + uint count; + treeCountClosure(uint c) { count = c; } + void do_list(FreeList* fl) { + count++; } -) +}; + +template +size_t BinaryTreeDictionary::totalCount() { + treeCountClosure ctc(0); + ctc.do_tree(root()); + return ctc.count; +} +#endif // PRODUCT // Calculate surpluses for the lists in the tree. -class setTreeSurplusClosure : public AscendTreeCensusClosure { +template +class setTreeSurplusClosure : public AscendTreeCensusClosure { double percentage; public: setTreeSurplusClosure(double v) { percentage = v; } - void do_list(FreeList* fl) { + void do_list(FreeList* fl) { double splitSurplusPercent = percentage; fl->set_surplus(fl->count() - (ssize_t)((double)fl->desired() * splitSurplusPercent)); } }; -void BinaryTreeDictionary::setTreeSurplus(double splitSurplusPercent) { - setTreeSurplusClosure sts(splitSurplusPercent); +template +void BinaryTreeDictionary::setTreeSurplus(double splitSurplusPercent) { + setTreeSurplusClosure sts(splitSurplusPercent); sts.do_tree(root()); } // Set hints for the lists in the tree. -class setTreeHintsClosure : public DescendTreeCensusClosure { +template +class setTreeHintsClosure : public DescendTreeCensusClosure { size_t hint; public: setTreeHintsClosure(size_t v) { hint = v; } - void do_list(FreeList* fl) { + void do_list(FreeList* fl) { fl->set_hint(hint); assert(fl->hint() == 0 || fl->hint() > fl->size(), "Current hint is inconsistent"); @@ -1063,14 +1129,16 @@ class setTreeHintsClosure : public DescendTreeCensusClosure { } }; -void BinaryTreeDictionary::setTreeHints(void) { - setTreeHintsClosure sth(0); +template +void BinaryTreeDictionary::setTreeHints(void) { + setTreeHintsClosure sth(0); sth.do_tree(root()); } // Save count before previous sweep and splits and coalesces. -class clearTreeCensusClosure : public AscendTreeCensusClosure { - void do_list(FreeList* fl) { +template +class clearTreeCensusClosure : public AscendTreeCensusClosure { + void do_list(FreeList* fl) { fl->set_prevSweep(fl->count()); fl->set_coalBirths(0); fl->set_coalDeaths(0); @@ -1079,13 +1147,15 @@ class clearTreeCensusClosure : public AscendTreeCensusClosure { } }; -void BinaryTreeDictionary::clearTreeCensus(void) { - clearTreeCensusClosure ctc; +template +void BinaryTreeDictionary::clearTreeCensus(void) { + clearTreeCensusClosure ctc; ctc.do_tree(root()); } // Do reporting and post sweep clean up. -void BinaryTreeDictionary::endSweepDictCensus(double splitSurplusPercent) { +template +void BinaryTreeDictionary::endSweepDictCensus(double splitSurplusPercent) { // Does walking the tree 3 times hurt? setTreeSurplus(splitSurplusPercent); setTreeHints(); @@ -1096,8 +1166,9 @@ void BinaryTreeDictionary::endSweepDictCensus(double splitSurplusPercent) { } // Print summary statistics -void BinaryTreeDictionary::reportStatistics() const { - verify_par_locked(); +template +void BinaryTreeDictionary::reportStatistics() const { + FreeBlockDictionary::verify_par_locked(); gclog_or_tty->print("Statistics for BinaryTreeDictionary:\n" "------------------------------------\n"); size_t totalSize = totalChunkSize(debug_only(NULL)); @@ -1114,21 +1185,22 @@ void BinaryTreeDictionary::reportStatistics() const { // Print census information - counts, births, deaths, etc. // for each list in the tree. Also print some summary // information. -class PrintTreeCensusClosure : public AscendTreeCensusClosure { +template +class PrintTreeCensusClosure : public AscendTreeCensusClosure { int _print_line; size_t _totalFree; - FreeList _total; + FreeList _total; public: PrintTreeCensusClosure() { _print_line = 0; _totalFree = 0; } - FreeList* total() { return &_total; } + FreeList* total() { return &_total; } size_t totalFree() { return _totalFree; } - void do_list(FreeList* fl) { + void do_list(FreeList* fl) { if (++_print_line >= 40) { - FreeList::print_labels_on(gclog_or_tty, "size"); + FreeList::print_labels_on(gclog_or_tty, "size"); _print_line = 0; } fl->print_on(gclog_or_tty); @@ -1146,15 +1218,16 @@ class PrintTreeCensusClosure : public AscendTreeCensusClosure { } }; -void BinaryTreeDictionary::printDictCensus(void) const { +template +void BinaryTreeDictionary::printDictCensus(void) const { gclog_or_tty->print("\nBinaryTree\n"); - FreeList::print_labels_on(gclog_or_tty, "size"); - PrintTreeCensusClosure ptc; + FreeList::print_labels_on(gclog_or_tty, "size"); + PrintTreeCensusClosure ptc; ptc.do_tree(root()); - FreeList* total = ptc.total(); - FreeList::print_labels_on(gclog_or_tty, " "); + FreeList* total = ptc.total(); + FreeList::print_labels_on(gclog_or_tty, " "); total->print_on(gclog_or_tty, "TOTAL\t"); gclog_or_tty->print( "totalFree(words): " SIZE_FORMAT_W(16) @@ -1167,7 +1240,8 @@ void BinaryTreeDictionary::printDictCensus(void) const { /(total->desired() != 0 ? (double)total->desired() : 1.0)); } -class PrintFreeListsClosure : public AscendTreeCensusClosure { +template +class PrintFreeListsClosure : public AscendTreeCensusClosure { outputStream* _st; int _print_line; @@ -1176,14 +1250,14 @@ class PrintFreeListsClosure : public AscendTreeCensusClosure { _st = st; _print_line = 0; } - void do_list(FreeList* fl) { + void do_list(FreeList* fl) { if (++_print_line >= 40) { - FreeList::print_labels_on(_st, "size"); + FreeList::print_labels_on(_st, "size"); _print_line = 0; } fl->print_on(gclog_or_tty); size_t sz = fl->size(); - for (FreeChunk* fc = fl->head(); fc != NULL; + for (Chunk* fc = fl->head(); fc != NULL; fc = fc->next()) { _st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", fc, (HeapWord*)fc + sz, @@ -1192,10 +1266,11 @@ class PrintFreeListsClosure : public AscendTreeCensusClosure { } }; -void BinaryTreeDictionary::print_free_lists(outputStream* st) const { +template +void BinaryTreeDictionary::print_free_lists(outputStream* st) const { - FreeList::print_labels_on(st, "size"); - PrintFreeListsClosure pflc(st); + FreeList::print_labels_on(st, "size"); + PrintFreeListsClosure pflc(st); pflc.do_tree(root()); } @@ -1203,16 +1278,18 @@ void BinaryTreeDictionary::print_free_lists(outputStream* st) const { // . _root has no parent // . parent and child point to each other // . each node's key correctly related to that of its child(ren) -void BinaryTreeDictionary::verifyTree() const { +template +void BinaryTreeDictionary::verifyTree() const { guarantee(root() == NULL || totalFreeBlocks() == 0 || totalSize() != 0, "_totalSize should't be 0?"); guarantee(root() == NULL || root()->parent() == NULL, "_root shouldn't have parent"); verifyTreeHelper(root()); } -size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) { +template +size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) { size_t ct = 0; - for (FreeChunk* curFC = tl->head(); curFC != NULL; curFC = curFC->next()) { + for (Chunk* curFC = tl->head(); curFC != NULL; curFC = curFC->next()) { ct++; assert(curFC->prev() == NULL || curFC->prev()->isFree(), "Chunk should be free"); @@ -1223,7 +1300,8 @@ size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) { // Note: this helper is recursive rather than iterative, so use with // caution on very deep trees; and watch out for stack overflow errors; // In general, to be used only for debugging. -void BinaryTreeDictionary::verifyTreeHelper(TreeList* tl) const { +template +void BinaryTreeDictionary::verifyTreeHelper(TreeList* tl) const { if (tl == NULL) return; guarantee(tl->size() != 0, "A list must has a size"); @@ -1251,7 +1329,15 @@ void BinaryTreeDictionary::verifyTreeHelper(TreeList* tl) const { verifyTreeHelper(tl->right()); } -void BinaryTreeDictionary::verify() const { +template +void BinaryTreeDictionary::verify() const { verifyTree(); guarantee(totalSize() == totalSizeInTree(root()), "Total Size inconsistency"); } + +#ifndef SERIALGC +// Explicitly instantiate these types for FreeChunk. +template class BinaryTreeDictionary; +template class TreeChunk; +template class TreeList; +#endif // SERIALGC diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp similarity index 60% rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp rename to hotspot/src/share/vm/memory/binaryTreeDictionary.hpp index f06f8d38548..8de138f085d 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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,51 +22,65 @@ * */ -#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_BINARYTREEDICTIONARY_HPP -#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_BINARYTREEDICTIONARY_HPP +#ifndef SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP +#define SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP -#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp" -#include "gc_implementation/concurrentMarkSweep/freeList.hpp" +#include "memory/freeBlockDictionary.hpp" +#include "memory/freeList.hpp" /* * A binary tree based search structure for free blocks. - * This is currently used in the Concurrent Mark&Sweep implementation. + * This is currently used in the Concurrent Mark&Sweep implementation, but + * will be used for free block management for metadata. */ // A TreeList is a FreeList which can be used to maintain a // binary tree of free lists. -class TreeChunk; -class BinaryTreeDictionary; -class AscendTreeCensusClosure; -class DescendTreeCensusClosure; -class DescendTreeSearchClosure; +template class TreeChunk; +template class BinaryTreeDictionary; +template class AscendTreeCensusClosure; +template class DescendTreeCensusClosure; +template class DescendTreeSearchClosure; -class TreeList: public FreeList { - friend class TreeChunk; - friend class BinaryTreeDictionary; - friend class AscendTreeCensusClosure; - friend class DescendTreeCensusClosure; - friend class DescendTreeSearchClosure; +template +class TreeList: public FreeList { + friend class TreeChunk; + friend class BinaryTreeDictionary; + friend class AscendTreeCensusClosure; + friend class DescendTreeCensusClosure; + friend class DescendTreeSearchClosure; + + TreeList* _parent; + TreeList* _left; + TreeList* _right; protected: - TreeList* parent() const { return _parent; } - TreeList* left() const { return _left; } - TreeList* right() const { return _right; } + TreeList* parent() const { return _parent; } + TreeList* left() const { return _left; } + TreeList* right() const { return _right; } + + // Wrapper on call to base class, to get the template to compile. + Chunk* head() const { return FreeList::head(); } + Chunk* tail() const { return FreeList::tail(); } + void set_head(Chunk* head) { FreeList::set_head(head); } + void set_tail(Chunk* tail) { FreeList::set_tail(tail); } + + size_t size() const { return FreeList::size(); } // Accessors for links in tree. - void setLeft(TreeList* tl) { + void setLeft(TreeList* tl) { _left = tl; if (tl != NULL) tl->setParent(this); } - void setRight(TreeList* tl) { + void setRight(TreeList* tl) { _right = tl; if (tl != NULL) tl->setParent(this); } - void setParent(TreeList* tl) { _parent = tl; } + void setParent(TreeList* tl) { _parent = tl; } void clearLeft() { _left = NULL; } void clearRight() { _right = NULL; } @@ -75,20 +89,20 @@ class TreeList: public FreeList { // For constructing a TreeList from a Tree chunk or // address and size. - static TreeList* as_TreeList(TreeChunk* tc); - static TreeList* as_TreeList(HeapWord* addr, size_t size); + static TreeList* as_TreeList(TreeChunk* tc); + static TreeList* as_TreeList(HeapWord* addr, size_t size); // Returns the head of the free list as a pointer to a TreeChunk. - TreeChunk* head_as_TreeChunk(); + TreeChunk* head_as_TreeChunk(); // Returns the first available chunk in the free list as a pointer // to a TreeChunk. - TreeChunk* first_available(); + TreeChunk* first_available(); // Returns the block with the largest heap address amongst // those in the list for this size; potentially slow and expensive, // use with caution! - TreeChunk* largest_address(); + TreeChunk* largest_address(); // removeChunkReplaceIfNeeded() removes the given "tc" from the TreeList. // If "tc" is the first chunk in the list, it is also the @@ -96,13 +110,13 @@ class TreeList: public FreeList { // returns the possibly replaced TreeList* for the node in // the tree. It also updates the parent of the original // node to point to the new node. - TreeList* removeChunkReplaceIfNeeded(TreeChunk* tc); + TreeList* removeChunkReplaceIfNeeded(TreeChunk* tc); // See FreeList. - void returnChunkAtHead(TreeChunk* tc); - void returnChunkAtTail(TreeChunk* tc); + void returnChunkAtHead(TreeChunk* tc); + void returnChunkAtTail(TreeChunk* tc); }; -// A TreeChunk is a subclass of a FreeChunk that additionally +// A TreeChunk is a subclass of a Chunk that additionally // maintains a pointer to the free list on which it is currently // linked. // A TreeChunk is also used as a node in the binary tree. This @@ -115,92 +129,111 @@ class TreeList: public FreeList { // on the free list for a node in the tree and is only removed if // it is the last chunk on the free list. -class TreeChunk : public FreeChunk { - friend class TreeList; - TreeList* _list; - TreeList _embedded_list; // if non-null, this chunk is on _list +template +class TreeChunk : public Chunk { + friend class TreeList; + TreeList* _list; + TreeList _embedded_list; // if non-null, this chunk is on _list protected: - TreeList* embedded_list() const { return (TreeList*) &_embedded_list; } - void set_embedded_list(TreeList* v) { _embedded_list = *v; } + TreeList* embedded_list() const { return (TreeList*) &_embedded_list; } + void set_embedded_list(TreeList* v) { _embedded_list = *v; } public: - TreeList* list() { return _list; } - void set_list(TreeList* v) { _list = v; } - static TreeChunk* as_TreeChunk(FreeChunk* fc); + TreeList* list() { return _list; } + void set_list(TreeList* v) { _list = v; } + static TreeChunk* as_TreeChunk(Chunk* fc); // Initialize fields in a TreeChunk that should be // initialized when the TreeChunk is being added to // a free list in the tree. void initialize() { embedded_list()->initialize(); } + Chunk* next() const { return Chunk::next(); } + Chunk* prev() const { return Chunk::prev(); } + size_t size() const volatile { return Chunk::size(); } + // debugging void verifyTreeChunkList() const; }; -const size_t MIN_TREE_CHUNK_SIZE = sizeof(TreeChunk)/HeapWordSize; -class BinaryTreeDictionary: public FreeBlockDictionary { +template +class BinaryTreeDictionary: public FreeBlockDictionary { friend class VMStructs; bool _splay; size_t _totalSize; size_t _totalFreeBlocks; - TreeList* _root; + TreeList* _root; + bool _adaptive_freelists; // private accessors bool splay() const { return _splay; } void set_splay(bool v) { _splay = v; } - size_t totalSize() const { return _totalSize; } void set_totalSize(size_t v) { _totalSize = v; } virtual void inc_totalSize(size_t v); virtual void dec_totalSize(size_t v); size_t totalFreeBlocks() const { return _totalFreeBlocks; } void set_totalFreeBlocks(size_t v) { _totalFreeBlocks = v; } - TreeList* root() const { return _root; } - void set_root(TreeList* v) { _root = v; } + TreeList* root() const { return _root; } + void set_root(TreeList* v) { _root = v; } + bool adaptive_freelists() { return _adaptive_freelists; } + + // This field is added and can be set to point to the + // the Mutex used to synchronize access to the + // dictionary so that assertion checking can be done. + // For example it is set to point to _parDictionaryAllocLock. + NOT_PRODUCT(Mutex* _lock;) // Remove a chunk of size "size" or larger from the tree and // return it. If the chunk // is the last chunk of that size, remove the node for that size // from the tree. - TreeChunk* getChunkFromTree(size_t size, Dither dither, bool splay); + TreeChunk* getChunkFromTree(size_t size, enum FreeBlockDictionary::Dither dither, bool splay); // Return a list of the specified size or NULL from the tree. // The list is not removed from the tree. - TreeList* findList (size_t size) const; + TreeList* findList (size_t size) const; // Remove this chunk from the tree. If the removal results // in an empty list in the tree, remove the empty list. - TreeChunk* removeChunkFromTree(TreeChunk* tc); + TreeChunk* removeChunkFromTree(TreeChunk* tc); // Remove the node in the trees starting at tl that has the // minimum value and return it. Repair the tree as needed. - TreeList* removeTreeMinimum(TreeList* tl); - void semiSplayStep(TreeList* tl); + TreeList* removeTreeMinimum(TreeList* tl); + void semiSplayStep(TreeList* tl); // Add this free chunk to the tree. - void insertChunkInTree(FreeChunk* freeChunk); + void insertChunkInTree(Chunk* freeChunk); public: + + static const size_t min_tree_chunk_size = sizeof(TreeChunk)/HeapWordSize; + void verifyTree() const; // verify that the given chunk is in the tree. - bool verifyChunkInFreeLists(FreeChunk* tc) const; + bool verifyChunkInFreeLists(Chunk* tc) const; private: - void verifyTreeHelper(TreeList* tl) const; - static size_t verifyPrevFreePtrs(TreeList* tl); + void verifyTreeHelper(TreeList* tl) const; + static size_t verifyPrevFreePtrs(TreeList* tl); // Returns the total number of chunks in the list. - size_t totalListLength(TreeList* tl) const; + size_t totalListLength(TreeList* tl) const; // Returns the total number of words in the chunks in the tree // starting at "tl". - size_t totalSizeInTree(TreeList* tl) const; + size_t totalSizeInTree(TreeList* tl) const; // Returns the sum of the square of the size of each block // in the tree starting at "tl". - double sum_of_squared_block_sizes(TreeList* const tl) const; + double sum_of_squared_block_sizes(TreeList* const tl) const; // Returns the total number of free blocks in the tree starting // at "tl". - size_t totalFreeBlocksInTree(TreeList* tl) const; + size_t totalFreeBlocksInTree(TreeList* tl) const; size_t numFreeBlocks() const; size_t treeHeight() const; - size_t treeHeightHelper(TreeList* tl) const; - size_t totalNodesInTree(TreeList* tl) const; - size_t totalNodesHelper(TreeList* tl) const; + size_t treeHeightHelper(TreeList* tl) const; + size_t totalNodesInTree(TreeList* tl) const; + size_t totalNodesHelper(TreeList* tl) const; public: // Constructor - BinaryTreeDictionary(MemRegion mr, bool splay = false); + BinaryTreeDictionary(bool adaptive_freelists, bool splay = false); + BinaryTreeDictionary(MemRegion mr, bool adaptive_freelists, bool splay = false); + + // Public accessors + size_t totalSize() const { return _totalSize; } // Reset the dictionary to the initial conditions with // a single free chunk. @@ -212,22 +245,22 @@ class BinaryTreeDictionary: public FreeBlockDictionary { // Return a chunk of size "size" or greater from // the tree. // want a better dynamic splay strategy for the future. - FreeChunk* getChunk(size_t size, Dither dither) { - verify_par_locked(); - FreeChunk* res = getChunkFromTree(size, dither, splay()); + Chunk* getChunk(size_t size, enum FreeBlockDictionary::Dither dither) { + FreeBlockDictionary::verify_par_locked(); + Chunk* res = getChunkFromTree(size, dither, splay()); assert(res == NULL || res->isFree(), "Should be returning a free chunk"); return res; } - void returnChunk(FreeChunk* chunk) { - verify_par_locked(); + void returnChunk(Chunk* chunk) { + FreeBlockDictionary::verify_par_locked(); insertChunkInTree(chunk); } - void removeChunk(FreeChunk* chunk) { - verify_par_locked(); - removeChunkFromTree((TreeChunk*)chunk); + void removeChunk(Chunk* chunk) { + FreeBlockDictionary::verify_par_locked(); + removeChunkFromTree((TreeChunk*)chunk); assert(chunk->isFree(), "Should still be a free chunk"); } @@ -243,14 +276,14 @@ class BinaryTreeDictionary: public FreeBlockDictionary { } size_t minSize() const { - return MIN_TREE_CHUNK_SIZE; + return min_tree_chunk_size; } double sum_of_squared_block_sizes() const { return sum_of_squared_block_sizes(root()); } - FreeChunk* find_chunk_ends_at(HeapWord* target) const; + Chunk* find_chunk_ends_at(HeapWord* target) const; // Find the list with size "size" in the binary tree and update // the statistics in the list according to "split" (chunk was @@ -269,7 +302,7 @@ class BinaryTreeDictionary: public FreeBlockDictionary { // statistics for the sweep. void endSweepDictCensus(double splitSurplusPercent); // Return the largest free chunk in the tree. - FreeChunk* findLargestDict() const; + Chunk* findLargestDict() const; // Accessors for statistics void setTreeSurplus(double splitSurplusPercent); void setTreeHints(void); @@ -293,4 +326,4 @@ class BinaryTreeDictionary: public FreeBlockDictionary { void verify() const; }; -#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_BINARYTREEDICTIONARY_HPP +#endif // SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp similarity index 76% rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp rename to hotspot/src/share/vm/memory/freeBlockDictionary.cpp index 1870c1f1b24..03314ebbe44 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp +++ b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp @@ -23,7 +23,10 @@ */ #include "precompiled.hpp" -#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp" +#ifndef SERIALGC +#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" +#endif // SERIALGC +#include "memory/freeBlockDictionary.hpp" #ifdef TARGET_OS_FAMILY_linux # include "thread_linux.inline.hpp" #endif @@ -38,15 +41,15 @@ #endif #ifndef PRODUCT -Mutex* FreeBlockDictionary::par_lock() const { +template Mutex* FreeBlockDictionary::par_lock() const { return _lock; } -void FreeBlockDictionary::set_par_lock(Mutex* lock) { +template void FreeBlockDictionary::set_par_lock(Mutex* lock) { _lock = lock; } -void FreeBlockDictionary::verify_par_locked() const { +template void FreeBlockDictionary::verify_par_locked() const { #ifdef ASSERT if (ParallelGCThreads > 0) { Thread* myThread = Thread::current(); @@ -58,3 +61,8 @@ void FreeBlockDictionary::verify_par_locked() const { #endif // ASSERT } #endif + +#ifndef SERIALGC +// Explicitly instantiate for FreeChunk +template class FreeBlockDictionary; +#endif // SERIALGC diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp b/hotspot/src/share/vm/memory/freeBlockDictionary.hpp similarity index 80% rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp rename to hotspot/src/share/vm/memory/freeBlockDictionary.hpp index 538662028df..43148837373 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp +++ b/hotspot/src/share/vm/memory/freeBlockDictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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,12 +22,10 @@ * */ -#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREEBLOCKDICTIONARY_HPP -#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREEBLOCKDICTIONARY_HPP +#ifndef SHARE_VM_MEMORY_FREEBLOCKDICTIONARY_HPP +#define SHARE_VM_MEMORY_FREEBLOCKDICTIONARY_HPP -#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" #include "memory/allocation.hpp" -#include "memory/memRegion.hpp" #include "runtime/mutex.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" @@ -35,6 +33,7 @@ // A FreeBlockDictionary is an abstract superclass that will allow // a number of alternative implementations in the future. +template class FreeBlockDictionary: public CHeapObj { public: enum Dither { @@ -52,9 +51,9 @@ class FreeBlockDictionary: public CHeapObj { NOT_PRODUCT(Mutex* _lock;) public: - virtual void removeChunk(FreeChunk* fc) = 0; - virtual FreeChunk* getChunk(size_t size, Dither dither = atLeast) = 0; - virtual void returnChunk(FreeChunk* chunk) = 0; + virtual void removeChunk(Chunk* fc) = 0; + virtual Chunk* getChunk(size_t size, Dither dither = atLeast) = 0; + virtual void returnChunk(Chunk* chunk) = 0; virtual size_t totalChunkSize(debug_only(const Mutex* lock)) const = 0; virtual size_t maxChunkSize() const = 0; virtual size_t minSize() const = 0; @@ -69,14 +68,14 @@ class FreeBlockDictionary: public CHeapObj { float inter_sweep_current, float inter_sweep_estimate, float intra__sweep_current) = 0; virtual void endSweepDictCensus(double splitSurplusPercent) = 0; - virtual FreeChunk* findLargestDict() const = 0; + virtual Chunk* findLargestDict() const = 0; // verify that the given chunk is in the dictionary. - virtual bool verifyChunkInFreeLists(FreeChunk* tc) const = 0; + virtual bool verifyChunkInFreeLists(Chunk* tc) const = 0; // Sigma_{all_free_blocks} (block_size^2) virtual double sum_of_squared_block_sizes() const = 0; - virtual FreeChunk* find_chunk_ends_at(HeapWord* target) const = 0; + virtual Chunk* find_chunk_ends_at(HeapWord* target) const = 0; virtual void inc_totalSize(size_t v) = 0; virtual void dec_totalSize(size_t v) = 0; @@ -100,4 +99,4 @@ class FreeBlockDictionary: public CHeapObj { void verify_par_locked() const PRODUCT_RETURN; }; -#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREEBLOCKDICTIONARY_HPP +#endif // SHARE_VM_MEMORY_FREEBLOCKDICTIONARY_HPP diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp b/hotspot/src/share/vm/memory/freeList.cpp similarity index 84% rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp rename to hotspot/src/share/vm/memory/freeList.cpp index 192b055481b..0ffd8f52f06 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp +++ b/hotspot/src/share/vm/memory/freeList.cpp @@ -23,20 +23,25 @@ */ #include "precompiled.hpp" -#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp" -#include "gc_implementation/concurrentMarkSweep/freeList.hpp" +#include "memory/freeBlockDictionary.hpp" +#include "memory/freeList.hpp" #include "memory/sharedHeap.hpp" #include "runtime/globals.hpp" #include "runtime/mutex.hpp" #include "runtime/vmThread.hpp" +#ifndef SERIALGC +#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" +#endif // SERIALGC + // Free list. A FreeList is used to access a linked list of chunks // of space in the heap. The head and tail are maintained so that // items can be (as in the current implementation) added at the // at the tail of the list and removed from the head of the list to // maintain a FIFO queue. -FreeList::FreeList() : +template +FreeList::FreeList() : _head(NULL), _tail(NULL) #ifdef ASSERT , _protecting_lock(NULL) @@ -48,7 +53,8 @@ FreeList::FreeList() : init_statistics(); } -FreeList::FreeList(FreeChunk* fc) : +template +FreeList::FreeList(Chunk* fc) : _head(fc), _tail(fc) #ifdef ASSERT , _protecting_lock(NULL) @@ -63,40 +69,27 @@ FreeList::FreeList(FreeChunk* fc) : #endif } -FreeList::FreeList(HeapWord* addr, size_t size) : - _head((FreeChunk*) addr), _tail((FreeChunk*) addr) -#ifdef ASSERT - , _protecting_lock(NULL) -#endif -{ - assert(size > sizeof(FreeChunk), "size is too small"); - head()->setSize(size); - _size = size; - _count = 1; - init_statistics(); -#ifndef PRODUCT - _allocation_stats.set_returnedBytes(_size * HeapWordSize); -#endif -} - -void FreeList::reset(size_t hint) { +template +void FreeList::reset(size_t hint) { set_count(0); set_head(NULL); set_tail(NULL); set_hint(hint); } -void FreeList::init_statistics(bool split_birth) { +template +void FreeList::init_statistics(bool split_birth) { _allocation_stats.initialize(split_birth); } -FreeChunk* FreeList::getChunkAtHead() { +template +Chunk* FreeList::getChunkAtHead() { assert_proper_lock_protection(); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); - FreeChunk* fc = head(); + Chunk* fc = head(); if (fc != NULL) { - FreeChunk* nextFC = fc->next(); + Chunk* nextFC = fc->next(); if (nextFC != NULL) { // The chunk fc being removed has a "next". Set the "next" to the // "prev" of fc. @@ -113,20 +106,21 @@ FreeChunk* FreeList::getChunkAtHead() { } -void FreeList::getFirstNChunksFromList(size_t n, FreeList* fl) { +template +void FreeList::getFirstNChunksFromList(size_t n, FreeList* fl) { assert_proper_lock_protection(); assert(fl->count() == 0, "Precondition"); if (count() > 0) { int k = 1; fl->set_head(head()); n--; - FreeChunk* tl = head(); + Chunk* tl = head(); while (tl->next() != NULL && n > 0) { tl = tl->next(); n--; k++; } assert(tl != NULL, "Loop Inv."); // First, fix up the list we took from. - FreeChunk* new_head = tl->next(); + Chunk* new_head = tl->next(); set_head(new_head); set_count(count() - k); if (new_head == NULL) { @@ -143,7 +137,8 @@ void FreeList::getFirstNChunksFromList(size_t n, FreeList* fl) { } // Remove this chunk from the list -void FreeList::removeChunk(FreeChunk*fc) { +template +void FreeList::removeChunk(Chunk*fc) { assert_proper_lock_protection(); assert(head() != NULL, "Remove from empty list"); assert(fc != NULL, "Remove a NULL chunk"); @@ -151,8 +146,8 @@ void FreeList::removeChunk(FreeChunk*fc) { assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); - FreeChunk* prevFC = fc->prev(); - FreeChunk* nextFC = fc->next(); + Chunk* prevFC = fc->prev(); + Chunk* nextFC = fc->next(); if (nextFC != NULL) { // The chunk fc being removed has a "next". Set the "next" to the // "prev" of fc. @@ -185,14 +180,15 @@ void FreeList::removeChunk(FreeChunk*fc) { } // Add this chunk at the head of the list. -void FreeList::returnChunkAtHead(FreeChunk* chunk, bool record_return) { +template +void FreeList::returnChunkAtHead(Chunk* chunk, bool record_return) { assert_proper_lock_protection(); assert(chunk != NULL, "insert a NULL chunk"); assert(size() == chunk->size(), "Wrong size"); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); - FreeChunk* oldHead = head(); + Chunk* oldHead = head(); assert(chunk != oldHead, "double insertion"); chunk->linkAfter(oldHead); link_head(chunk); @@ -212,20 +208,22 @@ void FreeList::returnChunkAtHead(FreeChunk* chunk, bool record_return) { assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); } -void FreeList::returnChunkAtHead(FreeChunk* chunk) { +template +void FreeList::returnChunkAtHead(Chunk* chunk) { assert_proper_lock_protection(); returnChunkAtHead(chunk, true); } // Add this chunk at the tail of the list. -void FreeList::returnChunkAtTail(FreeChunk* chunk, bool record_return) { +template +void FreeList::returnChunkAtTail(Chunk* chunk, bool record_return) { assert_proper_lock_protection(); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); assert(chunk != NULL, "insert a NULL chunk"); assert(size() == chunk->size(), "wrong size"); - FreeChunk* oldTail = tail(); + Chunk* oldTail = tail(); assert(chunk != oldTail, "double insertion"); if (oldTail != NULL) { oldTail->linkAfter(chunk); @@ -246,11 +244,13 @@ void FreeList::returnChunkAtTail(FreeChunk* chunk, bool record_return) { assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); } -void FreeList::returnChunkAtTail(FreeChunk* chunk) { +template +void FreeList::returnChunkAtTail(Chunk* chunk) { returnChunkAtTail(chunk, true); } -void FreeList::prepend(FreeList* fl) { +template +void FreeList::prepend(FreeList* fl) { assert_proper_lock_protection(); if (fl->count() > 0) { if (count() == 0) { @@ -259,8 +259,8 @@ void FreeList::prepend(FreeList* fl) { set_count(fl->count()); } else { // Both are non-empty. - FreeChunk* fl_tail = fl->tail(); - FreeChunk* this_head = head(); + Chunk* fl_tail = fl->tail(); + Chunk* this_head = head(); assert(fl_tail->next() == NULL, "Well-formedness of fl"); fl_tail->linkNext(this_head); this_head->linkPrev(fl_tail); @@ -275,11 +275,12 @@ void FreeList::prepend(FreeList* fl) { // verifyChunkInFreeLists() is used to verify that an item is in this free list. // It is used as a debugging aid. -bool FreeList::verifyChunkInFreeLists(FreeChunk* fc) const { +template +bool FreeList::verifyChunkInFreeLists(Chunk* fc) const { // This is an internal consistency check, not part of the check that the // chunk is in the free lists. guarantee(fc->size() == size(), "Wrong list is being searched"); - FreeChunk* curFC = head(); + Chunk* curFC = head(); while (curFC) { // This is an internal consistency check. guarantee(size() == curFC->size(), "Chunk is in wrong list."); @@ -292,7 +293,8 @@ bool FreeList::verifyChunkInFreeLists(FreeChunk* fc) const { } #ifndef PRODUCT -void FreeList::verify_stats() const { +template +void FreeList::verify_stats() const { // The +1 of the LH comparand is to allow some "looseness" in // checking: we usually call this interface when adding a block // and we'll subsequently update the stats; we cannot update the @@ -317,7 +319,8 @@ void FreeList::verify_stats() const { _allocation_stats.coalDeaths(), count())); } -void FreeList::assert_proper_lock_protection_work() const { +template +void FreeList::assert_proper_lock_protection_work() const { assert(_protecting_lock != NULL, "Don't call this directly"); assert(ParallelGCThreads > 0, "Don't call this directly"); Thread* thr = Thread::current(); @@ -334,7 +337,8 @@ void FreeList::assert_proper_lock_protection_work() const { #endif // Print the "label line" for free list stats. -void FreeList::print_labels_on(outputStream* st, const char* c) { +template +void FreeList::print_labels_on(outputStream* st, const char* c) { st->print("%16s\t", c); st->print("%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "\n", @@ -346,7 +350,8 @@ void FreeList::print_labels_on(outputStream* st, const char* c) { // to the call is a non-null string, it is printed in the first column; // otherwise, if the argument is null (the default), then the size of the // (free list) block is printed in the first column. -void FreeList::print_on(outputStream* st, const char* c) const { +template +void FreeList::print_on(outputStream* st, const char* c) const { if (c != NULL) { st->print("%16s", c); } else { @@ -358,3 +363,8 @@ void FreeList::print_on(outputStream* st, const char* c) const { bfrSurp(), surplus(), desired(), prevSweep(), beforeSweep(), count(), coalBirths(), coalDeaths(), splitBirths(), splitDeaths()); } + +#ifndef SERIALGC +// Needs to be after the definitions have been seen. +template class FreeList; +#endif // SERIALGC diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp b/hotspot/src/share/vm/memory/freeList.hpp similarity index 86% rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp rename to hotspot/src/share/vm/memory/freeList.hpp index 44afe8e56a8..77e42053bf5 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp +++ b/hotspot/src/share/vm/memory/freeList.hpp @@ -22,39 +22,36 @@ * */ -#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREELIST_HPP -#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREELIST_HPP +#ifndef SHARE_VM_MEMORY_FREELIST_HPP +#define SHARE_VM_MEMORY_FREELIST_HPP #include "gc_implementation/shared/allocationStats.hpp" class CompactibleFreeListSpace; -// A class for maintaining a free list of FreeChunk's. The FreeList +// A class for maintaining a free list of Chunk's. The FreeList // maintains a the structure of the list (head, tail, etc.) plus // statistics for allocations from the list. The links between items // are not part of FreeList. The statistics are -// used to make decisions about coalescing FreeChunk's when they +// used to make decisions about coalescing Chunk's when they // are swept during collection. // // See the corresponding .cpp file for a description of the specifics // for that implementation. class Mutex; -class TreeList; +template class TreeList; +template class PrintTreeCensusClosure; +template class FreeList VALUE_OBJ_CLASS_SPEC { friend class CompactibleFreeListSpace; friend class VMStructs; - friend class PrintTreeCensusClosure; - - protected: - TreeList* _parent; - TreeList* _left; - TreeList* _right; + friend class PrintTreeCensusClosure; private: - FreeChunk* _head; // Head of list of free chunks - FreeChunk* _tail; // Tail of list of free chunks + Chunk* _head; // Head of list of free chunks + Chunk* _tail; // Tail of list of free chunks size_t _size; // Size in Heap words of each chunk ssize_t _count; // Number of entries in list size_t _hint; // next larger size list with a positive surplus @@ -92,10 +89,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC { // Construct a list without any entries. FreeList(); // Construct a list with "fc" as the first (and lone) entry in the list. - FreeList(FreeChunk* fc); - // Construct a list which will have a FreeChunk at address "addr" and - // of size "size" as the first (and lone) entry in the list. - FreeList(HeapWord* addr, size_t size); + FreeList(Chunk* fc); // Reset the head, tail, hint, and count of a free list. void reset(size_t hint); @@ -108,18 +102,18 @@ class FreeList VALUE_OBJ_CLASS_SPEC { #endif // Accessors. - FreeChunk* head() const { + Chunk* head() const { assert_proper_lock_protection(); return _head; } - void set_head(FreeChunk* v) { + void set_head(Chunk* v) { assert_proper_lock_protection(); _head = v; assert(!_head || _head->size() == _size, "bad chunk size"); } // Set the head of the list and set the prev field of non-null // values to NULL. - void link_head(FreeChunk* v) { + void link_head(Chunk* v) { assert_proper_lock_protection(); set_head(v); // If this method is not used (just set the head instead), @@ -129,18 +123,18 @@ class FreeList VALUE_OBJ_CLASS_SPEC { } } - FreeChunk* tail() const { + Chunk* tail() const { assert_proper_lock_protection(); return _tail; } - void set_tail(FreeChunk* v) { + void set_tail(Chunk* v) { assert_proper_lock_protection(); _tail = v; assert(!_tail || _tail->size() == _size, "bad chunk size"); } // Set the tail of the list and set the next field of non-null // values to NULL. - void link_tail(FreeChunk* v) { + void link_tail(Chunk* v) { assert_proper_lock_protection(); set_tail(v); if (v != NULL) { @@ -298,31 +292,31 @@ class FreeList VALUE_OBJ_CLASS_SPEC { // Unlink head of list and return it. Returns NULL if // the list is empty. - FreeChunk* getChunkAtHead(); + Chunk* getChunkAtHead(); // Remove the first "n" or "count", whichever is smaller, chunks from the // list, setting "fl", which is required to be empty, to point to them. - void getFirstNChunksFromList(size_t n, FreeList* fl); + void getFirstNChunksFromList(size_t n, FreeList* fl); // Unlink this chunk from it's free list - void removeChunk(FreeChunk* fc); + void removeChunk(Chunk* fc); // Add this chunk to this free list. - void returnChunkAtHead(FreeChunk* fc); - void returnChunkAtTail(FreeChunk* fc); + void returnChunkAtHead(Chunk* fc); + void returnChunkAtTail(Chunk* fc); // Similar to returnChunk* but also records some diagnostic // information. - void returnChunkAtHead(FreeChunk* fc, bool record_return); - void returnChunkAtTail(FreeChunk* fc, bool record_return); + void returnChunkAtHead(Chunk* fc, bool record_return); + void returnChunkAtTail(Chunk* fc, bool record_return); // Prepend "fl" (whose size is required to be the same as that of "this") // to the front of "this" list. - void prepend(FreeList* fl); + void prepend(FreeList* fl); // Verify that the chunk is in the list. // found. Return NULL if "fc" is not found. - bool verifyChunkInFreeLists(FreeChunk* fc) const; + bool verifyChunkInFreeLists(Chunk* fc) const; // Stats verification void verify_stats() const PRODUCT_RETURN; @@ -332,4 +326,4 @@ class FreeList VALUE_OBJ_CLASS_SPEC { void print_on(outputStream* st, const char* c = NULL) const; }; -#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREELIST_HPP +#endif // SHARE_VM_MEMORY_FREELIST_HPP diff --git a/hotspot/src/share/vm/memory/generationSpec.cpp b/hotspot/src/share/vm/memory/generationSpec.cpp index bbe63ce48fe..4b2c3fc49da 100644 --- a/hotspot/src/share/vm/memory/generationSpec.cpp +++ b/hotspot/src/share/vm/memory/generationSpec.cpp @@ -68,7 +68,7 @@ Generation* GenerationSpec::init(ReservedSpace rs, int level, ConcurrentMarkSweepGeneration* g = NULL; g = new ConcurrentMarkSweepGeneration(rs, init_size(), level, ctrs, UseCMSAdaptiveFreeLists, - (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice); + (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice); g->initialize_performance_counters(); @@ -88,7 +88,7 @@ Generation* GenerationSpec::init(ReservedSpace rs, int level, ASConcurrentMarkSweepGeneration* g = NULL; g = new ASConcurrentMarkSweepGeneration(rs, init_size(), level, ctrs, UseCMSAdaptiveFreeLists, - (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice); + (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice); g->initialize_performance_counters(); @@ -175,7 +175,7 @@ PermGen* PermanentGenerationSpec::init(ReservedSpace rs, } // XXXPERM return new CMSPermGen(perm_rs, init_size, ctrs, - (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice); + (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice); } #endif // SERIALGC default: diff --git a/hotspot/src/share/vm/precompiled/precompiled.hpp b/hotspot/src/share/vm/precompiled/precompiled.hpp index 686f256695b..0414e070aa1 100644 --- a/hotspot/src/share/vm/precompiled/precompiled.hpp +++ b/hotspot/src/share/vm/precompiled/precompiled.hpp @@ -293,13 +293,10 @@ # include "c1/c1_globals.hpp" #endif // COMPILER1 #ifndef SERIALGC -# include "gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp" # include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp" # include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" # include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp" -# include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp" # include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" -# include "gc_implementation/concurrentMarkSweep/freeList.hpp" # include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp" # include "gc_implementation/g1/dirtyCardQueue.hpp" # include "gc_implementation/g1/g1BlockOffsetTable.hpp" diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 25d3b5b4179..cc2d0783430 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -44,7 +44,6 @@ #include "code/vmreg.hpp" #include "compiler/oopMap.hpp" #include "compiler/compileBroker.hpp" -#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp" #include "gc_implementation/shared/immutableSpace.hpp" #include "gc_implementation/shared/markSweep.hpp" #include "gc_implementation/shared/mutableSpace.hpp" @@ -55,6 +54,7 @@ #include "memory/cardTableRS.hpp" #include "memory/compactPermGen.hpp" #include "memory/defNewGeneration.hpp" +#include "memory/freeBlockDictionary.hpp" #include "memory/genCollectedHeap.hpp" #include "memory/generation.hpp" #include "memory/generationSpec.hpp" From 6f5472dfe9d0c0259f23551a0e92c01321312411 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Tue, 3 Apr 2012 09:48:34 -0700 Subject: [PATCH 03/51] 7158067: FDS: ENABLE_FULL_DEBUG_SYMBOLS flag should only affect product builds Build option FULL_DEBUG_SYMBOLS=0 only affects product builds. Reviewed-by: ohair, jmelvin, sspitsyn --- hotspot/make/Makefile | 53 ++++++++++++++++-------- hotspot/make/linux/Makefile | 4 +- hotspot/make/linux/makefiles/defs.make | 34 ++++++++++++++- hotspot/make/solaris/Makefile | 4 +- hotspot/make/solaris/makefiles/defs.make | 34 ++++++++++++++- hotspot/make/windows/makefiles/defs.make | 32 +++++++++++++- 6 files changed, 135 insertions(+), 26 deletions(-) diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile index 5492205e4e2..f367de58fd6 100644 --- a/hotspot/make/Makefile +++ b/hotspot/make/Makefile @@ -136,31 +136,36 @@ docs: ifeq ($(OSNAME),windows) @$(ECHO) "No docs ($(VM_TARGET)) for windows" else +# We specify 'BUILD_FLAVOR=product' so that the proper +# ENABLE_FULL_DEBUG_SYMBOLS value is used. $(CD) $(OUTPUTDIR); \ $(MAKE) -f $(ABS_OS_MAKEFILE) \ - $(MAKE_ARGS) docs + $(MAKE_ARGS) BUILD_FLAVOR=product docs endif # Build variation of hotspot $(C1_VM_TARGETS): $(CD) $(GAMMADIR)/make; \ - $(MAKE) VM_TARGET=$@ generic_build1 $(ALT_OUT) + $(MAKE) BUILD_FLAVOR=$(@:%1=%) VM_TARGET=$@ generic_build1 $(ALT_OUT) $(C2_VM_TARGETS): $(CD) $(GAMMADIR)/make; \ - $(MAKE) VM_TARGET=$@ generic_build2 $(ALT_OUT) + $(MAKE) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT) $(KERNEL_VM_TARGETS): $(CD) $(GAMMADIR)/make; \ - $(MAKE) VM_TARGET=$@ generic_buildkernel $(ALT_OUT) + $(MAKE) BUILD_FLAVOR=$(@:%kernel=%) VM_TARGET=$@ \ + generic_buildkernel $(ALT_OUT) $(ZERO_VM_TARGETS): $(CD) $(GAMMADIR)/make; \ - $(MAKE) VM_TARGET=$@ generic_buildzero $(ALT_OUT) + $(MAKE) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ \ + generic_buildzero $(ALT_OUT) $(SHARK_VM_TARGETS): $(CD) $(GAMMADIR)/make; \ - $(MAKE) VM_TARGET=$@ generic_buildshark $(ALT_OUT) + $(MAKE) BUILD_FLAVOR=$(@:%shark=%) VM_TARGET=$@ \ + generic_buildshark $(ALT_OUT) # Build compiler1 (client) rule, different for platforms generic_build1: @@ -237,25 +242,37 @@ generic_buildshark: # Export file rule generic_export: $(EXPORT_LIST) export_product: - $(MAKE) VM_SUBDIR=product generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \ + generic_export export_fastdebug: - $(MAKE) VM_SUBDIR=fastdebug EXPORT_SUBDIR=/fastdebug generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \ + EXPORT_SUBDIR=/$(@:export_%=%) \ + generic_export export_debug: - $(MAKE) VM_SUBDIR=${VM_DEBUG} EXPORT_SUBDIR=/debug generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=${VM_DEBUG} \ + EXPORT_SUBDIR=/$(@:export_%=%) \ + generic_export export_optimized: - $(MAKE) VM_SUBDIR=optimized EXPORT_SUBDIR=/optimized generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \ + EXPORT_SUBDIR=/$(@:export_%=%) \ + generic_export export_product_jdk:: - $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \ - VM_SUBDIR=product generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \ + VM_SUBDIR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \ + generic_export export_optimized_jdk:: - $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \ - VM_SUBDIR=optimized generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \ + VM_SUBDIR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \ + generic_export export_fastdebug_jdk:: - $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/fastdebug \ - VM_SUBDIR=fastdebug generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) \ + VM_SUBDIR=$(@:export_%_jdk=%) \ + ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \ + generic_export export_debug_jdk:: - $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/debug \ - VM_SUBDIR=${VM_DEBUG} generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) VM_SUBDIR=${VM_DEBUG} \ + ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \ + generic_export # Export file copy rules XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt diff --git a/hotspot/make/linux/Makefile b/hotspot/make/linux/Makefile index 4c1854f124f..0ae3f4cc1dd 100644 --- a/hotspot/make/linux/Makefile +++ b/hotspot/make/linux/Makefile @@ -337,9 +337,11 @@ treeshark: $(SUBDIRS_SHARK) # Doc target. This is the same for all build options. # Hence create a docs directory beside ...$(ARCH)_[...] +# We specify 'BUILD_FLAVOR=product' so that the proper +# ENABLE_FULL_DEBUG_SYMBOLS value is used. docs: checks $(QUIETLY) mkdir -p $(SUBDIR_DOCS) - $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) jvmtidocs + $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) BUILD_FLAVOR=product jvmtidocs # Synonyms for win32-like targets. compiler2: jvmg product diff --git a/hotspot/make/linux/makefiles/defs.make b/hotspot/make/linux/makefiles/defs.make index 632a99b6a5c..db5a42ce765 100644 --- a/hotspot/make/linux/makefiles/defs.make +++ b/hotspot/make/linux/makefiles/defs.make @@ -130,9 +130,37 @@ endif ifeq ($(JDK6_OR_EARLIER),0) # Full Debug Symbols is supported on JDK7 or newer. - # Default is enabled with .debuginfo files ZIP'ed to save space. + # The Full Debug Symbols (FDS) default for BUILD_FLAVOR == product + # builds is enabled with debug info files ZIP'ed to save space. For + # BUILD_FLAVOR != product builds, FDS is always enabled, after all a + # debug build without debug info isn't very useful. + # The ZIP_DEBUGINFO_FILES option only has meaning when FDS is enabled. + # + # If you invoke a build with FULL_DEBUG_SYMBOLS=0, then FDS will be + # disabled for a BUILD_FLAVOR == product build. + # + # Note: Use of a different variable name for the FDS override option + # versus the FDS enabled check is intentional (FULL_DEBUG_SYMBOLS + # versus ENABLE_FULL_DEBUG_SYMBOLS). For auto build systems that pass + # in options via environment variables, use of distinct variables + # prevents strange behaviours. For example, in a BUILD_FLAVOR != + # product build, the FULL_DEBUG_SYMBOLS environment variable will be + # 0, but the ENABLE_FULL_DEBUG_SYMBOLS make variable will be 1. If + # the same variable name is used, then different values can be picked + # up by different parts of the build. Just to be clear, we only need + # two variable names because the incoming option value can be + # overridden in some situations, e.g., a BUILD_FLAVOR != product + # build. - ENABLE_FULL_DEBUG_SYMBOLS ?= 1 + ifeq ($(BUILD_FLAVOR), product) + FULL_DEBUG_SYMBOLS ?= 1 + ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS) + else + # debug variants always get Full Debug Symbols (if available) + ENABLE_FULL_DEBUG_SYMBOLS = 1 + endif + _JUNK_ := $(shell \ + echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) @@ -159,6 +187,8 @@ ifeq ($(JDK6_OR_EARLIER),0) _JUNK_ := $(shell \ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.") ENABLE_FULL_DEBUG_SYMBOLS=0 + _JUNK_ := $(shell \ + echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") else _JUNK_ := $(shell \ echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.") diff --git a/hotspot/make/solaris/Makefile b/hotspot/make/solaris/Makefile index ae6b2be6b23..eec2be46da6 100644 --- a/hotspot/make/solaris/Makefile +++ b/hotspot/make/solaris/Makefile @@ -278,9 +278,11 @@ treekernel: $(SUBDIRS_KERNEL) # Doc target. This is the same for all build options. # Hence create a docs directory beside ...$(ARCH)_[...] +# We specify 'BUILD_FLAVOR=product' so that the proper +# ENABLE_FULL_DEBUG_SYMBOLS value is used. docs: checks $(QUIETLY) mkdir -p $(SUBDIR_DOCS) - $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) jvmtidocs + $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) BUILD_FLAVOR=product jvmtidocs # Synonyms for win32-like targets. compiler2: jvmg product diff --git a/hotspot/make/solaris/makefiles/defs.make b/hotspot/make/solaris/makefiles/defs.make index 3674d48e475..8e480946bc8 100644 --- a/hotspot/make/solaris/makefiles/defs.make +++ b/hotspot/make/solaris/makefiles/defs.make @@ -75,9 +75,37 @@ endif ifeq ($(JDK6_OR_EARLIER),0) # Full Debug Symbols is supported on JDK7 or newer. - # Default is enabled with .debuginfo files ZIP'ed to save space. + # The Full Debug Symbols (FDS) default for BUILD_FLAVOR == product + # builds is enabled with debug info files ZIP'ed to save space. For + # BUILD_FLAVOR != product builds, FDS is always enabled, after all a + # debug build without debug info isn't very useful. + # The ZIP_DEBUGINFO_FILES option only has meaning when FDS is enabled. + # + # If you invoke a build with FULL_DEBUG_SYMBOLS=0, then FDS will be + # disabled for a BUILD_FLAVOR == product build. + # + # Note: Use of a different variable name for the FDS override option + # versus the FDS enabled check is intentional (FULL_DEBUG_SYMBOLS + # versus ENABLE_FULL_DEBUG_SYMBOLS). For auto build systems that pass + # in options via environment variables, use of distinct variables + # prevents strange behaviours. For example, in a BUILD_FLAVOR != + # product build, the FULL_DEBUG_SYMBOLS environment variable will be + # 0, but the ENABLE_FULL_DEBUG_SYMBOLS make variable will be 1. If + # the same variable name is used, then different values can be picked + # up by different parts of the build. Just to be clear, we only need + # two variable names because the incoming option value can be + # overridden in some situations, e.g., a BUILD_FLAVOR != product + # build. - ENABLE_FULL_DEBUG_SYMBOLS ?= 1 + ifeq ($(BUILD_FLAVOR), product) + FULL_DEBUG_SYMBOLS ?= 1 + ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS) + else + # debug variants always get Full Debug Symbols (if available) + ENABLE_FULL_DEBUG_SYMBOLS = 1 + endif + _JUNK_ := $(shell \ + echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) @@ -111,6 +139,8 @@ ifeq ($(JDK6_OR_EARLIER),0) _JUNK_ := $(shell \ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.") ENABLE_FULL_DEBUG_SYMBOLS=0 + _JUNK_ := $(shell \ + echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") else _JUNK_ := $(shell \ echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.") diff --git a/hotspot/make/windows/makefiles/defs.make b/hotspot/make/windows/makefiles/defs.make index 0e1a31ade77..e922ce29660 100644 --- a/hotspot/make/windows/makefiles/defs.make +++ b/hotspot/make/windows/makefiles/defs.make @@ -109,9 +109,37 @@ endif # Full Debug Symbols has been enabled on Windows since JDK1.4.1 so # there is no need for an "earlier than JDK7 check". -# Default is enabled with debug info files ZIP'ed to save space. +# The Full Debug Symbols (FDS) default for BUILD_FLAVOR == product +# builds is enabled with debug info files ZIP'ed to save space. For +# BUILD_FLAVOR != product builds, FDS is always enabled, after all a +# debug build without debug info isn't very useful. +# The ZIP_DEBUGINFO_FILES option only has meaning when FDS is enabled. +# +# If you invoke a build with FULL_DEBUG_SYMBOLS=0, then FDS will be +# disabled for a BUILD_FLAVOR == product build. +# +# Note: Use of a different variable name for the FDS override option +# versus the FDS enabled check is intentional (FULL_DEBUG_SYMBOLS +# versus ENABLE_FULL_DEBUG_SYMBOLS). For auto build systems that pass +# in options via environment variables, use of distinct variables +# prevents strange behaviours. For example, in a BUILD_FLAVOR != +# product build, the FULL_DEBUG_SYMBOLS environment variable will be +# 0, but the ENABLE_FULL_DEBUG_SYMBOLS make variable will be 1. If +# the same variable name is used, then different values can be picked +# up by different parts of the build. Just to be clear, we only need +# two variable names because the incoming option value can be +# overridden in some situations, e.g., a BUILD_FLAVOR != product +# build. -ENABLE_FULL_DEBUG_SYMBOLS ?= 1 +ifeq ($(BUILD_FLAVOR), product) + FULL_DEBUG_SYMBOLS ?= 1 + ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS) +else + # debug variants always get Full Debug Symbols (if available) + ENABLE_FULL_DEBUG_SYMBOLS = 1 +endif +_JUNK_ := $(shell \ + echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) From d090606f367fc4683046c18443c669ff60a69193 Mon Sep 17 00:00:00 2001 From: James Melvin Date: Mon, 16 Apr 2012 18:09:53 -0400 Subject: [PATCH 04/51] 7130404: [macosx] "os.arch" value should be "x86_64" for compatibility with Apple JDK6 On Mac OS X, align system property "os.arch" with Apple legacy JDKs. Also, improve os.name string matching by using .contains() method instead of .startsWith(). This fix spans multiple repositories. Reviewed-by: dcubed, phh, ohair, katleman --- jdk/make/common/Defs-macosx.gmk | 12 ++++++------ jdk/make/common/shared/Platform.gmk | 4 ++-- .../java/net/AbstractPlainDatagramSocketImpl.java | 4 ++-- jdk/src/share/classes/java/nio/Bits.java | 4 ++-- .../share/classes/java/util/prefs/Preferences.java | 4 ++-- jdk/src/share/classes/sun/awt/OSInfo.java | 4 ++-- jdk/src/share/classes/sun/font/FontUtilities.java | 4 ++-- .../share/classes/sun/launcher/LauncherHelper.java | 4 ++-- .../classes/sun/nio/cs/ext/ExtendedCharsets.java | 4 ++-- jdk/src/share/classes/sun/print/PSPrinterJob.java | 4 ++-- .../sun/security/jgss/wrapper/SunNativeProvider.java | 4 ++-- jdk/src/share/classes/sun/security/krb5/Config.java | 4 ++-- .../share/classes/sun/security/krb5/Credentials.java | 6 +++--- .../sun/security/provider/ByteArrayAccess.java | 5 +++-- .../nio/ch/DefaultAsynchronousChannelProvider.java | 4 ++-- .../sun/nio/fs/DefaultFileSystemProvider.java | 4 ++-- .../classes/sun/print/UnixPrintServiceLookup.java | 4 ++-- jdk/test/demo/jvmti/DemoRun.java | 4 ++-- jdk/test/java/io/File/GetXSpace.java | 4 ++-- jdk/test/java/lang/ProcessBuilder/Basic.java | 4 ++-- jdk/test/java/lang/ProcessBuilder/Zombies.java | 4 ++-- jdk/test/java/lang/invoke/InvokeGenericTest.java | 4 ++-- .../OperatingSystemMXBean/GetSystemLoadAverage.java | 6 +++--- jdk/test/java/nio/channels/FileChannel/Size.java | 4 ++-- jdk/test/java/nio/channels/FileChannel/Transfer.java | 4 ++-- jdk/test/java/nio/file/FileSystem/Basic.java | 4 ++-- jdk/test/sun/nio/ch/SelProvider.java | 4 ++-- jdk/test/tools/launcher/TestHelper.java | 2 +- 28 files changed, 62 insertions(+), 61 deletions(-) diff --git a/jdk/make/common/Defs-macosx.gmk b/jdk/make/common/Defs-macosx.gmk index 53871ac1d5f..b3349db2711 100644 --- a/jdk/make/common/Defs-macosx.gmk +++ b/jdk/make/common/Defs-macosx.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012, 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 @@ -111,10 +111,10 @@ CC_OPT = $(CC_OPT/$(OPTIMIZATION_LEVEL)) # For all platforms, do not omit the frame pointer register usage. # We need this frame pointer to make it easy to walk the stacks. -# This should be the default on X86, but ia64 and amd64 may not have this -# as the default. -CFLAGS_REQUIRED_amd64 += -m64 -fno-omit-frame-pointer -D_LITTLE_ENDIAN -LDFLAGS_COMMON_amd64 += -m64 +# This should be the default on X86, but ia64, and x86_64 +# may not have this as the default. +CFLAGS_REQUIRED_x86_64 += -m64 -fno-omit-frame-pointer -D_LITTLE_ENDIAN +LDFLAGS_COMMON_x86_64 += -m64 CFLAGS_REQUIRED_i586 += -m32 -fno-omit-frame-pointer -D_LITTLE_ENDIAN LDFLAGS_COMMON_i586 += -m32 CFLAGS_REQUIRED_ia64 += -m64 -fno-omit-frame-pointer -D_LITTLE_ENDIAN @@ -168,7 +168,7 @@ PIC_CODE_LARGE = -fPIC PIC_CODE_SMALL = -fpic GLOBAL_KPIC = $(PIC_CODE_LARGE) CFLAGS_COMMON += $(GLOBAL_KPIC) $(GCC_WARNINGS) -ifeq ($(ARCH), amd64) +ifeq ($(ARCH), x86_64) CFLAGS_COMMON += -pipe endif diff --git a/jdk/make/common/shared/Platform.gmk b/jdk/make/common/shared/Platform.gmk index 618fa0bec46..49e6cbda78e 100644 --- a/jdk/make/common/shared/Platform.gmk +++ b/jdk/make/common/shared/Platform.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2012, 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 @@ -264,7 +264,7 @@ ifeq ($(PLATFORM), macosx) echo sparc \ ;; \ x86_64) \ - echo amd64 \ + echo x86_64 \ ;; \ universal) \ echo universal \ diff --git a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java index 71e329a84e0..3b9f531c08d 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, 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 @@ -60,7 +60,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl /** * flag set if the native connect() call not to be used */ - private final static boolean connectDisabled = os.startsWith("Mac OS"); + private final static boolean connectDisabled = os.contains("OS X"); /** * Load net library into runtime. diff --git a/jdk/src/share/classes/java/nio/Bits.java b/jdk/src/share/classes/java/nio/Bits.java index 5f1eabe7336..11f2b6d0083 100644 --- a/jdk/src/share/classes/java/nio/Bits.java +++ b/jdk/src/share/classes/java/nio/Bits.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012, 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 @@ -609,7 +609,7 @@ class Bits { // package-private String arch = AccessController.doPrivileged( new sun.security.action.GetPropertyAction("os.arch")); unaligned = arch.equals("i386") || arch.equals("x86") - || arch.equals("amd64"); + || arch.equals("amd64") || arch.equals("x86_64"); unalignedKnown = true; return unaligned; } diff --git a/jdk/src/share/classes/java/util/prefs/Preferences.java b/jdk/src/share/classes/java/util/prefs/Preferences.java index 391439cbfa1..781b95ae446 100644 --- a/jdk/src/share/classes/java/util/prefs/Preferences.java +++ b/jdk/src/share/classes/java/util/prefs/Preferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012, 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 @@ -293,7 +293,7 @@ public abstract class Preferences { String platformFactory; if (osName.startsWith("Windows")) { platformFactory = "java.util.prefs.WindowsPreferencesFactory"; - } else if (osName.startsWith("Mac OS X")) { + } else if (osName.contains("OS X")) { platformFactory = "java.util.prefs.MacOSXPreferencesFactory"; } else { platformFactory = "java.util.prefs.FileSystemPreferencesFactory"; diff --git a/jdk/src/share/classes/sun/awt/OSInfo.java b/jdk/src/share/classes/sun/awt/OSInfo.java index 58dd6cc1fd0..4a515a1734c 100644 --- a/jdk/src/share/classes/sun/awt/OSInfo.java +++ b/jdk/src/share/classes/sun/awt/OSInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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 @@ -101,7 +101,7 @@ public class OSInfo { return SOLARIS; } - if (osName.startsWith("Mac OS X")) { + if (osName.contains("OS X")) { return MACOSX; } diff --git a/jdk/src/share/classes/sun/font/FontUtilities.java b/jdk/src/share/classes/sun/font/FontUtilities.java index fd1adcc9c98..2284c11714a 100644 --- a/jdk/src/share/classes/sun/font/FontUtilities.java +++ b/jdk/src/share/classes/sun/font/FontUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012, 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 @@ -78,7 +78,7 @@ public final class FontUtilities { isLinux = osName.startsWith("Linux"); - isMacOSX = osName.startsWith("Mac OS X"); // TODO: MacOSX + isMacOSX = osName.contains("OS X"); // TODO: MacOSX String t2kStr = System.getProperty("sun.java2d.font.scaler"); if (t2kStr != null) { diff --git a/jdk/src/share/classes/sun/launcher/LauncherHelper.java b/jdk/src/share/classes/sun/launcher/LauncherHelper.java index 233704c3b01..06c64f8ed50 100644 --- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java +++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2012, 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 @@ -381,7 +381,7 @@ public enum LauncherHelper { PrintStream ostream = (printToStderr) ? System.err : System.out; ostream.println(getLocalizedMessage("java.launcher.X.usage", File.pathSeparator)); - if (System.getProperty("os.name").startsWith("Mac OS")) { + if (System.getProperty("os.name").contains("OS X")) { ostream.println(getLocalizedMessage("java.launcher.X.macosx.usage", File.pathSeparator)); } diff --git a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java index ebf55b206ce..299db8fd7c4 100644 --- a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java +++ b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012, 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 @@ -1280,7 +1280,7 @@ public class ExtendedCharsets String osName = AccessController.doPrivileged( new GetPropertyAction("os.name")); if ("SunOS".equals(osName) || "Linux".equals(osName) - || osName.startsWith("Mac OS")) { + || osName.contains("OS X")) { charset("x-COMPOUND_TEXT", "COMPOUND_TEXT", new String[] { "COMPOUND_TEXT", // JDK historical diff --git a/jdk/src/share/classes/sun/print/PSPrinterJob.java b/jdk/src/share/classes/sun/print/PSPrinterJob.java index 49584f2f8a2..99f88f356c4 100644 --- a/jdk/src/share/classes/sun/print/PSPrinterJob.java +++ b/jdk/src/share/classes/sun/print/PSPrinterJob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, 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 @@ -1567,7 +1567,7 @@ public class PSPrinterJob extends RasterPrinterJob { } String osname = System.getProperty("os.name"); - if (osname.equals("Linux") || osname.startsWith("Mac OS X")) { + if (osname.equals("Linux") || osname.contains("OS X")) { execCmd = new String[ncomps]; execCmd[n++] = "/usr/bin/lpr"; if ((pFlags & PRINTER) != 0) { diff --git a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java index a6280121420..1c869ade651 100644 --- a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java +++ b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, 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 @@ -90,7 +90,7 @@ public final class SunNativeProvider extends Provider { "libgssapi_krb5.so", "libgssapi_krb5.so.2", }; - } else if (osname.startsWith("Mac OS X")) { + } else if (osname.contains("OS X")) { gssLibs = new String[]{ "/usr/lib/sasl2/libgssapiv2.2.so", }; diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java index 8c0cc628029..61a3c7c129f 100644 --- a/jdk/src/share/classes/sun/security/krb5/Config.java +++ b/jdk/src/share/classes/sun/security/krb5/Config.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012, 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 @@ -737,7 +737,7 @@ public class Config { } } else if (osname.startsWith("SunOS")) { name = "/etc/krb5/krb5.conf"; - } else if (osname.startsWith("Mac")) { + } else if (osname.contains("OS X")) { if (isMacosLionOrBetter()) return ""; name = findMacosConfigFile(); } else { diff --git a/jdk/src/share/classes/sun/security/krb5/Credentials.java b/jdk/src/share/classes/sun/security/krb5/Credentials.java index 3414e2f6e72..1451910c5cf 100644 --- a/jdk/src/share/classes/sun/security/krb5/Credentials.java +++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012, 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 @@ -289,7 +289,7 @@ public class Credentials { String os = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("os.name")); if (os.toUpperCase(Locale.ENGLISH).startsWith("WINDOWS") || - os.toUpperCase(Locale.ENGLISH).startsWith("MAC")) { + os.toUpperCase(Locale.ENGLISH).contains("OS X")) { Credentials creds = acquireDefaultCreds(); if (creds == null) { if (DEBUG) { @@ -478,7 +478,7 @@ public class Credentials { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction () { public Void run() { - if (System.getProperty("os.name").startsWith("Mac")) { + if (System.getProperty("os.name").contains("OS X")) { System.loadLibrary("osxkrb5"); } else { System.loadLibrary("w2k_lsa_auth"); diff --git a/jdk/src/share/classes/sun/security/provider/ByteArrayAccess.java b/jdk/src/share/classes/sun/security/provider/ByteArrayAccess.java index 5b6f8bfaa93..1c7641372ab 100644 --- a/jdk/src/share/classes/sun/security/provider/ByteArrayAccess.java +++ b/jdk/src/share/classes/sun/security/provider/ByteArrayAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012, 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 @@ -95,7 +95,8 @@ final class ByteArrayAccess { private static boolean unaligned() { String arch = java.security.AccessController.doPrivileged (new sun.security.action.GetPropertyAction("os.arch", "")); - return arch.equals("i386") || arch.equals("x86") || arch.equals("amd64"); + return arch.equals("i386") || arch.equals("x86") || arch.equals("amd64") + || arch.equals("x86_64"); } /** diff --git a/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java b/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java index 9767c7ced9a..3efecaacac9 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java +++ b/jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ public class DefaultAsynchronousChannelProvider { return new SolarisAsynchronousChannelProvider(); if (osname.equals("Linux")) return new LinuxAsynchronousChannelProvider(); - if (osname.startsWith("Mac OS")) + if (osname.contains("OS X")) return new BsdAsynchronousChannelProvider(); throw new InternalError("platform not recognized"); } diff --git a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java index 2605e1d6d44..9f8d479831e 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java +++ b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012, 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 @@ -68,7 +68,7 @@ public class DefaultFileSystemProvider { return createProvider("sun.nio.fs.SolarisFileSystemProvider"); if (osname.equals("Linux")) return createProvider("sun.nio.fs.LinuxFileSystemProvider"); - if (osname.equals("Darwin") || osname.startsWith("Mac OS X")) + if (osname.equals("Darwin") || osname.contains("OS X")) return createProvider("sun.nio.fs.BsdFileSystemProvider"); throw new AssertionError("Platform not recognized"); } diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java index c1de9bc1849..7f402865d2b 100644 --- a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java +++ b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,7 +120,7 @@ public class UnixPrintServiceLookup extends PrintServiceLookup static boolean isBSD() { return (osname.equals("Linux") || - osname.startsWith("Mac OS X")); + osname.contains("OS X")); } static final int UNINITIALIZED = -1; diff --git a/jdk/test/demo/jvmti/DemoRun.java b/jdk/test/demo/jvmti/DemoRun.java index 9038507df90..9a0ec96f20f 100644 --- a/jdk/test/demo/jvmti/DemoRun.java +++ b/jdk/test/demo/jvmti/DemoRun.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012, 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 @@ -124,7 +124,7 @@ public class DemoRun { String os_name = System.getProperty("os.name"); String libprefix = os_name.contains("Windows")?"":"lib"; String libsuffix = os_name.contains("Windows")?".dll": - os_name.startsWith("Mac OS")?".dylib":".so"; + os_name.contains("OS X")?".dylib":".so"; boolean d64 = ( os_name.contains("Solaris") || os_name.contains("SunOS") ) && ( os_arch.equals("sparcv9") || diff --git a/jdk/test/java/io/File/GetXSpace.java b/jdk/test/java/io/File/GetXSpace.java index 9276ef5a55c..e9aed50bbed 100644 --- a/jdk/test/java/io/File/GetXSpace.java +++ b/jdk/test/java/io/File/GetXSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ public class GetXSpace { private static final String dfFormat; static { if (name.equals("SunOS") || name.equals("Linux") - || name.startsWith("Mac OS")) { + || name.contains("OS X")) { // FileSystem Total Used Available Use% MountedOn dfFormat = "([^\\s]+)\\s+(\\d+)\\s+\\d+\\s+(\\d+)\\s+\\d+%\\s+([^\\s]+)"; } else if (name.startsWith("Windows")) { diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index 4397c2ce8ff..b3aa3087495 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -597,7 +597,7 @@ public class Basic { static class MacOSX { public static boolean is() { return is; } private static final String osName = System.getProperty("os.name"); - private static final boolean is = osName.startsWith("Mac OS"); + private static final boolean is = osName.contains("OS X"); } static class True { diff --git a/jdk/test/java/lang/ProcessBuilder/Zombies.java b/jdk/test/java/lang/ProcessBuilder/Zombies.java index 210d831667a..f8c3b627dd8 100644 --- a/jdk/test/java/lang/ProcessBuilder/Zombies.java +++ b/jdk/test/java/lang/ProcessBuilder/Zombies.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ public class Zombies { static final String os = System.getProperty("os.name"); - static final String TrueCommand = os.startsWith("Mac OS")? + static final String TrueCommand = os.contains("OS X")? "/usr/bin/true" : "/bin/true"; public static void main(String[] args) throws Throwable { diff --git a/jdk/test/java/lang/invoke/InvokeGenericTest.java b/jdk/test/java/lang/invoke/InvokeGenericTest.java index b95a5d34f8a..b54ec5ec472 100644 --- a/jdk/test/java/lang/invoke/InvokeGenericTest.java +++ b/jdk/test/java/lang/invoke/InvokeGenericTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012, 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 @@ -76,7 +76,7 @@ public class InvokeGenericTest { String name = properties.getProperty("java.vm.name"); String arch = properties.getProperty("os.arch"); if ((arch.equals("amd64") || arch.equals("i386") || arch.equals("x86") || - arch.equals("sparc") || arch.equals("sparcv9")) && + arch.equals("x86_64") || arch.equals("sparc") || arch.equals("sparcv9")) && (name.contains("Client") || name.contains("Server")) ) { platformOK = true; diff --git a/jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java b/jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java index 882c9b32124..6018befc589 100644 --- a/jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java +++ b/jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, 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,7 +80,7 @@ public class GetSystemLoadAverage { } private static String LOAD_AVERAGE_TEXT - = System.getProperty("os.name").startsWith("Mac OS") + = System.getProperty("os.name").contains("OS X") ? "load averages:" : "load average:"; @@ -99,7 +99,7 @@ public class GetSystemLoadAverage { System.out.println("Load average returned from uptime = " + output); System.out.println("getSystemLoadAverage() returned " + loadavg); - String[] lavg = System.getProperty("os.name").startsWith("Mac OS") + String[] lavg = System.getProperty("os.name").contains("OS X") ? output.split(" ") : output.split(","); double expected = Double.parseDouble(lavg[0]); diff --git a/jdk/test/java/nio/channels/FileChannel/Size.java b/jdk/test/java/nio/channels/FileChannel/Size.java index ffa0720b9fd..d17ed6b70f4 100644 --- a/jdk/test/java/nio/channels/FileChannel/Size.java +++ b/jdk/test/java/nio/channels/FileChannel/Size.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012, 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 @@ -69,7 +69,7 @@ public class Size { // Windows and Linux can't handle the really large file sizes for a truncate // or a positional write required by the test for 4563125 String osName = System.getProperty("os.name"); - if (osName.startsWith("SunOS") || osName.startsWith("Mac OS")) { + if (osName.startsWith("SunOS") || osName.contains("OS X")) { blah = File.createTempFile("blah", null); long testSize = ((long)Integer.MAX_VALUE) * 2; initTestFile(blah, 10); diff --git a/jdk/test/java/nio/channels/FileChannel/Transfer.java b/jdk/test/java/nio/channels/FileChannel/Transfer.java index 0e18f54d726..e9524be7b5f 100644 --- a/jdk/test/java/nio/channels/FileChannel/Transfer.java +++ b/jdk/test/java/nio/channels/FileChannel/Transfer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -228,7 +228,7 @@ public class Transfer { // Windows and Linux can't handle the really large file sizes for a // truncate or a positional write required by the test for 4563125 String osName = System.getProperty("os.name"); - if (!(osName.startsWith("SunOS") || osName.startsWith("Mac OS"))) + if (!(osName.startsWith("SunOS") || osName.contains("OS X"))) return; File source = File.createTempFile("blah", null); source.deleteOnExit(); diff --git a/jdk/test/java/nio/file/FileSystem/Basic.java b/jdk/test/java/nio/file/FileSystem/Basic.java index a2ff3bf3587..89903611b4f 100644 --- a/jdk/test/java/nio/file/FileSystem/Basic.java +++ b/jdk/test/java/nio/file/FileSystem/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012, 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 @@ -76,7 +76,7 @@ public class Basic { checkSupported(fs, "posix", "unix", "owner", "acl", "user"); if (os.equals("Linux")) checkSupported(fs, "posix", "unix", "owner", "dos", "user"); - if (os.startsWith("Mac OS")) + if (os.contains("OS X")) checkSupported(fs, "posix", "unix", "owner"); if (os.equals("Windows")) checkSupported(fs, "owner", "dos", "acl", "user"); diff --git a/jdk/test/sun/nio/ch/SelProvider.java b/jdk/test/sun/nio/ch/SelProvider.java index cae745f5b78..d0682b6f288 100644 --- a/jdk/test/sun/nio/ch/SelProvider.java +++ b/jdk/test/sun/nio/ch/SelProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ public class SelProvider { expected = "sun.nio.ch.DevPollSelectorProvider"; } else if ("Linux".equals(osname)) { expected = "sun.nio.ch.EPollSelectorProvider"; - } else if (osname.startsWith("Mac OS")) { + } else if (osname.contains("OS X")) { expected = "sun.nio.ch.KQueueSelectorProvider"; } else return; diff --git a/jdk/test/tools/launcher/TestHelper.java b/jdk/test/tools/launcher/TestHelper.java index 445efcec3a6..e0e50c92466 100644 --- a/jdk/test/tools/launcher/TestHelper.java +++ b/jdk/test/tools/launcher/TestHelper.java @@ -66,7 +66,7 @@ public class TestHelper { static final boolean isWindows = System.getProperty("os.name", "unknown").startsWith("Windows"); static final boolean isMacOSX = - System.getProperty("os.name", "unknown").startsWith("Mac"); + System.getProperty("os.name", "unknown").contains("OS X"); static final boolean is64Bit = System.getProperty("sun.arch.data.model").equals("64"); static final boolean is32Bit = From 5befb6f577d7f2127534e74d89308ea1ab4db938 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Thu, 19 Apr 2012 14:05:07 +0100 Subject: [PATCH 05/51] 7162262: (fs) Typo in java.nio.file.Path class description Reviewed-by: alanb --- jdk/src/share/classes/java/nio/file/Path.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/nio/file/Path.java b/jdk/src/share/classes/java/nio/file/Path.java index 92cd1f9661e..afe07a387d6 100644 --- a/jdk/src/share/classes/java/nio/file/Path.java +++ b/jdk/src/share/classes/java/nio/file/Path.java @@ -54,7 +54,7 @@ import java.util.Iterator; * resolveSibling} methods to combine paths. The {@link #relativize relativize} * method that can be used to construct a relative path between two paths. * Paths can be {@link #compareTo compared}, and tested against each other using - * the {@link #startsWith startsWith} and {@link #endsWith endWith} methods. + * the {@link #startsWith startsWith} and {@link #endsWith endsWith} methods. * *

This interface extends {@link Watchable} interface so that a directory * located by a path can be {@link #register registered} with a {@link From a7c87287046d7a11d7b79d9339d60a7f35a0280e Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Thu, 19 Apr 2012 16:58:34 +0100 Subject: [PATCH 06/51] 7162823: Modify the list of excluded tests (ProblemList Reviewed-by: alanb --- jdk/test/ProblemList.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 1980d033038..79c53f580db 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -286,13 +286,13 @@ com/sun/org/apache/xml/internal/security/transforms/ClassLoaderTest.java generic # Failing on Solaris i586, 3/9/2010, not a -samevm issue (jdk_security3) sun/security/pkcs11/Secmod/AddPrivateKey.java solaris-i586 -sun/security/pkcs11/ec/ReadCertificates.java solaris-i586 -sun/security/pkcs11/ec/ReadPKCS12.java solaris-i586 +sun/security/pkcs11/ec/ReadCertificates.java generic-all +sun/security/pkcs11/ec/ReadPKCS12.java generic-all sun/security/pkcs11/ec/TestCurves.java solaris-i586 sun/security/pkcs11/ec/TestECDSA.java solaris-i586 #sun/security/pkcs11/ec/TestECGenSpec.java solaris-i586 #sun/security/pkcs11/ec/TestKeyFactory.java solaris-i586 -sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-i586 +sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java generic-all # Fails on Fedora 9/Ubuntu 10.04 64bit, PKCS11Exception: CKR_DEVICE_ERROR sun/security/pkcs11/KeyAgreement/TestDH.java generic-all From 4f6ca7513e4ccd7347e7f52a237962028cd5252d Mon Sep 17 00:00:00 2001 From: Kurchi Subhra Hazra Date: Thu, 19 Apr 2012 13:26:06 -0700 Subject: [PATCH 07/51] 7162385: TEST_BUG: sun/net/www/protocol/jar/B4957695.java failing again Enable finding "foo1.jar" Reviewed-by: chegar --- jdk/test/sun/net/www/protocol/jar/B4957695.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/test/sun/net/www/protocol/jar/B4957695.java b/jdk/test/sun/net/www/protocol/jar/B4957695.java index 0d25825f0cc..3ab0f0c7562 100644 --- a/jdk/test/sun/net/www/protocol/jar/B4957695.java +++ b/jdk/test/sun/net/www/protocol/jar/B4957695.java @@ -62,7 +62,8 @@ public class B4957695 { readOneRequest(s.getInputStream()); try (OutputStreamWriter ow = new OutputStreamWriter((s.getOutputStream()))) { - FileInputStream fin = new FileInputStream("foo1.jar"); + FileInputStream fin = new FileInputStream(new File( + System.getProperty("test.src", "."), "foo1.jar")); int length = fin.available(); byte[] b = new byte[length-10]; fin.read(b, 0, length-10); From 0590a1ea49c8a872ae070c88ec901234dfab224c Mon Sep 17 00:00:00 2001 From: Kurchi Subhra Hazra Date: Thu, 19 Apr 2012 18:11:28 -0700 Subject: [PATCH 08/51] 7158636: InterfaceAddress.getBroadcast() returns invalid broadcast address on WLAN Update Windows native code to infer WLAN interface type in Windows Vista and later Reviewed-by: chegar, alanb --- .../native/java/net/NetworkInterface.c | 22 ++++++++++++------- .../native/java/net/NetworkInterface.h | 5 +++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/jdk/src/windows/native/java/net/NetworkInterface.c b/jdk/src/windows/native/java/net/NetworkInterface.c index d6b04886975..8dbeb925029 100644 --- a/jdk/src/windows/native/java/net/NetworkInterface.c +++ b/jdk/src/windows/native/java/net/NetworkInterface.c @@ -178,7 +178,7 @@ int enumInterfaces(JNIEnv *env, netif **netifPP) int count; netif *netifP; DWORD i; - int lo=0, eth=0, tr=0, fddi=0, ppp=0, sl=0, net=0; + int lo=0, eth=0, tr=0, fddi=0, ppp=0, sl=0, wlan=0, net=0; /* * Ask the IP Helper library to enumerate the adapters @@ -218,15 +218,15 @@ int enumInterfaces(JNIEnv *env, netif **netifPP) */ switch (ifrowP->dwType) { case MIB_IF_TYPE_ETHERNET: - sprintf(dev_name, "eth%d", eth++); + _snprintf_s(dev_name, 8, _TRUNCATE, "eth%d", eth++); break; case MIB_IF_TYPE_TOKENRING: - sprintf(dev_name, "tr%d", tr++); + _snprintf_s(dev_name, 8, _TRUNCATE, "tr%d", tr++); break; case MIB_IF_TYPE_FDDI: - sprintf(dev_name, "fddi%d", fddi++); + _snprintf_s(dev_name, 8, _TRUNCATE, "fddi%d", fddi++); break; case MIB_IF_TYPE_LOOPBACK: @@ -234,20 +234,24 @@ int enumInterfaces(JNIEnv *env, netif **netifPP) if (lo > 0) { continue; } - strcpy(dev_name, "lo"); + strncpy_s(dev_name, 8, "lo", _TRUNCATE); lo++; break; case MIB_IF_TYPE_PPP: - sprintf(dev_name, "ppp%d", ppp++); + _snprintf_s(dev_name, 8, _TRUNCATE, "ppp%d", ppp++); break; case MIB_IF_TYPE_SLIP: - sprintf(dev_name, "sl%d", sl++); + _snprintf_s(dev_name, 8, _TRUNCATE, "sl%d", sl++); + break; + + case IF_TYPE_IEEE80211: + _snprintf_s(dev_name, 8, _TRUNCATE, "wlan%d", wlan++); break; default: - sprintf(dev_name, "net%d", net++); + _snprintf_s(dev_name, 8, _TRUNCATE, "net%d", net++); } /* @@ -382,6 +386,7 @@ int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP) case MIB_IF_TYPE_TOKENRING: case MIB_IF_TYPE_FDDI: case MIB_IF_TYPE_LOOPBACK: + case IF_TYPE_IEEE80211: /** * Contrary to what it seems to indicate, dwBCastAddr doesn't * contain the broadcast address but 0 or 1 depending on whether @@ -928,6 +933,7 @@ JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0 case MIB_IF_TYPE_ETHERNET: case MIB_IF_TYPE_TOKENRING: case MIB_IF_TYPE_FDDI: + case IF_TYPE_IEEE80211: len = ifRowP->dwPhysAddrLen; ret = (*env)->NewByteArray(env, len); if (!IS_NULL(ret)) { diff --git a/jdk/src/windows/native/java/net/NetworkInterface.h b/jdk/src/windows/native/java/net/NetworkInterface.h index 262e15a0db0..2f977fd624b 100644 --- a/jdk/src/windows/native/java/net/NetworkInterface.h +++ b/jdk/src/windows/native/java/net/NetworkInterface.h @@ -89,4 +89,9 @@ extern jfieldID ni_ibmaskID; /* InterfaceAddress.maskLength */ int enumInterfaces(JNIEnv *env, netif **netifPP); +// Windows Visa (and later) only..... +#ifndef IF_TYPE_IEEE80211 +#define IF_TYPE_IEEE80211 71 +#endif + #endif From 2f21d39ae5aff974b67c27a7bb512ad0d2a844e6 Mon Sep 17 00:00:00 2001 From: Sean Chou Date: Fri, 20 Apr 2012 10:34:40 +0800 Subject: [PATCH 09/51] 7129742: Unable to view focus in Non-Editable TextArea Make sure the cursor is visible by setVisible(true) Reviewed-by: rupashka, alexp --- .../classes/sun/awt/X11/XTextAreaPeer.java | 7 +- .../classes/sun/awt/X11/XTextFieldPeer.java | 26 +--- .../bug7129742.java | 113 ++++++++++++++++++ 3 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 jdk/test/java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java index 253fa4d1da0..5a08630acdc 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java @@ -657,10 +657,13 @@ class XTextAreaPeer extends XComponentPeer implements TextAreaPeer { } - // TODO : fix this duplicate code - class XAWTCaret extends DefaultCaret { + static class XAWTCaret extends DefaultCaret { public void focusGained(FocusEvent e) { super.focusGained(e); + if (getComponent().isEnabled()){ + // Make sure the cursor is visible in case of non-editable TextArea + super.setVisible(true); + } getComponent().repaint(); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java index 6e3b78d1498..c67a2be1f5f 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java @@ -578,31 +578,7 @@ public class XTextFieldPeer extends XComponentPeer implements TextFieldPeer { } protected Caret createCaret() { - return new XAWTCaret(); - } - } - - class XAWTCaret extends DefaultCaret { - public void focusGained(FocusEvent e) { - super.focusGained(e); - getComponent().repaint(); - } - - public void focusLost(FocusEvent e) { - super.focusLost(e); - getComponent().repaint(); - } - - // Fix for 5100950: textarea.getSelectedText() returns the de-selected text, on XToolkit - // Restoring Motif behaviour - // If the text is unhighlighted then we should sets the selection range to zero - public void setSelectionVisible(boolean vis) { - if (vis){ - super.setSelectionVisible(vis); - }else{ - // In order to de-select the selection - setDot(getDot()); - } + return new XTextAreaPeer.XAWTCaret(); } } diff --git a/jdk/test/java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java b/jdk/test/java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java new file mode 100644 index 00000000000..188cd3fde86 --- /dev/null +++ b/jdk/test/java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012 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. + */ + +/* + * Portions Copyright (c) 2012 IBM Corporation + */ + + +/* @test + * @bug 7129742 + * @summary Focus in non-editable TextArea is not shown on Linux. + * @author Sean Chou + */ + +import java.awt.FlowLayout; +import java.awt.TextArea; +import java.awt.Toolkit; +import java.lang.reflect.Field; + +import javax.swing.JFrame; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.text.DefaultCaret; + +import sun.awt.SunToolkit; + +public class bug7129742 { + + public static DefaultCaret caret = null; + public static JFrame frame = null; + public static boolean fastreturn = false; + + public static void main(String[] args) throws Exception { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + frame = new JFrame("Test"); + TextArea textArea = new TextArea("Non-editable textArea"); + textArea.setEditable(false); + frame.setLayout(new FlowLayout()); + frame.add(textArea); + frame.pack(); + frame.setVisible(true); + + try { + Class XTextAreaPeerClzz = textArea.getPeer().getClass(); + System.out.println(XTextAreaPeerClzz.getName()); + if (!XTextAreaPeerClzz.getName().equals("sun.awt.X11.XTextAreaPeer")) { + fastreturn = true; + return; + } + + Field jtextField = XTextAreaPeerClzz.getDeclaredField("jtext"); + jtextField.setAccessible(true); + JTextArea jtext = (JTextArea)jtextField.get(textArea.getPeer()); + caret = (DefaultCaret) jtext.getCaret(); + + textArea.requestFocusInWindow(); + } catch (NoSuchFieldException | SecurityException + | IllegalArgumentException | IllegalAccessException e) { + /* These exceptions mean the implementation of XTextAreaPeer is + * changed, this testcase is not valid any more, fix it or remove. + */ + frame.dispose(); + throw new RuntimeException("This testcase is not valid any more!"); + } + } + }); + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + try{ + if (fastreturn) { + return; + } + boolean passed = caret.isActive(); + System.out.println("is caret visible : " + passed); + + if (!passed) { + throw new RuntimeException("The test for bug 71297422 failed"); + } + } finally { + frame.dispose(); + } + } + }); + } + +} From 91ae75b0874b5530413cf8f2493c7b0d8194e540 Mon Sep 17 00:00:00 2001 From: Jonathan Lu Date: Fri, 20 Apr 2012 13:13:00 +0800 Subject: [PATCH 10/51] 7055065: NullPointerException when sorting JTable with empty cell Reviewed-by: rupashka --- jdk/src/share/classes/javax/swing/JTable.java | 2 +- .../swing/JTable/7055065/bug7055065.java | 178 ++++++++++++++++++ 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JTable/7055065/bug7055065.java diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index 6314cb0a207..17b6b23d135 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -5470,7 +5470,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable if (constructor.getDeclaringClass() == String.class) { value = s; } - super.stopCellEditing(); + return super.stopCellEditing(); } try { diff --git a/jdk/test/javax/swing/JTable/7055065/bug7055065.java b/jdk/test/javax/swing/JTable/7055065/bug7055065.java new file mode 100644 index 00000000000..119d9a57654 --- /dev/null +++ b/jdk/test/javax/swing/JTable/7055065/bug7055065.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2012 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. + */ + +/* + * Portions Copyright (c) 2012 IBM Corporation + */ + +/* @test 1.1 2012/04/19 + * @bug 7055065 + * @summary NullPointerException when sorting JTable with empty cell + * @author Jonathan Lu + * @library ../../regtesthelpers/ + * @build Util + * @run main bug7055065 + */ + +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; +import sun.awt.SunToolkit; +import java.util.concurrent.Callable; + +public class bug7055065 { + + private static JTable table; + + public static void main(String[] args) throws Exception { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + createAndShowUI(); + } + }); + + toolkit.realSync(); + clickCell(robot, 1, 1); + Util.hitKeys(robot, KeyEvent.VK_BACK_SPACE, KeyEvent.VK_BACK_SPACE, + KeyEvent.VK_BACK_SPACE); + + toolkit.realSync(); + clickColumnHeader(robot, 1); + + toolkit.realSync(); + clickColumnHeader(robot, 1); + } + + private static void clickCell(Robot robot, final int row, final int column) + throws Exception { + Point point = Util.invokeOnEDT(new Callable() { + @Override + public Point call() throws Exception { + Rectangle rect = table.getCellRect(row, column, false); + Point point = new Point(rect.x + rect.width / 2, rect.y + + rect.height / 2); + SwingUtilities.convertPointToScreen(point, table); + return point; + } + }); + + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + + private static void clickColumnHeader(Robot robot, final int column) + throws Exception { + Point point = Util.invokeOnEDT(new Callable() { + @Override + public Point call() throws Exception { + Rectangle rect = table.getCellRect(0, column, false); + int headerHeight = table.getTableHeader().getHeight(); + Point point = new Point(rect.x + rect.width / 2, rect.y + - headerHeight / 2); + SwingUtilities.convertPointToScreen(point, table); + return point; + } + }); + + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + + private static void createAndShowUI() { + JFrame frame = new JFrame("SimpleTableDemo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JPanel newContentPane = new JPanel(); + newContentPane.setOpaque(true); + frame.setContentPane(newContentPane); + + final String[] columnNames = { "String", "Number" }; + final Object[][] data = { { "aaaa", new Integer(1) }, + { "bbbb", new Integer(3) }, { "cccc", new Integer(2) }, + { "dddd", new Integer(4) }, { "eeee", new Integer(5) } }; + table = new JTable(data, columnNames); + + table.setPreferredScrollableViewportSize(new Dimension(500, 400)); + table.setFillsViewportHeight(true); + + TableModel dataModel = new AbstractTableModel() { + + public int getColumnCount() { + return columnNames.length; + } + + public int getRowCount() { + return data.length; + } + + public Object getValueAt(int row, int col) { + return data[row][col]; + } + + public String getColumnName(int column) { + return columnNames[column]; + } + + public Class getColumnClass(int c) { + return getValueAt(0, c).getClass(); + } + + public boolean isCellEditable(int row, int col) { + return col != 5; + } + + public void setValueAt(Object aValue, int row, int column) { + data[row][column] = aValue; + } + }; + table.setModel(dataModel); + TableRowSorter sorter = new TableRowSorter( + dataModel); + table.setRowSorter(sorter); + + JScrollPane scrollPane = new JScrollPane(table); + newContentPane.add(scrollPane); + + frame.pack(); + frame.setLocation(0, 0); + frame.setVisible(true); + } +} From c354b234a4f6980320b773859b4187921bd8fa9c Mon Sep 17 00:00:00 2001 From: Sean Chou Date: Fri, 20 Apr 2012 16:11:28 +0800 Subject: [PATCH 11/51] 7159982: ZipFile uses static for error message when malformed zip file encountered Reviewed-by: alanb, dholmes --- jdk/src/share/native/java/util/zip/ZipFile.c | 1 + jdk/src/share/native/java/util/zip/zip_util.c | 31 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/jdk/src/share/native/java/util/zip/ZipFile.c b/jdk/src/share/native/java/util/zip/ZipFile.c index 99d6d229f89..281dbc628fa 100644 --- a/jdk/src/share/native/java/util/zip/ZipFile.c +++ b/jdk/src/share/native/java/util/zip/ZipFile.c @@ -117,6 +117,7 @@ Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name, result = ptr_to_jlong(zip); } else if (msg != 0) { ThrowZipException(env, msg); + free(msg); } else if (errno == ENOMEM) { JNU_ThrowOutOfMemoryError(env, 0); } else { diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c index 991ed5c0123..9bffd3461e5 100644 --- a/jdk/src/share/native/java/util/zip/zip_util.c +++ b/jdk/src/share/native/java/util/zip/zip_util.c @@ -726,7 +726,7 @@ readCEN(jzfile *zip, jint knownTotal) * Opens a zip file with the specified mode. Returns the jzfile object * or NULL if an error occurred. If a zip error occurred then *pmsg will * be set to the error message text if pmsg != 0. Otherwise, *pmsg will be - * set to NULL. + * set to NULL. Caller is responsible to free the error message. */ jzfile * ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified) @@ -751,12 +751,12 @@ ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified) * Returns the jzfile corresponding to the given file name from the cache of * zip files, or NULL if the file is not in the cache. If the name is longer * than PATH_MAX or a zip error occurred then *pmsg will be set to the error - * message text if pmsg != 0. Otherwise, *pmsg will be set to NULL. + * message text if pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller + * is responsible to free the error message. */ jzfile * ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified) { - static char errbuf[256]; char buf[PATH_MAX]; jzfile *zip; @@ -771,7 +771,7 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified) if (strlen(name) >= PATH_MAX) { if (pmsg) { - *pmsg = "zip file name too long"; + *pmsg = strdup("zip file name too long"); } return NULL; } @@ -796,7 +796,8 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified) * Reads data from the given file descriptor to create a jzfile, puts the * jzfile in a cache, and returns that jzfile. Returns NULL in case of error. * If a zip error occurs, then *pmsg will be set to the error message text if - * pmsg != 0. Otherwise, *pmsg will be set to NULL. + * pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller is responsible to + * free the error message. */ jzfile * @@ -809,7 +810,7 @@ jzfile * ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, jboolean usemmap) { - static char errbuf[256]; + char errbuf[256]; jlong len; jzfile *zip; @@ -825,7 +826,7 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, if (zfd == -1) { if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0) - *pmsg = errbuf; + *pmsg = strdup(errbuf); freeZip(zip); return NULL; } @@ -834,11 +835,11 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, if (len <= 0) { if (len == 0) { /* zip file is empty */ if (pmsg) { - *pmsg = "zip file is empty"; + *pmsg = strdup("zip file is empty"); } } else { /* error */ if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0) - *pmsg = errbuf; + *pmsg = strdup(errbuf); } ZFILE_Close(zfd); freeZip(zip); @@ -850,7 +851,8 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, /* An error occurred while trying to read the zip file */ if (pmsg != 0) { /* Set the zip error message */ - *pmsg = zip->msg; + if (zip->msg != NULL) + *pmsg = strdup(zip->msg); } freeZip(zip); return NULL; @@ -867,12 +869,17 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, * Opens a zip file for reading. Returns the jzfile object or NULL * if an error occurred. If a zip error occurred then *msg will be * set to the error message text if msg != 0. Otherwise, *msg will be - * set to NULL. + * set to NULL. Caller doesn't need to free the error message. */ jzfile * JNICALL ZIP_Open(const char *name, char **pmsg) { - return ZIP_Open_Generic(name, pmsg, O_RDONLY, 0); + jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0); + if (file == NULL && pmsg != NULL && *pmsg != NULL) { + free(*pmsg); + *pmsg = "Zip file open error"; + } + return file; } /* From 7e36bafdcdbd10babf52b9deb33007a58092490d Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 20 Apr 2012 14:55:45 +0100 Subject: [PATCH 12/51] 7162488: VM not printing unknown -XX options Reviewed-by: dholmes, kamg --- hotspot/src/share/vm/runtime/arguments.cpp | 3 + hotspot/test/runtime/7162488/Test7162488.sh | 77 +++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 hotspot/test/runtime/7162488/Test7162488.sh diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 69f6edaee42..8deacc6f564 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -829,6 +829,9 @@ bool Arguments::process_argument(const char* arg, } else { jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf); } + } else { + jio_fprintf(defaultStream::error_stream(), + "Unrecognized VM option '%s'\n", argname); } // allow for commandline "commenting out" options like -XX:#+Verbose diff --git a/hotspot/test/runtime/7162488/Test7162488.sh b/hotspot/test/runtime/7162488/Test7162488.sh new file mode 100644 index 00000000000..bd70d027d46 --- /dev/null +++ b/hotspot/test/runtime/7162488/Test7162488.sh @@ -0,0 +1,77 @@ +# +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + + +# @test Test7162488.sh +# @bug 7162488 +# @summary VM not printing unknown -XX options +# @run shell Test7162488.sh +# + +if [ "${TESTSRC}" = "" ] + then TESTSRC=. +fi + +if [ "${TESTJAVA}" = "" ] +then + PARENT=`dirname \`which java\`` + TESTJAVA=`dirname ${PARENT}` + printf "TESTJAVA not set, selecting " ${TESTJAVA} + printf " If this is incorrect, try setting the variable manually.\n" +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +JAVA=${TESTJAVA}${FS}bin${FS}java + +# +# Just run with an option we are confident will not be recognized, +# and check for the message: +# +OPTION=this_is_not_an_option + +${JAVA} ${TESTVMOPTS} -showversion -XX:${OPTION} 2>&1 | grep "Unrecognized VM option" +if [ "$?" != "0" ] +then + printf "FAILED: option not flagged as unrecognized.\n" + exit 1 +fi + +${JAVA} ${TESTVMOPTS} -showversion -XX:${OPTION} 2>&1 | grep ${OPTION} +if [ "$?" != "0" ] +then + printf "FAILED: bad option not named as being bad.\n" + exit 1 +fi + +printf "Passed.\n" + From 6de80de07f466c695bf5a7f526cfa635fb612693 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 20 Apr 2012 17:13:36 -0700 Subject: [PATCH 13/51] 7163193: new hotspot build - hs24-b09 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index 00601747489..3f3c7dc92ca 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011 HS_MAJOR_VER=24 HS_MINOR_VER=0 -HS_BUILD_NUMBER=08 +HS_BUILD_NUMBER=09 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From b0c273a9b8b56c432c64a16eb2d3f38c58c7df7a Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Sun, 22 Apr 2012 06:54:38 -0700 Subject: [PATCH 14/51] 6981776: Pack200 must support -target 7 bytecodes Pack200 implementation of JSR-200 updated for JSR-292 changes Co-authored-by: John Rose Reviewed-by: jrose, ksrini --- .../com/sun/java/util/jar/pack/Attribute.java | 46 +- .../sun/java/util/jar/pack/BandStructure.java | 67 +- .../sun/java/util/jar/pack/ClassReader.java | 129 +- .../sun/java/util/jar/pack/ClassWriter.java | 49 +- .../sun/java/util/jar/pack/ConstantPool.java | 512 ++++- .../com/sun/java/util/jar/pack/Constants.java | 49 +- .../sun/java/util/jar/pack/Instruction.java | 18 +- .../com/sun/java/util/jar/pack/Package.java | 57 +- .../sun/java/util/jar/pack/PackageReader.java | 180 +- .../sun/java/util/jar/pack/PackageWriter.java | 158 +- .../com/sun/java/util/jar/pack/TLGlobals.java | 30 +- .../com/sun/java/util/jar/pack/Utils.java | 43 +- .../com/sun/java/util/jar/pack/bands.cpp | 33 +- .../native/com/sun/java/util/jar/pack/bands.h | 24 +- .../com/sun/java/util/jar/pack/constants.h | 130 +- .../com/sun/java/util/jar/pack/defines.h | 5 +- .../com/sun/java/util/jar/pack/unpack.cpp | 606 ++++-- .../com/sun/java/util/jar/pack/unpack.h | 41 +- jdk/test/tools/pack200/AttributeTests.java | 36 +- .../tools/pack200/PackageVersionTest.java | 10 +- jdk/test/tools/pack200/Utils.java | 14 +- jdk/test/tools/pack200/dyn.jar | Bin 1963 -> 0 bytes .../pack200/pack200-verifier/data/README | 21 +- .../pack200/pack200-verifier/data/golden.jar | Bin 418156 -> 423427 bytes .../pack200/pack200-verifier/make/build.xml | 6 +- .../src/xmlkit/ClassReader.java | 1866 +++++++++++------ .../src/xmlkit/ClassSyntax.java | 518 ----- .../src/xmlkit/ClassWriter.java | 818 -------- .../src/xmlkit/InstructionAssembler.java | 464 ---- .../src/xmlkit/InstructionSyntax.java | 483 ----- 30 files changed, 2928 insertions(+), 3485 deletions(-) delete mode 100644 jdk/test/tools/pack200/dyn.jar delete mode 100644 jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassSyntax.java delete mode 100644 jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassWriter.java delete mode 100644 jdk/test/tools/pack200/pack200-verifier/src/xmlkit/InstructionAssembler.java delete mode 100644 jdk/test/tools/pack200/pack200-verifier/src/xmlkit/InstructionSyntax.java diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java index 164870e4a82..5cf2456bdf1 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -166,6 +166,7 @@ class Attribute implements Comparable { define(sd, ATTR_CONTEXT_CLASS, "SourceFile", "RUH"); define(sd, ATTR_CONTEXT_CLASS, "EnclosingMethod", "RCHRDNH"); define(sd, ATTR_CONTEXT_CLASS, "InnerClasses", "NH[RCHRCNHRUNHFH]"); + define(sd, ATTR_CONTEXT_CLASS, "BootstrapMethods", "NH[RMHNH[KLH]]"); define(sd, ATTR_CONTEXT_FIELD, "Signature", "RSH"); define(sd, ATTR_CONTEXT_FIELD, "Synthetic", ""); @@ -203,6 +204,8 @@ class Attribute implements Comparable { // Their layout specs. are given here for completeness. // The Code spec is incomplete, in that it does not distinguish // bytecode bytes or locate CP references. + // The BootstrapMethods attribute is also special-cased + // elsewhere as an appendix to the local constant pool. } // Metadata. @@ -822,9 +825,9 @@ class Attribute implements Comparable { reference_type: ( constant_ref | schema_ref | utf8_ref | untyped_ref ) constant_ref: - ( 'KI' | 'KJ' | 'KF' | 'KD' | 'KS' | 'KQ' ) + ( 'KI' | 'KJ' | 'KF' | 'KD' | 'KS' | 'KQ' | 'KM' | 'KT' | 'KL' ) schema_ref: - ( 'RC' | 'RS' | 'RD' | 'RF' | 'RM' | 'RI' ) + ( 'RC' | 'RS' | 'RD' | 'RF' | 'RM' | 'RI' | 'RY' | 'RB' | 'RN' ) utf8_ref: 'RU' untyped_ref: @@ -1012,7 +1015,12 @@ class Attribute implements Comparable { case 'F': e.refKind = CONSTANT_Float; break; case 'D': e.refKind = CONSTANT_Double; break; case 'S': e.refKind = CONSTANT_String; break; - case 'Q': e.refKind = CONSTANT_Literal; break; + case 'Q': e.refKind = CONSTANT_FieldSpecific; break; + + // new in 1.7: + case 'M': e.refKind = CONSTANT_MethodHandle; break; + case 'T': e.refKind = CONSTANT_MethodType; break; + case 'L': e.refKind = CONSTANT_LoadableValue; break; default: { i = -i; continue; } // fail } break; @@ -1029,6 +1037,11 @@ class Attribute implements Comparable { case 'U': e.refKind = CONSTANT_Utf8; break; //utf8_ref case 'Q': e.refKind = CONSTANT_All; break; //untyped_ref + // new in 1.7: + case 'Y': e.refKind = CONSTANT_InvokeDynamic; break; + case 'B': e.refKind = CONSTANT_BootstrapMethod; break; + case 'N': e.refKind = CONSTANT_AnyMember; break; + default: { i = -i; continue; } // fail } break; @@ -1279,10 +1292,12 @@ class Attribute implements Comparable { // Cf. ClassReader.readSignatureRef. String typeName = globalRef.stringValue(); globalRef = ConstantPool.getSignatureEntry(typeName); - } else if (e.refKind == CONSTANT_Literal) { + } else if (e.refKind == CONSTANT_FieldSpecific) { assert(globalRef.getTag() >= CONSTANT_Integer); - assert(globalRef.getTag() <= CONSTANT_String); - } else if (e.refKind != CONSTANT_All) { + assert(globalRef.getTag() <= CONSTANT_String || + globalRef.getTag() >= CONSTANT_MethodHandle); + assert(globalRef.getTag() <= CONSTANT_MethodType); + } else if (e.refKind < CONSTANT_GroupFirst) { assert(e.refKind == globalRef.getTag()); } } @@ -1462,27 +1477,29 @@ class Attribute implements Comparable { "NH[PHPOHIIH]", // CharacterRangeTable "NH[PHHII]", // CoverageTable "NH[RCHRCNHRUNHFH]", // InnerClasses + "NH[RMHNH[KLH]]", // BootstrapMethods "HHNI[B]NH[PHPOHPOHRCNH]NH[RUHNI[B]]", // Code "=AnnotationDefault", // Like metadata, but with a compact tag set: "[NH[(1)]]" - +"[NH[(2)]]" - +"[RSHNH[RUH(3)]]" - +"[TB(0,1,3)[KIH](2)[KDH](5)[KFH](4)[KJH](7)[RSH](8)[RSHRUH](9)[RUH](10)[(2)](6)[NH[(3)]]()[]]", + +"[NH[(1)]]" + +"[RSHNH[RUH(1)]]" + +"[TB(0,1,3)[KIH](2)[KDH](5)[KFH](4)[KJH](7)[RSH](8)[RSHRUH](9)[RUH](10)[(-1)](6)[NH[(0)]]()[]]", "" }; ap = 0; } + Utils.currentInstance.set(new PackerImpl()); final int[][] counts = new int[2][3]; // int bci ref final Entry[] cpMap = new Entry[maxVal+1]; for (int i = 0; i < cpMap.length; i++) { if (i == 0) continue; // 0 => null cpMap[i] = ConstantPool.getLiteralEntry(new Integer(i)); } - Class cls = new Package().new Class(""); + Package.Class cls = new Package().new Class(""); cls.cpMap = cpMap; class TestValueStream extends ValueStream { - Random rand = new Random(0); + java.util.Random rand = new java.util.Random(0); ArrayList history = new ArrayList(); int ckidx = 0; int maxVal; @@ -1570,8 +1587,7 @@ class Attribute implements Comparable { String layout = av[i]; if (layout.startsWith("=")) { String name = layout.substring(1); - for (Iterator j = standardDefs.values().iterator(); j.hasNext(); ) { - Attribute a = (Attribute) j.next(); + for (Attribute a : standardDefs.values()) { if (a.name().equals(name)) { layout = a.layout().layout(); break; @@ -1604,7 +1620,7 @@ class Attribute implements Comparable { if (verbose) { System.out.print(" parse: {"); } - self.parse(0, cls, bytes, 0, bytes.length, tts); + self.parse(cls, bytes, 0, bytes.length, tts); if (verbose) { System.out.println("}"); } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java index 8d472b9bdd4..a63491b9a34 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -1372,17 +1372,17 @@ class BandStructure { protected long archiveSize1; // size reported in archive_header protected int archiveNextCount; // reported in archive_header - static final int AH_LENGTH_0 = 3; //minver, majver, options - static final int AH_ARCHIVE_SIZE_HI = 0; - static final int AH_ARCHIVE_SIZE_LO = 1; - static final int AH_LENGTH_S = 2; //optional size hi/lo - static final int AH_LENGTH = 26; // mentioned in spec + static final int AH_LENGTH_0 = 3; // archive_header_0 = {minver, majver, options} + static final int AH_LENGTH_MIN = 15; // observed in spec {header_0[3], cp_counts[8], class_counts[4]} + // Length contributions from optional archive size fields: + static final int AH_LENGTH_S = 2; // archive_header_S = optional {size_hi, size_lo} + static final int AH_ARCHIVE_SIZE_HI = 0; // offset in archive_header_S + static final int AH_ARCHIVE_SIZE_LO = 1; // offset in archive_header_S // Length contributions from optional header fields: - static final int AH_FILE_HEADER_LEN = 5; // sizehi/lo/next/modtime/files - static final int AH_SPECIAL_FORMAT_LEN = 2; // layouts/band-headers - static final int AH_CP_NUMBER_LEN = 4; // int/float/long/double - static final int AH_LENGTH_MIN = AH_LENGTH - -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN); + static final int AH_FILE_HEADER_LEN = 5; // file_counts = {{size_hi, size_lo}, next, modtime, files} + static final int AH_SPECIAL_FORMAT_LEN = 2; // special_counts = {layouts, band_headers} + static final int AH_CP_NUMBER_LEN = 4; // cp_number_counts = {int, float, long, double} + static final int AH_CP_EXTRA_LEN = 4; // cp_attr_counts = {MH, MT, InDy, BSM} // Common structure of attribute band groups: static final int AB_FLAGS_HI = 0; @@ -1446,6 +1446,14 @@ class BandStructure { CPRefBand cp_Method_desc = cp_bands.newCPRefBand("cp_Method_desc", UDELTA5, CONSTANT_NameandType); CPRefBand cp_Imethod_class = cp_bands.newCPRefBand("cp_Imethod_class", CONSTANT_Class); CPRefBand cp_Imethod_desc = cp_bands.newCPRefBand("cp_Imethod_desc", UDELTA5, CONSTANT_NameandType); + IntBand cp_MethodHandle_refkind = cp_bands.newIntBand("cp_MethodHandle_refkind", DELTA5); + CPRefBand cp_MethodHandle_member = cp_bands.newCPRefBand("cp_MethodHandle_member", UDELTA5, CONSTANT_AnyMember); + CPRefBand cp_MethodType = cp_bands.newCPRefBand("cp_MethodType", UDELTA5, CONSTANT_Signature); + CPRefBand cp_BootstrapMethod_ref = cp_bands.newCPRefBand("cp_BootstrapMethod_ref", DELTA5, CONSTANT_MethodHandle); + IntBand cp_BootstrapMethod_arg_count = cp_bands.newIntBand("cp_BootstrapMethod_arg_count", UDELTA5); + CPRefBand cp_BootstrapMethod_arg = cp_bands.newCPRefBand("cp_BootstrapMethod_arg", DELTA5, CONSTANT_LoadableValue); + CPRefBand cp_InvokeDynamic_spec = cp_bands.newCPRefBand("cp_InvokeDynamic_spec", DELTA5, CONSTANT_BootstrapMethod); + CPRefBand cp_InvokeDynamic_desc = cp_bands.newCPRefBand("cp_InvokeDynamic_desc", UDELTA5, CONSTANT_NameandType); // bands for carrying attribute definitions: MultiBand attr_definition_bands = all_bands.newMultiBand("(attr_definition_bands)", UNSIGNED5); @@ -1481,7 +1489,7 @@ class BandStructure { IntBand field_attr_calls = field_attr_bands.newIntBand("field_attr_calls"); // bands for predefined field attributes - CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_Literal); + CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_FieldSpecific); CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature); MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5); @@ -1585,12 +1593,14 @@ class BandStructure { CPRefBand bc_longref = bc_bands.newCPRefBand("bc_longref", DELTA5, CONSTANT_Long); CPRefBand bc_doubleref = bc_bands.newCPRefBand("bc_doubleref", DELTA5, CONSTANT_Double); CPRefBand bc_stringref = bc_bands.newCPRefBand("bc_stringref", DELTA5, CONSTANT_String); + CPRefBand bc_loadablevalueref = bc_bands.newCPRefBand("bc_loadablevalueref", DELTA5, CONSTANT_LoadableValue); // nulls produced by bc_classref are taken to mean the current class CPRefBand bc_classref = bc_bands.newCPRefBand("bc_classref", UNSIGNED5, CONSTANT_Class, NULL_IS_OK); // new, *anew*, c*cast, i*of, ldc CPRefBand bc_fieldref = bc_bands.newCPRefBand("bc_fieldref", DELTA5, CONSTANT_Fieldref); // get*, put* CPRefBand bc_methodref = bc_bands.newCPRefBand("bc_methodref", CONSTANT_Methodref); // invoke[vs]* CPRefBand bc_imethodref = bc_bands.newCPRefBand("bc_imethodref", DELTA5, CONSTANT_InterfaceMethodref); // invokeinterface + CPRefBand bc_indyref = bc_bands.newCPRefBand("bc_indyref", DELTA5, CONSTANT_InvokeDynamic); // invokedynamic // _self_linker_op family CPRefBand bc_thisfield = bc_bands.newCPRefBand("bc_thisfield", CONSTANT_None); // any field within cur. class @@ -1633,7 +1643,7 @@ class BandStructure { protected void setBandIndex(CPRefBand b, byte which) { Object[] need = { b, Byte.valueOf(which) }; - if (which == CONSTANT_Literal) { + if (which == CONSTANT_FieldSpecific) { // I.e., attribute layouts KQ (no null) or KQN (null ok). allKQBands.add(b); } else if (needPredefIndex != null) { @@ -1856,12 +1866,20 @@ class BandStructure { attrClassFileVersionMask = (1< 0) Utils.log.fine("Legacy package version"); // Revoke definition of pre-1.6 attribute type. undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE); } + if (getPackageMajver() < JAVA7_PACKAGE_MAJOR_VERSION) { + if (testBit(archiveOptions, AO_HAVE_CP_EXTRAS)) + // this bit was reserved for future use in previous versions + throw new IOException("Format bits for Java 7 must be zero in previous releases"); + } + if (testBit(archiveOptions, AO_UNUSED_MBZ)) { + throw new IOException("High archive option bits are reserved and must be zero: "+Integer.toHexString(archiveOptions)); + } } protected void initAttrIndexLimit() { @@ -2323,7 +2341,9 @@ class BandStructure { return bc_methodref; case CONSTANT_InterfaceMethodref: return bc_imethodref; - case CONSTANT_Literal: + case CONSTANT_InvokeDynamic: + return bc_indyref; + case CONSTANT_LoadableValue: switch (bc) { case _ildc: case _ildc_w: return bc_intref; @@ -2333,10 +2353,12 @@ class BandStructure { return bc_longref; case _dldc2_w: return bc_doubleref; - case _aldc: case _aldc_w: + case _sldc: case _sldc_w: return bc_stringref; case _cldc: case _cldc_w: return bc_classref; + case _qldc: case _qldc_w: + return bc_loadablevalueref; } break; } @@ -2623,15 +2645,23 @@ class BandStructure { } static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end) { + printArrayTo(ps, cpMap, start, end, false); + } + static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end, boolean showTags) { StringBuffer buf = new StringBuffer(); int len = end-start; for (int i = 0; i < len; i++) { - String s = cpMap[start+i].stringValue(); + Entry e = cpMap[start+i]; + ps.print(start+i); ps.print("="); + if (showTags) { ps.print(e.tag); ps.print(":"); } + String s = e.stringValue(); buf.setLength(0); for (int j = 0; j < s.length(); j++) { char ch = s.charAt(j); if (!(ch < ' ' || ch > '~' || ch == '\\')) { buf.append(ch); + } else if (ch == '\\') { + buf.append("\\\\"); } else if (ch == '\n') { buf.append("\\n"); } else if (ch == '\t') { @@ -2639,7 +2669,8 @@ class BandStructure { } else if (ch == '\r') { buf.append("\\r"); } else { - buf.append("\\x"+Integer.toHexString(ch)); + String str = "000"+Integer.toHexString(ch); + buf.append("\\u"+str.substring(str.length()-4)); } } ps.println(buf); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java index ce29f1f3a19..545faab9127 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,9 @@ import com.sun.java.util.jar.pack.ConstantPool.ClassEntry; import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry; import com.sun.java.util.jar.pack.ConstantPool.Entry; import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry; +import com.sun.java.util.jar.pack.ConstantPool.MemberEntry; +import com.sun.java.util.jar.pack.ConstantPool.MethodHandleEntry; +import com.sun.java.util.jar.pack.ConstantPool.BootstrapMethodEntry; import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry; import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.Package.InnerClass; @@ -37,6 +40,7 @@ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Map; import static com.sun.java.util.jar.pack.Constants.*; @@ -114,6 +118,7 @@ class ClassReader { private Entry readRef(byte tag) throws IOException { Entry e = readRef(); assert(e != null); + assert(!(e instanceof UnresolvedEntry)); assert(e.tagMatches(tag)); return e; } @@ -151,6 +156,7 @@ class ClassReader { readMembers(false); // fields readMembers(true); // methods readAttributes(ATTR_CONTEXT_CLASS, cls); + fixUnresolvedEntries(); cls.finishReading(); assert(0 >= in.read(new byte[1])); ok = true; @@ -236,6 +242,7 @@ class ClassReader { // just read the refs; do not attempt to resolve while reading case CONSTANT_Class: case CONSTANT_String: + case CONSTANT_MethodType: fixups[fptr++] = i; fixups[fptr++] = tag; fixups[fptr++] = in.readUnsignedShort(); @@ -250,6 +257,18 @@ class ClassReader { fixups[fptr++] = in.readUnsignedShort(); fixups[fptr++] = in.readUnsignedShort(); break; + case CONSTANT_InvokeDynamic: + fixups[fptr++] = i; + fixups[fptr++] = tag; + fixups[fptr++] = -1 ^ in.readUnsignedShort(); // not a ref + fixups[fptr++] = in.readUnsignedShort(); + break; + case CONSTANT_MethodHandle: + fixups[fptr++] = i; + fixups[fptr++] = tag; + fixups[fptr++] = -1 ^ in.readUnsignedByte(); + fixups[fptr++] = in.readUnsignedShort(); + break; default: throw new ClassFormatException("Bad constant pool tag " + tag + " in File: " + cls.file.nameString + @@ -270,7 +289,7 @@ class ClassReader { int ref2 = fixups[fi++]; if (verbose > 3) Utils.log.fine(" cp["+cpi+"] = "+ConstantPool.tagName(tag)+"{"+ref+","+ref2+"}"); - if (cpMap[ref] == null || ref2 >= 0 && cpMap[ref2] == null) { + if (ref >= 0 && cpMap[ref] == null || ref2 >= 0 && cpMap[ref2] == null) { // Defer. fixups[fptr++] = cpi; fixups[fptr++] = tag; @@ -297,6 +316,19 @@ class ClassReader { Utf8Entry mtype = (Utf8Entry) cpMap[ref2]; cpMap[cpi] = ConstantPool.getDescriptorEntry(mname, mtype); break; + case CONSTANT_MethodType: + cpMap[cpi] = ConstantPool.getMethodTypeEntry((Utf8Entry) cpMap[ref]); + break; + case CONSTANT_MethodHandle: + byte refKind = (byte)(-1 ^ ref); + MemberEntry memRef = (MemberEntry) cpMap[ref2]; + cpMap[cpi] = ConstantPool.getMethodHandleEntry(refKind, memRef); + break; + case CONSTANT_InvokeDynamic: + DescriptorEntry idescr = (DescriptorEntry) cpMap[ref2]; + cpMap[cpi] = new UnresolvedEntry((byte)tag, (-1 ^ ref), idescr); + // Note that ref must be resolved later, using the BootstrapMethods attribute. + break; default: assert(false); } @@ -307,6 +339,50 @@ class ClassReader { cls.cpMap = cpMap; } + private /*non-static*/ + class UnresolvedEntry extends Entry { + final Object[] refsOrIndexes; + UnresolvedEntry(byte tag, Object... refsOrIndexes) { + super(tag); + this.refsOrIndexes = refsOrIndexes; + ClassReader.this.haveUnresolvedEntry = true; + } + Entry resolve() { + Class cls = ClassReader.this.cls; + Entry res; + switch (tag) { + case CONSTANT_InvokeDynamic: + BootstrapMethodEntry iboots = cls.bootstrapMethods.get((Integer) refsOrIndexes[0]); + DescriptorEntry idescr = (DescriptorEntry) refsOrIndexes[1]; + res = ConstantPool.getInvokeDynamicEntry(iboots, idescr); + break; + default: + throw new AssertionError(); + } + return res; + } + private void unresolved() { throw new RuntimeException("unresolved entry has no string"); } + public int compareTo(Object x) { unresolved(); return 0; } + public boolean equals(Object x) { unresolved(); return false; } + protected int computeValueHash() { unresolved(); return 0; } + public String stringValue() { unresolved(); return toString(); } + public String toString() { return "(unresolved "+ConstantPool.tagName(tag)+")"; } + } + + boolean haveUnresolvedEntry; + private void fixUnresolvedEntries() { + if (!haveUnresolvedEntry) return; + Entry[] cpMap = cls.getCPMap(); + for (int i = 0; i < cpMap.length; i++) { + Entry e = cpMap[i]; + if (e instanceof UnresolvedEntry) { + cpMap[i] = e = ((UnresolvedEntry)e).resolve(); + assert(!(e instanceof UnresolvedEntry)); + } + } + haveUnresolvedEntry = false; + } + void readHeader() throws IOException { cls.flags = readUnsignedShort(); cls.thisClass = readClassRef(); @@ -416,25 +492,31 @@ class ClassReader { unknownAttrCommand); } } - if (a.layout() == Package.attrCodeEmpty || - a.layout() == Package.attrInnerClassesEmpty) { + long pos0 = inPos; // in case we want to check it + if (a.layout() == Package.attrCodeEmpty) { // These are hardwired. - long pos0 = inPos; - if ("Code".equals(a.name())) { - Class.Method m = (Class.Method) h; - m.code = new Code(m); - try { - readCode(m.code); - } catch (Instruction.FormatException iie) { - String message = iie.getMessage() + " in " + h; - throw new ClassReader.ClassFormatException(message, iie); - } - } else { - assert(h == cls); - readInnerClasses(cls); + Class.Method m = (Class.Method) h; + m.code = new Code(m); + try { + readCode(m.code); + } catch (Instruction.FormatException iie) { + String message = iie.getMessage() + " in " + h; + throw new ClassReader.ClassFormatException(message, iie); } assert(length == inPos - pos0); // Keep empty attribute a... + } else if (a.layout() == Package.attrBootstrapMethodsEmpty) { + assert(h == cls); + readBootstrapMethods(cls); + assert(length == inPos - pos0); + // Delete the attribute; it is logically part of the constant pool. + continue; + } else if (a.layout() == Package.attrInnerClassesEmpty) { + // These are hardwired also. + assert(h == cls); + readInnerClasses(cls); + assert(length == inPos - pos0); + // Keep empty attribute a... } else if (length > 0) { byte[] bytes = new byte[length]; in.readFully(bytes); @@ -467,6 +549,19 @@ class ClassReader { readAttributes(ATTR_CONTEXT_CODE, code); } + void readBootstrapMethods(Class cls) throws IOException { + BootstrapMethodEntry[] bsms = new BootstrapMethodEntry[readUnsignedShort()]; + for (int i = 0; i < bsms.length; i++) { + MethodHandleEntry bsmRef = (MethodHandleEntry) readRef(CONSTANT_MethodHandle); + Entry[] argRefs = new Entry[readUnsignedShort()]; + for (int j = 0; j < argRefs.length; j++) { + argRefs[j] = readRef(); + } + bsms[i] = ConstantPool.getBootstrapMethodEntry(bsmRef, argRefs); + } + cls.setBootstrapMethods(Arrays.asList(bsms)); + } + void readInnerClasses(Class cls) throws IOException { int nc = readUnsignedShort(); ArrayList ics = new ArrayList<>(nc); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java index 37424d1e65c..dacae44b4d3 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ package com.sun.java.util.jar.pack; import com.sun.java.util.jar.pack.ConstantPool.Entry; import com.sun.java.util.jar.pack.ConstantPool.Index; import com.sun.java.util.jar.pack.ConstantPool.NumberEntry; +import com.sun.java.util.jar.pack.ConstantPool.MethodHandleEntry; +import com.sun.java.util.jar.pack.ConstantPool.BootstrapMethodEntry; import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.Package.InnerClass; import java.io.BufferedOutputStream; @@ -49,6 +51,7 @@ class ClassWriter { Class cls; DataOutputStream out; Index cpIndex; + Index bsmIndex; ClassWriter(Class cls, OutputStream out) throws IOException { this.pkg = cls.getPackage(); @@ -57,6 +60,10 @@ class ClassWriter { this.out = new DataOutputStream(new BufferedOutputStream(out)); this.cpIndex = ConstantPool.makeIndex(cls.toString(), cls.getCPMap()); this.cpIndex.flattenSigs = true; + if (cls.hasBootstrapMethods()) { + this.bsmIndex = ConstantPool.makeIndex(cpIndex.debugName+".BootstrapMethods", + cls.getBootstrapMethodMap()); + } if (verbose > 1) Utils.log.fine("local CP="+(verbose > 2 ? cpIndex.dumpString() : cpIndex.toString())); } @@ -71,6 +78,11 @@ class ClassWriter { /** Write a 2-byte int representing a CP entry, using the local cpIndex. */ private void writeRef(Entry e) throws IOException { + writeRef(e, cpIndex); + } + + /** Write a 2-byte int representing a CP entry, using the given cpIndex. */ + private void writeRef(Entry e, Index cpIndex) throws IOException { int i = (e == null) ? 0 : cpIndex.indexOf(e); writeShort(i); } @@ -117,8 +129,7 @@ class ClassWriter { out.write(tag); switch (tag) { case CONSTANT_Signature: - assert(false); // should not reach here - break; + throw new AssertionError("CP should have Signatures remapped to Utf8"); case CONSTANT_Utf8: out.writeUTF(e.stringValue()); break; @@ -138,8 +149,14 @@ class ClassWriter { break; case CONSTANT_Class: case CONSTANT_String: + case CONSTANT_MethodType: writeRef(e.getRef(0)); break; + case CONSTANT_MethodHandle: + MethodHandleEntry mhe = (MethodHandleEntry) e; + out.writeByte(mhe.refKind); + writeRef(mhe.getRef(0)); + break; case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: @@ -147,6 +164,12 @@ class ClassWriter { writeRef(e.getRef(0)); writeRef(e.getRef(1)); break; + case CONSTANT_InvokeDynamic: + writeRef(e.getRef(0), bsmIndex); + writeRef(e.getRef(1)); + break; + case CONSTANT_BootstrapMethod: + throw new AssertionError("CP should have BootstrapMethods moved to side-table"); default: throw new IOException("Bad constant pool tag "+tag); } @@ -198,6 +221,7 @@ class ClassWriter { a.finishRefs(cpIndex); writeRef(a.getNameRef()); if (a.layout() == Package.attrCodeEmpty || + a.layout() == Package.attrBootstrapMethodsEmpty || a.layout() == Package.attrInnerClassesEmpty) { // These are hardwired. DataOutputStream savedOut = out; @@ -207,9 +231,14 @@ class ClassWriter { if ("Code".equals(a.name())) { Class.Method m = (Class.Method) h; writeCode(m.code); - } else { + } else if ("BootstrapMethods".equals(a.name())) { + assert(h == cls); + writeBootstrapMethods(cls); + } else if ("InnerClasses".equals(a.name())) { assert(h == cls); writeInnerClasses(cls); + } else { + throw new AssertionError(); } out = savedOut; if (verbose > 2) @@ -242,6 +271,18 @@ class ClassWriter { writeAttributes(ATTR_CONTEXT_CODE, code); } + void writeBootstrapMethods(Class cls) throws IOException { + List bsms = cls.getBootstrapMethods(); + writeShort(bsms.size()); + for (BootstrapMethodEntry e : bsms) { + writeRef(e.bsmRef); + writeShort(e.argRefs.length); + for (Entry argRef : e.argRefs) { + writeRef(argRef); + } + } + } + void writeInnerClasses(Class cls) throws IOException { List ics = cls.getInnerClasses(); writeShort(ics.size()); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java index acade5b7a3d..be4da54d247 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ class ConstantPool { * Also used to back up more complex constant pool entries, like Class. */ public static synchronized Utf8Entry getUtf8Entry(String value) { - Map utf8Entries = Utils.getUtf8Entries(); + Map utf8Entries = Utils.getTLGlobals().getUtf8Entries(); Utf8Entry e = utf8Entries.get(value); if (e == null) { e = new Utf8Entry(value); @@ -61,8 +61,8 @@ class ConstantPool { return e; } /** Factory for Class constants. */ - public static synchronized ClassEntry getClassEntry(String name) { - Map classEntries = Utils.getClassEntries(); + public static ClassEntry getClassEntry(String name) { + Map classEntries = Utils.getTLGlobals().getClassEntries(); ClassEntry e = classEntries.get(name); if (e == null) { e = new ClassEntry(getUtf8Entry(name)); @@ -72,8 +72,8 @@ class ConstantPool { return e; } /** Factory for literal constants (String, Integer, etc.). */ - public static synchronized LiteralEntry getLiteralEntry(Comparable value) { - Map literalEntries = Utils.getLiteralEntries(); + public static LiteralEntry getLiteralEntry(Comparable value) { + Map literalEntries = Utils.getTLGlobals().getLiteralEntries(); LiteralEntry e = literalEntries.get(value); if (e == null) { if (value instanceof String) @@ -85,13 +85,13 @@ class ConstantPool { return e; } /** Factory for literal constants (String, Integer, etc.). */ - public static synchronized StringEntry getStringEntry(String value) { + public static StringEntry getStringEntry(String value) { return (StringEntry) getLiteralEntry(value); } /** Factory for signature (type) constants. */ - public static synchronized SignatureEntry getSignatureEntry(String type) { - Map signatureEntries = Utils.getSignatureEntries(); + public static SignatureEntry getSignatureEntry(String type) { + Map signatureEntries = Utils.getTLGlobals().getSignatureEntries(); SignatureEntry e = signatureEntries.get(type); if (e == null) { e = new SignatureEntry(type); @@ -106,8 +106,8 @@ class ConstantPool { } /** Factory for descriptor (name-and-type) constants. */ - public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) { - Map descriptorEntries = Utils.getDescriptorEntries(); + public static DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) { + Map descriptorEntries = Utils.getTLGlobals().getDescriptorEntries(); String key = DescriptorEntry.stringValueOf(nameRef, typeRef); DescriptorEntry e = descriptorEntries.get(key); if (e == null) { @@ -124,8 +124,8 @@ class ConstantPool { } /** Factory for member reference constants. */ - public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { - Map memberEntries = Utils.getMemberEntries(); + public static MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { + Map memberEntries = Utils.getTLGlobals().getMemberEntries(); String key = MemberEntry.stringValueOf(tag, classRef, descRef); MemberEntry e = memberEntries.get(key); if (e == null) { @@ -137,6 +137,61 @@ class ConstantPool { return e; } + /** Factory for MethodHandle constants. */ + public static MethodHandleEntry getMethodHandleEntry(byte refKind, MemberEntry memRef) { + Map methodHandleEntries = Utils.getTLGlobals().getMethodHandleEntries(); + String key = MethodHandleEntry.stringValueOf(refKind, memRef); + MethodHandleEntry e = methodHandleEntries.get(key); + if (e == null) { + e = new MethodHandleEntry(refKind, memRef); + assert(e.stringValue().equals(key)); + methodHandleEntries.put(key, e); + } + return e; + } + + /** Factory for MethodType constants. */ + public static MethodTypeEntry getMethodTypeEntry(SignatureEntry sigRef) { + Map methodTypeEntries = Utils.getTLGlobals().getMethodTypeEntries(); + String key = sigRef.stringValue(); + MethodTypeEntry e = methodTypeEntries.get(key); + if (e == null) { + e = new MethodTypeEntry(sigRef); + assert(e.stringValue().equals(key)); + methodTypeEntries.put(key, e); + } + return e; + } + public static MethodTypeEntry getMethodTypeEntry(Utf8Entry typeRef) { + return getMethodTypeEntry(getSignatureEntry(typeRef.stringValue())); + } + + /** Factory for InvokeDynamic constants. */ + public static InvokeDynamicEntry getInvokeDynamicEntry(BootstrapMethodEntry bssRef, DescriptorEntry descRef) { + Map invokeDynamicEntries = Utils.getTLGlobals().getInvokeDynamicEntries(); + String key = InvokeDynamicEntry.stringValueOf(bssRef, descRef); + InvokeDynamicEntry e = invokeDynamicEntries.get(key); + if (e == null) { + e = new InvokeDynamicEntry(bssRef, descRef); + assert(e.stringValue().equals(key)); + invokeDynamicEntries.put(key, e); + } + return e; + } + + /** Factory for BootstrapMethod pseudo-constants. */ + public static BootstrapMethodEntry getBootstrapMethodEntry(MethodHandleEntry bsmRef, Entry[] argRefs) { + Map bootstrapMethodEntries = Utils.getTLGlobals().getBootstrapMethodEntries(); + String key = BootstrapMethodEntry.stringValueOf(bsmRef, argRefs); + BootstrapMethodEntry e = bootstrapMethodEntries.get(key); + if (e == null) { + e = new BootstrapMethodEntry(bsmRef, argRefs); + assert(e.stringValue().equals(key)); + bootstrapMethodEntries.put(key, e); + } + return e; + } + /** Entries in the constant pool. */ public static abstract @@ -251,6 +306,10 @@ class ConstantPool { throw new RuntimeException("bad literal value "+value); } + static boolean isRefKind(byte refKind) { + return (REF_getField <= refKind && refKind <= REF_invokeInterface); + } + public static abstract class LiteralEntry extends Entry { protected LiteralEntry(byte tag) { @@ -404,7 +463,7 @@ class ConstantPool { } static String stringValueOf(Entry nameRef, Entry typeRef) { - return typeRef.stringValue()+","+nameRef.stringValue(); + return qualifiedStringValue(typeRef, nameRef); } public String prettyString() { @@ -420,6 +479,15 @@ class ConstantPool { } } + static String qualifiedStringValue(Entry e1, Entry e2) { + return qualifiedStringValue(e1.stringValue(), e2.stringValue()); + } + static String qualifiedStringValue(String s1, String s234) { + // Qualification by dot must decompose uniquely. Second string might already be qualified. + assert(s1.indexOf(".") < 0); + return s1+"."+s234; + } + public static class MemberEntry extends Entry { final ClassEntry classRef; @@ -453,8 +521,12 @@ class ConstantPool { int x = superCompareTo(o); if (x == 0) { MemberEntry that = (MemberEntry)o; + if (Utils.SORT_MEMBERS_DESCR_MAJOR) + // descRef is transmitted as UDELTA5; sort it first? + x = this.descRef.compareTo(that.descRef); // Primary key is classRef. - x = this.classRef.compareTo(that.classRef); + if (x == 0) + x = this.classRef.compareTo(that.classRef); if (x == 0) x = this.descRef.compareTo(that.descRef); } @@ -473,7 +545,7 @@ class ConstantPool { case CONSTANT_InterfaceMethodref: pfx = "IMethod:"; break; default: pfx = tag+"???"; break; } - return pfx+classRef.stringValue()+","+descRef.stringValue(); + return pfx+qualifiedStringValue(classRef, descRef); } public boolean isMethod() { @@ -581,13 +653,26 @@ class ConstantPool { } public byte getLiteralTag() { switch (formRef.stringValue().charAt(0)) { - case 'L': return CONSTANT_String; case 'I': return CONSTANT_Integer; case 'J': return CONSTANT_Long; case 'F': return CONSTANT_Float; case 'D': return CONSTANT_Double; case 'B': case 'S': case 'C': case 'Z': return CONSTANT_Integer; + case 'L': + /* + switch (classRefs[0].stringValue()) { + case "java/lang/String": + return CONSTANT_String; + case "java/lang/invoke/MethodHandle": + return CONSTANT_MethodHandle; + case "java/lang/invoke/MethodType": + return CONSTANT_MethodType; + default: // java/lang/Object, etc. + return CONSTANT_LoadableValue; + } + */ + return CONSTANT_String; // JDK 7 ConstantValue limited to String } assert(false); return CONSTANT_None; @@ -724,6 +809,218 @@ class ConstantPool { return parts; } + /** @since JDK 7, JSR 292 */ + public static + class MethodHandleEntry extends Entry { + final int refKind; + final MemberEntry memRef; + public Entry getRef(int i) { return i == 0 ? memRef : null; } + + protected int computeValueHash() { + int hc2 = refKind; + return (memRef.hashCode() + (hc2 << 8)) ^ hc2; + } + + MethodHandleEntry(byte refKind, MemberEntry memRef) { + super(CONSTANT_MethodHandle); + assert(isRefKind(refKind)); + this.refKind = refKind; + this.memRef = memRef; + hashCode(); // force computation of valueHash + } + public boolean equals(Object o) { + if (o == null || o.getClass() != MethodHandleEntry.class) { + return false; + } + MethodHandleEntry that = (MethodHandleEntry)o; + return this.refKind == that.refKind + && this.memRef.eq(that.memRef); + } + public int compareTo(Object o) { + int x = superCompareTo(o); + if (x == 0) { + MethodHandleEntry that = (MethodHandleEntry)o; + if (Utils.SORT_HANDLES_KIND_MAJOR) + // Primary key could be refKind. + x = this.refKind - that.refKind; + // Primary key is memRef, which is transmitted as UDELTA5. + if (x == 0) + x = this.memRef.compareTo(that.memRef); + if (x == 0) + x = this.refKind - that.refKind; + } + return x; + } + public static String stringValueOf(int refKind, MemberEntry memRef) { + return refKindName(refKind)+":"+memRef.stringValue(); + } + public String stringValue() { + return stringValueOf(refKind, memRef); + } + } + + /** @since JDK 7, JSR 292 */ + public static + class MethodTypeEntry extends Entry { + final SignatureEntry typeRef; + public Entry getRef(int i) { return i == 0 ? typeRef : null; } + + protected int computeValueHash() { + return typeRef.hashCode() + tag; + } + + MethodTypeEntry(SignatureEntry typeRef) { + super(CONSTANT_MethodType); + this.typeRef = typeRef; + hashCode(); // force computation of valueHash + } + public boolean equals(Object o) { + if (o == null || o.getClass() != MethodTypeEntry.class) { + return false; + } + MethodTypeEntry that = (MethodTypeEntry)o; + return this.typeRef.eq(that.typeRef); + } + public int compareTo(Object o) { + int x = superCompareTo(o); + if (x == 0) { + MethodTypeEntry that = (MethodTypeEntry)o; + x = this.typeRef.compareTo(that.typeRef); + } + return x; + } + public String stringValue() { + return typeRef.stringValue(); + } + } + + /** @since JDK 7, JSR 292 */ + public static + class InvokeDynamicEntry extends Entry { + final BootstrapMethodEntry bssRef; + final DescriptorEntry descRef; + public Entry getRef(int i) { + if (i == 0) return bssRef; + if (i == 1) return descRef; + return null; + } + protected int computeValueHash() { + int hc2 = descRef.hashCode(); + return (bssRef.hashCode() + (hc2 << 8)) ^ hc2; + } + + InvokeDynamicEntry(BootstrapMethodEntry bssRef, DescriptorEntry descRef) { + super(CONSTANT_InvokeDynamic); + this.bssRef = bssRef; + this.descRef = descRef; + hashCode(); // force computation of valueHash + } + public boolean equals(Object o) { + if (o == null || o.getClass() != InvokeDynamicEntry.class) { + return false; + } + InvokeDynamicEntry that = (InvokeDynamicEntry)o; + return this.bssRef.eq(that.bssRef) + && this.descRef.eq(that.descRef); + } + public int compareTo(Object o) { + int x = superCompareTo(o); + if (x == 0) { + InvokeDynamicEntry that = (InvokeDynamicEntry)o; + if (Utils.SORT_INDY_BSS_MAJOR) + // Primary key could be bsmRef. + x = this.bssRef.compareTo(that.bssRef); + // Primary key is descriptor, which is transmitted as UDELTA5. + if (x == 0) + x = this.descRef.compareTo(that.descRef); + if (x == 0) + x = this.bssRef.compareTo(that.bssRef); + } + return x; + } + public String stringValue() { + return stringValueOf(bssRef, descRef); + } + static + String stringValueOf(BootstrapMethodEntry bssRef, DescriptorEntry descRef) { + return "Indy:"+bssRef.stringValue()+"."+descRef.stringValue(); + } + } + + /** @since JDK 7, JSR 292 */ + public static + class BootstrapMethodEntry extends Entry { + final MethodHandleEntry bsmRef; + final Entry[] argRefs; + public Entry getRef(int i) { + if (i == 0) return bsmRef; + if (i-1 < argRefs.length) return argRefs[i-1]; + return null; + } + protected int computeValueHash() { + int hc2 = bsmRef.hashCode(); + return (Arrays.hashCode(argRefs) + (hc2 << 8)) ^ hc2; + } + + BootstrapMethodEntry(MethodHandleEntry bsmRef, Entry[] argRefs) { + super(CONSTANT_BootstrapMethod); + this.bsmRef = bsmRef; + this.argRefs = argRefs.clone(); + hashCode(); // force computation of valueHash + } + public boolean equals(Object o) { + if (o == null || o.getClass() != BootstrapMethodEntry.class) { + return false; + } + BootstrapMethodEntry that = (BootstrapMethodEntry)o; + return this.bsmRef.eq(that.bsmRef) + && Arrays.equals(this.argRefs, that.argRefs); + } + public int compareTo(Object o) { + int x = superCompareTo(o); + if (x == 0) { + BootstrapMethodEntry that = (BootstrapMethodEntry)o; + if (Utils.SORT_BSS_BSM_MAJOR) + // Primary key is bsmRef. + x = this.bsmRef.compareTo(that.bsmRef); + // Primary key is args array length, which is transmitted as UDELTA5. + if (x == 0) + x = compareArgArrays(this.argRefs, that.argRefs); + if (x == 0) + x = this.bsmRef.compareTo(that.bsmRef); + } + return x; + } + public String stringValue() { + return stringValueOf(bsmRef, argRefs); + } + static + String stringValueOf(MethodHandleEntry bsmRef, Entry[] argRefs) { + StringBuffer sb = new StringBuffer(bsmRef.stringValue()); + // Arguments are formatted as "" instead of "[foo,bar,baz]". + // This ensures there will be no confusion if "[,]" appear inside of names. + char nextSep = '<'; + boolean didOne = false; + for (Entry argRef : argRefs) { + sb.append(nextSep).append(argRef.stringValue()); + nextSep = ';'; + } + if (nextSep == '<') sb.append(nextSep); + sb.append('>'); + return sb.toString(); + } + static + int compareArgArrays(Entry[] a1, Entry[] a2) { + int x = a1.length - a2.length; + if (x != 0) return x; + for (int i = 0; i < a1.length; i++) { + x = a1[i].compareTo(a2[i]); + if (x != 0) break; + } + return x; + } + } + // Handy constants: protected static final Entry[] noRefs = {}; protected static final ClassEntry[] noClassRefs = {}; @@ -964,35 +1261,51 @@ class ConstantPool { /** Coherent group of constant pool indexes. */ public static class IndexGroup { - private Index indexUntyped; private Index[] indexByTag = new Index[CONSTANT_Limit]; + private Index[] indexByTagGroup; private int[] untypedFirstIndexByTag; - private int totalSize; + private int totalSizeQQ; private Index[][] indexByTagAndClass; /** Index of all CP entries of all types, in definition order. */ - public Index getUntypedIndex() { - if (indexUntyped == null) { + private Index makeTagGroupIndex(byte tagGroupTag, byte[] tagsInGroup) { + if (indexByTagGroup == null) + indexByTagGroup = new Index[CONSTANT_GroupLimit - CONSTANT_GroupFirst]; + int which = tagGroupTag - CONSTANT_GroupFirst; + assert(indexByTagGroup[which] == null); + int fillp = 0; + Entry[] cpMap = null; + for (int pass = 1; pass <= 2; pass++) { untypedIndexOf(null); // warm up untypedFirstIndexByTag - Entry[] cpMap = new Entry[totalSize]; - for (int tag = 0; tag < indexByTag.length; tag++) { + for (byte tag : tagsInGroup) { Index ix = indexByTag[tag]; if (ix == null) continue; int ixLen = ix.cpMap.length; if (ixLen == 0) continue; - int fillp = untypedFirstIndexByTag[tag]; - assert(cpMap[fillp] == null); - assert(cpMap[fillp+ixLen-1] == null); - System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen); + assert(tagGroupTag == CONSTANT_All + ? fillp == untypedFirstIndexByTag[tag] + : fillp < untypedFirstIndexByTag[tag]); + if (cpMap != null) { + assert(cpMap[fillp] == null); + assert(cpMap[fillp+ixLen-1] == null); + System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen); + } + fillp += ixLen; + } + if (cpMap == null) { + assert(pass == 1); + // get ready for pass 2 + cpMap = new Entry[fillp]; + fillp = 0; } - indexUntyped = new Index("untyped", cpMap); } - return indexUntyped; + indexByTagGroup[which] = new Index(tagName(tagGroupTag), cpMap); + return indexByTagGroup[which]; } public int untypedIndexOf(Entry e) { if (untypedFirstIndexByTag == null) { - untypedFirstIndexByTag = new int[CONSTANT_Limit]; + untypedFirstIndexByTag = new int[CONSTANT_Limit+1]; int fillp = 0; for (int i = 0; i < TAGS_IN_ORDER.length; i++) { byte tag = TAGS_IN_ORDER[i]; @@ -1002,7 +1315,7 @@ class ConstantPool { untypedFirstIndexByTag[tag] = fillp; fillp += ixLen; } - totalSize = fillp; + untypedFirstIndexByTag[CONSTANT_Limit] = fillp; } if (e == null) return -1; int tag = e.tag; @@ -1028,16 +1341,15 @@ class ConstantPool { indexByTag[tag] = ix; // decache indexes derived from this one: untypedFirstIndexByTag = null; - indexUntyped = null; + indexByTagGroup = null; if (indexByTagAndClass != null) indexByTagAndClass[tag] = null; } /** Index of all CP entries of a given tag. */ public Index getIndexByTag(byte tag) { - if (tag == CONSTANT_All) { - return getUntypedIndex(); - } + if (tag >= CONSTANT_GroupFirst) + return getIndexByTagGroup(tag); Index ix = indexByTag[tag]; if (ix == null) { // Make an empty one by default. @@ -1047,6 +1359,26 @@ class ConstantPool { return ix; } + private Index getIndexByTagGroup(byte tag) { + // pool groups: + if (indexByTagGroup != null) { + Index ix = indexByTagGroup[tag - CONSTANT_GroupFirst]; + if (ix != null) return ix; + } + switch (tag) { + case CONSTANT_All: + return makeTagGroupIndex(CONSTANT_All, TAGS_IN_ORDER); + case CONSTANT_LoadableValue: + return makeTagGroupIndex(CONSTANT_LoadableValue, LOADABLE_VALUE_TAGS); + case CONSTANT_AnyMember: + return makeTagGroupIndex(CONSTANT_AnyMember, ANY_MEMBER_TAGS); + case CONSTANT_FieldSpecific: + // This one does not have any fixed index, since it is context-specific. + return null; + } + throw new AssertionError("bad tag group "+tag); + } + /** Index of all CP entries of a given tag and class. */ public Index getMemberIndex(byte tag, ClassEntry classRef) { if (indexByTagAndClass == null) @@ -1107,16 +1439,14 @@ class ConstantPool { } public boolean haveNumbers() { - for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) { - switch (tag) { - case CONSTANT_Integer: - case CONSTANT_Float: - case CONSTANT_Long: - case CONSTANT_Double: - break; - default: - assert(false); - } + for (byte tag : NUMBER_TAGS) { + if (getIndexByTag(tag).size() > 0) return true; + } + return false; + } + + public boolean haveExtraTags() { + for (byte tag : EXTRA_TAGS) { if (getIndexByTag(tag).size() > 0) return true; } return false; @@ -1129,8 +1459,13 @@ class ConstantPool { * by their equivalent Utf8s. * Also, discard null from cpRefs. */ + public static void completeReferencesIn(Set cpRefs, boolean flattenSigs) { + completeReferencesIn(cpRefs, flattenSigs, null); + } + public static - void completeReferencesIn(Set cpRefs, boolean flattenSigs) { + void completeReferencesIn(Set cpRefs, boolean flattenSigs, + Listbsms) { cpRefs.remove(null); for (ListIterator work = new ArrayList<>(cpRefs).listIterator(cpRefs.size()); @@ -1146,6 +1481,14 @@ class ConstantPool { cpRefs.add(ue); e = ue; // do not descend into the sig } + if (bsms != null && e.tag == CONSTANT_BootstrapMethod) { + BootstrapMethodEntry bsm = (BootstrapMethodEntry)e; + cpRefs.remove(bsm); + // move it away to the side table where it belongs + if (!bsms.contains(bsm)) + bsms.add(bsm); + // fall through to recursively add refs for this entry + } // Recursively add the refs of e to cpRefs: for (int i = 0; ; i++) { Entry re = e.getRef(i); @@ -1174,15 +1517,37 @@ class ConstantPool { case CONSTANT_Methodref: return "Methodref"; case CONSTANT_InterfaceMethodref: return "InterfaceMethodref"; case CONSTANT_NameandType: return "NameandType"; + case CONSTANT_MethodHandle: return "MethodHandle"; + case CONSTANT_MethodType: return "MethodType"; + case CONSTANT_InvokeDynamic: return "InvokeDynamic"; // pseudo-tags: - case CONSTANT_All: return "*All"; - case CONSTANT_None: return "*None"; + case CONSTANT_All: return "**All"; + case CONSTANT_None: return "**None"; + case CONSTANT_LoadableValue: return "**LoadableValue"; + case CONSTANT_AnyMember: return "**AnyMember"; + case CONSTANT_FieldSpecific: return "*FieldSpecific"; case CONSTANT_Signature: return "*Signature"; + case CONSTANT_BootstrapMethod: return "*BootstrapMethod"; } return "tag#"+tag; } + public static String refKindName(int refKind) { + switch (refKind) { + case REF_getField: return "getField"; + case REF_getStatic: return "getStatic"; + case REF_putField: return "putField"; + case REF_putStatic: return "putStatic"; + case REF_invokeVirtual: return "invokeVirtual"; + case REF_invokeStatic: return "invokeStatic"; + case REF_invokeSpecial: return "invokeSpecial"; + case REF_newInvokeSpecial: return "newInvokeSpecial"; + case REF_invokeInterface: return "invokeInterface"; + } + return "refKind#"+refKind; + } + // archive constant pool definition order static final byte TAGS_IN_ORDER[] = { CONSTANT_Utf8, @@ -1190,13 +1555,19 @@ class ConstantPool { CONSTANT_Float, CONSTANT_Long, CONSTANT_Double, - CONSTANT_String, + CONSTANT_String, // note that String=8 precedes Class=7 CONSTANT_Class, CONSTANT_Signature, CONSTANT_NameandType, // cp_Descr CONSTANT_Fieldref, // cp_Field CONSTANT_Methodref, // cp_Method - CONSTANT_InterfaceMethodref // cp_Imethod + CONSTANT_InterfaceMethodref, // cp_Imethod + + // Constants defined in JDK 7 and later: + CONSTANT_MethodHandle, + CONSTANT_MethodType, + CONSTANT_BootstrapMethod, // pseudo-tag, really stored in a class attribute + CONSTANT_InvokeDynamic }; static final byte TAG_ORDER[]; static { @@ -1211,4 +1582,45 @@ class ConstantPool { System.out.println("};"); */ } + static final byte[] NUMBER_TAGS = { + CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long, CONSTANT_Double + }; + static final byte[] EXTRA_TAGS = { + CONSTANT_MethodHandle, CONSTANT_MethodType, + CONSTANT_BootstrapMethod, // pseudo-tag + CONSTANT_InvokeDynamic + }; + static final byte[] LOADABLE_VALUE_TAGS = { // for CONSTANT_LoadableValue + CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long, CONSTANT_Double, + CONSTANT_String, CONSTANT_Class, + CONSTANT_MethodHandle, CONSTANT_MethodType + }; + static final byte[] ANY_MEMBER_TAGS = { // for CONSTANT_AnyMember + CONSTANT_Fieldref, CONSTANT_Methodref, CONSTANT_InterfaceMethodref + }; + static final byte[] FIELD_SPECIFIC_TAGS = { // for CONSTANT_FieldSpecific + CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long, CONSTANT_Double, + CONSTANT_String + }; + static { + assert( + verifyTagOrder(TAGS_IN_ORDER) && + verifyTagOrder(NUMBER_TAGS) && + verifyTagOrder(EXTRA_TAGS) && + verifyTagOrder(LOADABLE_VALUE_TAGS) && + verifyTagOrder(ANY_MEMBER_TAGS) && + verifyTagOrder(FIELD_SPECIFIC_TAGS) + ); + } + private static boolean verifyTagOrder(byte[] tags) { + int prev = -1; + for (byte tag : tags) { + int next = TAG_ORDER[tag]; + assert(next > 0) : "tag not found: "+tag; + assert(TAGS_IN_ORDER[next-1] == tag) : "tag repeated: "+tag+" => "+next+" => "+TAGS_IN_ORDER[next-1]; + assert(prev < next) : "tags not in order: "+Arrays.toString(tags)+" at "+tag; + prev = next; + } + return true; + } } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java index 8dc6560d148..c7fa00e0f18 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -65,6 +65,9 @@ class Constants { public final static int JAVA6_PACKAGE_MAJOR_VERSION = 160; public final static int JAVA6_PACKAGE_MINOR_VERSION = 1; + public final static int JAVA7_PACKAGE_MAJOR_VERSION = 170; + public final static int JAVA7_PACKAGE_MINOR_VERSION = 1; + public final static int CONSTANT_POOL_INDEX_LIMIT = 0x10000; public final static int CONSTANT_POOL_NARROW_LIMIT = 0x00100; @@ -82,14 +85,36 @@ class Constants { public final static byte CONSTANT_Methodref = 10; public final static byte CONSTANT_InterfaceMethodref = 11; public final static byte CONSTANT_NameandType = 12; + public final static byte CONSTANT_unused13 = 13; + public final static byte CONSTANT_unused14 = 14; + public final static byte CONSTANT_MethodHandle = 15; + public final static byte CONSTANT_MethodType = 16; + public final static byte CONSTANT_unused17 = 17; // unused + public final static byte CONSTANT_InvokeDynamic = 18; // pseudo-constants: public final static byte CONSTANT_None = 0; - public final static byte CONSTANT_Signature = 13; - public final static byte CONSTANT_Limit = 14; + public final static byte CONSTANT_Signature = CONSTANT_unused13; + public final static byte CONSTANT_BootstrapMethod = CONSTANT_unused17; // used only in InvokeDynamic constants + public final static byte CONSTANT_Limit = 19; - public final static byte CONSTANT_All = 19; // combined global map - public final static byte CONSTANT_Literal = 20; // used only for ldc fields + public final static byte CONSTANT_All = 50; // combined global map + public final static byte CONSTANT_LoadableValue = 51; // used for 'KL' and qldc operands + public final static byte CONSTANT_AnyMember = 52; // union of refs to field or (interface) method + public final static byte CONSTANT_FieldSpecific = 53; // used only for 'KQ' ConstantValue attrs + public final static byte CONSTANT_GroupFirst = CONSTANT_All; + public final static byte CONSTANT_GroupLimit = CONSTANT_FieldSpecific+1; + + // CONSTANT_MethodHandle reference kinds + public final static byte REF_getField = 1; + public final static byte REF_getStatic = 2; + public final static byte REF_putField = 3; + public final static byte REF_putStatic = 4; + public final static byte REF_invokeVirtual = 5; + public final static byte REF_invokeStatic = 6; + public final static byte REF_invokeSpecial = 7; + public final static byte REF_newInvokeSpecial = 8; + public final static byte REF_invokeInterface = 9; // pseudo-access bits public final static int ACC_IC_LONG_FORM = (1<<16); //for ic_flags @@ -133,7 +158,7 @@ class Constants { public static final int AO_HAVE_SPECIAL_FORMATS = 1<<0; public static final int AO_HAVE_CP_NUMBERS = 1<<1; public static final int AO_HAVE_ALL_CODE_FLAGS = 1<<2; - public static final int AO_3_UNUSED_MBZ = 1<<3; + public static final int AO_HAVE_CP_EXTRAS = 1<<3; public static final int AO_HAVE_FILE_HEADERS = 1<<4; public static final int AO_DEFLATE_HINT = 1<<5; public static final int AO_HAVE_FILE_MODTIME = 1<<6; @@ -143,6 +168,7 @@ class Constants { public static final int AO_HAVE_FIELD_FLAGS_HI = 1<<10; public static final int AO_HAVE_METHOD_FLAGS_HI = 1<<11; public static final int AO_HAVE_CODE_FLAGS_HI = 1<<12; + public static final int AO_UNUSED_MBZ = (-1)<<13; // option bits reserved for future use public static final int LG_AO_HAVE_XXX_FLAGS_HI = 9; @@ -357,7 +383,7 @@ class Constants { _invokespecial = 183, // 0xb7 _invokestatic = 184, // 0xb8 _invokeinterface = 185, // 0xb9 - _xxxunusedxxx = 186, // 0xba + _invokedynamic = 186, // 0xba _new = 187, // 0xbb _newarray = 188, // 0xbc _anewarray = 189, // 0xbd @@ -422,15 +448,18 @@ class Constants { // Ldc variants gain us only 0.007% improvement in compression ratio, // but they simplify the file format greatly. public final static int _xldc_op = _invokeinit_limit; - public final static int _aldc = _ldc; + public final static int _sldc = _ldc; // previously named _aldc public final static int _cldc = _xldc_op+0; public final static int _ildc = _xldc_op+1; public final static int _fldc = _xldc_op+2; - public final static int _aldc_w = _ldc_w; + public final static int _sldc_w = _ldc_w; // previously named _aldc_w public final static int _cldc_w = _xldc_op+3; public final static int _ildc_w = _xldc_op+4; public final static int _fldc_w = _xldc_op+5; public final static int _lldc2_w = _ldc2_w; public final static int _dldc2_w = _xldc_op+6; - public final static int _xldc_limit = _xldc_op+7; + // anything other than primitive, string, or class must be handled with qldc: + public final static int _qldc = _xldc_op+7; + public final static int _qldc_w = _xldc_op+8; + public final static int _xldc_limit = _xldc_op+9; } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java index 8d947689ae6..f488bede323 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -451,7 +451,7 @@ class Instruction { public static byte getCPRefOpTag(int bc) { if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return BC_TAG[0][bc]; - if (bc >= _xldc_op && bc < _xldc_limit) return CONSTANT_Literal; + if (bc >= _xldc_op && bc < _xldc_limit) return CONSTANT_LoadableValue; return CONSTANT_None; } @@ -500,7 +500,7 @@ class Instruction { def("bkf", _getstatic, _putfield); // pack kf (base=Field) def("bkm", _invokevirtual, _invokestatic); // pack kn (base=Method) def("bkixx", _invokeinterface); // pack ki (base=IMethod), omit xx - def("", _xxxunusedxxx); + def("bkyxx", _invokedynamic); // pack ky (base=Any), omit xx def("bkc", _new); // pack kc def("bx", _newarray); def("bkc", _anewarray); // pack kc @@ -515,7 +515,6 @@ class Instruction { //System.out.println(i+": l="+BC_LENGTH[0][i]+" i="+BC_INDEX[0][i]); //assert(BC_LENGTH[0][i] != -1); if (BC_LENGTH[0][i] == -1) { - assert(i == _xxxunusedxxx); continue; // unknown opcode } @@ -543,7 +542,7 @@ class Instruction { "if_icmpne if_icmplt if_icmpge if_icmpgt if_icmple if_acmpeq if_acmpne "+ "goto jsr ret tableswitch lookupswitch ireturn lreturn freturn dreturn "+ "areturn return getstatic putstatic getfield putfield invokevirtual "+ - "invokespecial invokestatic invokeinterface xxxunusedxxx new newarray "+ + "invokespecial invokestatic invokeinterface invokedynamic new newarray "+ "anewarray arraylength athrow checkcast instanceof monitorenter "+ "monitorexit wide multianewarray ifnull ifnonnull goto_w jsr_w "; for (int bc = 0; names.length() > 0; bc++) { @@ -588,6 +587,8 @@ class Instruction { case _dldc2_w: iname = "*dldc2_w"; break; case _cldc: iname = "*cldc"; break; case _cldc_w: iname = "*cldc_w"; break; + case _qldc: iname = "*qldc"; break; + case _qldc_w: iname = "*qldc_w"; break; case _byte_escape: iname = "*byte_escape"; break; case _ref_escape: iname = "*ref_escape"; break; case _end_marker: iname = "*end"; break; @@ -618,15 +619,16 @@ class Instruction { if (index > 0 && index+1 < length) { switch (fmt.charAt(index+1)) { case 'c': tag = CONSTANT_Class; break; - case 'k': tag = CONSTANT_Literal; break; + case 'k': tag = CONSTANT_LoadableValue; break; case 'f': tag = CONSTANT_Fieldref; break; case 'm': tag = CONSTANT_Methodref; break; case 'i': tag = CONSTANT_InterfaceMethodref; break; + case 'y': tag = CONSTANT_InvokeDynamic; break; } assert(tag != CONSTANT_None); } else if (index > 0 && length == 2) { assert(from_bc == _ldc); - tag = CONSTANT_Literal; // _ldc opcode only + tag = CONSTANT_LoadableValue; // _ldc opcode only } for (int bc = from_bc; bc <= to_bc; bc++) { BC_FORMAT[w][bc] = fmt; @@ -649,7 +651,7 @@ class Instruction { Instruction i = at(code, 0); while (i != null) { int opcode = i.getBC(); - if (opcode == _xxxunusedxxx || opcode < _nop || opcode > _jsr_w) { + if (opcode < _nop || opcode > _jsr_w) { String message = "illegal opcode: " + opcode + " " + i; throw new FormatException(message); } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java index 2abe5452249..fee97f4d964 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ package com.sun.java.util.jar.pack; import com.sun.java.util.jar.pack.Attribute.Layout; import com.sun.java.util.jar.pack.ConstantPool.ClassEntry; import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry; +import com.sun.java.util.jar.pack.ConstantPool.BootstrapMethodEntry; import com.sun.java.util.jar.pack.ConstantPool.Index; import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry; import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry; @@ -100,6 +101,8 @@ class Package { classes.clear(); files.clear(); BandStructure.nextSeqForDebug = 0; + package_minver = -1; // fill in later + package_majver = 0; // fill in later } int getPackageVersion() { @@ -108,6 +111,7 @@ class Package { // Special empty versions of Code and InnerClasses, used for markers. public static final Attribute.Layout attrCodeEmpty; + public static final Attribute.Layout attrBootstrapMethodsEmpty; public static final Attribute.Layout attrInnerClassesEmpty; public static final Attribute.Layout attrSourceFileSpecial; public static final Map attrDefs; @@ -115,6 +119,8 @@ class Package { Map ad = new HashMap<>(3); attrCodeEmpty = Attribute.define(ad, ATTR_CONTEXT_METHOD, "Code", "").layout(); + attrBootstrapMethodsEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS, + "BootstrapMethods", "").layout(); attrInnerClassesEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS, "InnerClasses", "").layout(); attrSourceFileSpecial = Attribute.define(ad, ATTR_CONTEXT_CLASS, @@ -153,9 +159,8 @@ class Package { package_minver = JAVA6_PACKAGE_MINOR_VERSION; } else { // Normal case. Use the newest archive format, when available - // TODO: replace the following with JAVA7* when the need arises - package_majver = JAVA6_PACKAGE_MAJOR_VERSION; - package_minver = JAVA6_PACKAGE_MINOR_VERSION; + package_majver = JAVA7_PACKAGE_MAJOR_VERSION; + package_minver = JAVA7_PACKAGE_MINOR_VERSION; } } @@ -168,13 +173,22 @@ class Package { String expMag = Integer.toHexString(JAVA_PACKAGE_MAGIC); throw new IOException("Unexpected package magic number: got "+gotMag+"; expected "+expMag); } - if ((package_majver != JAVA6_PACKAGE_MAJOR_VERSION && - package_majver != JAVA5_PACKAGE_MAJOR_VERSION) || - (package_minver != JAVA6_PACKAGE_MINOR_VERSION && - package_minver != JAVA5_PACKAGE_MINOR_VERSION)) { - + int[] majminFound = null; + for (int[] majmin : new int[][]{ + { JAVA7_PACKAGE_MAJOR_VERSION, JAVA7_PACKAGE_MINOR_VERSION }, + { JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION }, + { JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION } + }) { + if (package_majver == majmin[0] && package_minver == majmin[1]) { + majminFound = majmin; + break; + } + } + if (majminFound == null) { String gotVer = package_majver+"."+package_minver; - String expVer = JAVA6_PACKAGE_MAJOR_VERSION+"."+JAVA6_PACKAGE_MINOR_VERSION+ + String expVer = JAVA7_PACKAGE_MAJOR_VERSION+"."+JAVA7_PACKAGE_MINOR_VERSION+ + " OR "+ + JAVA6_PACKAGE_MAJOR_VERSION+"."+JAVA6_PACKAGE_MINOR_VERSION+ " OR "+ JAVA5_PACKAGE_MAJOR_VERSION+"."+JAVA5_PACKAGE_MINOR_VERSION; throw new IOException("Unexpected package minor version: got "+gotVer+"; expected "+expVer); @@ -213,6 +227,7 @@ class Package { //ArrayList attributes; // in Attribute.Holder.this.attributes // Note that InnerClasses may be collected at the package level. ArrayList innerClasses; + ArrayList bootstrapMethods; Class(int flags, ClassEntry thisClass, ClassEntry superClass, ClassEntry[] interfaces) { this.magic = JAVA_MAGIC; @@ -313,6 +328,25 @@ class Package { this.cpMap = cpMap; } + boolean hasBootstrapMethods() { + return bootstrapMethods != null && !bootstrapMethods.isEmpty(); + } + + List getBootstrapMethods() { + return bootstrapMethods; + } + + BootstrapMethodEntry[] getBootstrapMethodMap() { + return (hasBootstrapMethods()) + ? bootstrapMethods.toArray(new BootstrapMethodEntry[bootstrapMethods.size()]) + : null; + } + + void setBootstrapMethods(Collection bsms) { + assert(bootstrapMethods == null); // do not do this twice + bootstrapMethods = new ArrayList<>(bsms); + } + boolean hasInnerClasses() { return innerClasses != null; } @@ -1283,7 +1317,8 @@ class Package { byTagU[tag] = null; // done with it } for (int i = 0; i < byTagU.length; i++) { - assert(byTagU[i] == null); // all consumed + Index ix = byTagU[i]; + assert(ix == null); // all consumed } for (int i = 0; i < ConstantPool.TAGS_IN_ORDER.length; i++) { byte tag = ConstantPool.TAGS_IN_ORDER[i]; diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java index a6886b42c7a..8813b5e3f25 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,7 @@ package com.sun.java.util.jar.pack; -import com.sun.java.util.jar.pack.ConstantPool.ClassEntry; -import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry; -import com.sun.java.util.jar.pack.ConstantPool.Entry; -import com.sun.java.util.jar.pack.ConstantPool.Index; -import com.sun.java.util.jar.pack.ConstantPool.MemberEntry; -import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry; -import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry; +import com.sun.java.util.jar.pack.ConstantPool.*; import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.Package.File; import com.sun.java.util.jar.pack.Package.InnerClass; @@ -46,6 +40,7 @@ import java.util.ArrayList; import java.util.Map; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.HashMap; @@ -266,7 +261,6 @@ class PackageReader extends BandStructure { // #band_headers_size :UNSIGNED5[1] // #attr_definition_count :UNSIGNED5[1] // - assert(AH_LENGTH == 8+(ConstantPool.TAGS_IN_ORDER.length)+6); archive_header_0.expectLength(AH_LENGTH_0); archive_header_0.readFrom(in); @@ -282,6 +276,7 @@ class PackageReader extends BandStructure { boolean haveSpecial = testBit(archiveOptions, AO_HAVE_SPECIAL_FORMATS); boolean haveFiles = testBit(archiveOptions, AO_HAVE_FILE_HEADERS); boolean haveNumbers = testBit(archiveOptions, AO_HAVE_CP_NUMBERS); + boolean haveCPExtra = testBit(archiveOptions, AO_HAVE_CP_EXTRAS); initAttrIndexLimit(); // now we are ready to use the data: @@ -300,11 +295,11 @@ class PackageReader extends BandStructure { archive_header_S.doneDisbursing(); archiveSize0 = in.getBytesServed(); - int remainingHeaders = AH_LENGTH - AH_LENGTH_0 - AH_LENGTH_S; - if (!haveFiles) remainingHeaders -= AH_FILE_HEADER_LEN-AH_LENGTH_S; - if (!haveSpecial) remainingHeaders -= AH_SPECIAL_FORMAT_LEN; - if (!haveNumbers) remainingHeaders -= AH_CP_NUMBER_LEN; - assert(remainingHeaders >= AH_LENGTH_MIN - AH_LENGTH_0); + int remainingHeaders = AH_LENGTH_MIN - AH_LENGTH_0 - AH_LENGTH_S; + if (haveFiles) remainingHeaders += AH_FILE_HEADER_LEN; + if (haveSpecial) remainingHeaders += AH_SPECIAL_FORMAT_LEN; + if (haveNumbers) remainingHeaders += AH_CP_NUMBER_LEN; + if (haveCPExtra) remainingHeaders += AH_CP_EXTRA_LEN; archive_header_1.expectLength(remainingHeaders); archive_header_1.readFrom(in); @@ -325,7 +320,7 @@ class PackageReader extends BandStructure { numAttrDefs = 0; } - readConstantPoolCounts(haveNumbers); + readConstantPoolCounts(haveNumbers, haveCPExtra); numInnerClasses = archive_header_1.getInt(); @@ -351,7 +346,7 @@ class PackageReader extends BandStructure { band_headers.doneDisbursing(); } - void readConstantPoolCounts(boolean haveNumbers) throws IOException { + void readConstantPoolCounts(boolean haveNumbers, boolean haveCPExtra) throws IOException { // size the constant pools: for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) { // cp_counts: @@ -364,6 +359,7 @@ class PackageReader extends BandStructure { // #cp_Field_count :UNSIGNED5[1] // #cp_Method_count :UNSIGNED5[1] // #cp_Imethod_count :UNSIGNED5[1] + // (cp_attr_counts) ** (#have_cp_attr_counts) // // cp_number_counts: // #cp_Int_count :UNSIGNED5[1] @@ -371,6 +367,12 @@ class PackageReader extends BandStructure { // #cp_Long_count :UNSIGNED5[1] // #cp_Double_count :UNSIGNED5[1] // + // cp_extra_counts: + // #cp_MethodHandle_count :UNSIGNED5[1] + // #cp_MethodType_count :UNSIGNED5[1] + // #cp_InvokeDynamic_count :UNSIGNED5[1] + // #cp_BootstrapMethod_count :UNSIGNED5[1] + // byte tag = ConstantPool.TAGS_IN_ORDER[k]; if (!haveNumbers) { // These four counts are optional. @@ -382,6 +384,16 @@ class PackageReader extends BandStructure { continue; } } + if (!haveCPExtra) { + // These four counts are optional. + switch (tag) { + case CONSTANT_MethodHandle: + case CONSTANT_MethodType: + case CONSTANT_InvokeDynamic: + case CONSTANT_BootstrapMethod: + continue; + } + } tagCount[tag] = archive_header_1.getInt(); } } @@ -401,6 +413,11 @@ class PackageReader extends BandStructure { return index; } + void checkLegacy(String bandname) { + if (this.pkg.package_majver < JAVA7_PACKAGE_MAJOR_VERSION) { + throw new RuntimeException("unexpected band " + bandname); + } + } void readConstantPool() throws IOException { // cp_bands: // cp_Utf8 @@ -533,8 +550,82 @@ class PackageReader extends BandStructure { case CONSTANT_InterfaceMethodref: readMemberRefs(tag, cpMap, cp_Imethod_class, cp_Imethod_desc); break; + case CONSTANT_MethodHandle: + if (cpMap.length > 0) { + checkLegacy(cp_MethodHandle_refkind.name()); + } + cp_MethodHandle_refkind.expectLength(cpMap.length); + cp_MethodHandle_refkind.readFrom(in); + cp_MethodHandle_member.expectLength(cpMap.length); + cp_MethodHandle_member.readFrom(in); + cp_MethodHandle_member.setIndex(getCPIndex(CONSTANT_AnyMember)); + for (int i = 0; i < cpMap.length; i++) { + byte refKind = (byte) cp_MethodHandle_refkind.getInt(); + MemberEntry memRef = (MemberEntry) cp_MethodHandle_member.getRef(); + cpMap[i] = ConstantPool.getMethodHandleEntry(refKind, memRef); + } + cp_MethodHandle_refkind.doneDisbursing(); + cp_MethodHandle_member.doneDisbursing(); + break; + case CONSTANT_MethodType: + if (cpMap.length > 0) { + checkLegacy(cp_MethodType.name()); + } + cp_MethodType.expectLength(cpMap.length); + cp_MethodType.readFrom(in); + cp_MethodType.setIndex(getCPIndex(CONSTANT_Signature)); + for (int i = 0; i < cpMap.length; i++) { + SignatureEntry typeRef = (SignatureEntry) cp_MethodType.getRef(); + cpMap[i] = ConstantPool.getMethodTypeEntry(typeRef); + } + cp_MethodType.doneDisbursing(); + break; + case CONSTANT_InvokeDynamic: + if (cpMap.length > 0) { + checkLegacy(cp_InvokeDynamic_spec.name()); + } + cp_InvokeDynamic_spec.expectLength(cpMap.length); + cp_InvokeDynamic_spec.readFrom(in); + cp_InvokeDynamic_spec.setIndex(getCPIndex(CONSTANT_BootstrapMethod)); + cp_InvokeDynamic_desc.expectLength(cpMap.length); + cp_InvokeDynamic_desc.readFrom(in); + cp_InvokeDynamic_desc.setIndex(getCPIndex(CONSTANT_NameandType)); + for (int i = 0; i < cpMap.length; i++) { + BootstrapMethodEntry bss = (BootstrapMethodEntry) cp_InvokeDynamic_spec.getRef(); + DescriptorEntry descr = (DescriptorEntry) cp_InvokeDynamic_desc.getRef(); + cpMap[i] = ConstantPool.getInvokeDynamicEntry(bss, descr); + } + cp_InvokeDynamic_spec.doneDisbursing(); + cp_InvokeDynamic_desc.doneDisbursing(); + break; + case CONSTANT_BootstrapMethod: + if (cpMap.length > 0) { + checkLegacy(cp_BootstrapMethod_ref.name()); + } + cp_BootstrapMethod_ref.expectLength(cpMap.length); + cp_BootstrapMethod_ref.readFrom(in); + cp_BootstrapMethod_ref.setIndex(getCPIndex(CONSTANT_MethodHandle)); + cp_BootstrapMethod_arg_count.expectLength(cpMap.length); + cp_BootstrapMethod_arg_count.readFrom(in); + int totalArgCount = cp_BootstrapMethod_arg_count.getIntTotal(); + cp_BootstrapMethod_arg.expectLength(totalArgCount); + cp_BootstrapMethod_arg.readFrom(in); + cp_BootstrapMethod_arg.setIndex(getCPIndex(CONSTANT_LoadableValue)); + for (int i = 0; i < cpMap.length; i++) { + MethodHandleEntry bsm = (MethodHandleEntry) cp_BootstrapMethod_ref.getRef(); + int argc = cp_BootstrapMethod_arg_count.getInt(); + Entry[] argRefs = new Entry[argc]; + for (int j = 0; j < argc; j++) { + argRefs[j] = cp_BootstrapMethod_arg.getRef(); + } + cpMap[i] = ConstantPool.getBootstrapMethodEntry(bsm, argRefs); + } + cp_BootstrapMethod_ref.doneDisbursing(); + cp_BootstrapMethod_arg_count.doneDisbursing(); + cp_BootstrapMethod_arg.doneDisbursing(); + break; default: - assert(false); + throw new AssertionError("unexpected CP tag in package"); } Index index = initCPIndex(tag, cpMap); @@ -548,6 +639,21 @@ class PackageReader extends BandStructure { cp_bands.doneDisbursing(); + if (optDumpBands || verbose > 1) { + for (byte tag = CONSTANT_GroupFirst; tag < CONSTANT_GroupLimit; tag++) { + Index index = pkg.cp.getIndexByTag(tag); + if (index == null || index.isEmpty()) continue; + Entry[] cpMap = index.cpMap; + if (verbose > 1) + Utils.log.info("Index group "+ConstantPool.tagName(tag)+" contains "+cpMap.length+" entries."); + if (optDumpBands) { + try (PrintStream ps = new PrintStream(getDumpStream(index.debugName, tag, ".gidx", index))) { + printArrayTo(ps, cpMap, 0, cpMap.length, true); + } + } + } + } + setBandIndexes(); } @@ -1056,8 +1162,16 @@ class PackageReader extends BandStructure { // look for constant pool entries: cls.visitRefs(VRM_CLASSIC, cpRefs); + ArrayList bsms = new ArrayList<>(); + /* + * BootstrapMethod(BSMs) are added here before InnerClasses(ICs), + * so as to ensure the order. Noting that the BSMs may be + * removed if they are not found in the CP, after the ICs expansion. + */ + cls.addAttribute(Package.attrBootstrapMethodsEmpty.canonicalInstance()); + // flesh out the local constant pool - ConstantPool.completeReferencesIn(cpRefs, true); + ConstantPool.completeReferencesIn(cpRefs, true, bsms); // Now that we know all our local class references, // compute the InnerClasses attribute. @@ -1074,14 +1188,23 @@ class PackageReader extends BandStructure { } // flesh out the local constant pool, again - ConstantPool.completeReferencesIn(cpRefs, true); + ConstantPool.completeReferencesIn(cpRefs, true, bsms); + } + + // remove the attr previously set, otherwise add the bsm and + // references as required + if (bsms.isEmpty()) { + cls.attributes.remove(Package.attrBootstrapMethodsEmpty.canonicalInstance()); + } else { + cpRefs.add(Package.getRefString("BootstrapMethods")); + Collections.sort(bsms); + cls.setBootstrapMethods(bsms); } // construct a local constant pool int numDoubles = 0; for (Entry e : cpRefs) { if (e.isDoubleWord()) numDoubles++; - assert(e.tag != CONSTANT_Signature) : (e); } Entry[] cpMap = new Entry[1+numDoubles+cpRefs.size()]; int fillp = 1; @@ -1154,7 +1277,8 @@ class PackageReader extends BandStructure { int totalNM = class_method_count.getIntTotal(); field_descr.expectLength(totalNF); method_descr.expectLength(totalNM); - if (verbose > 1) Utils.log.fine("expecting #fields="+totalNF+" and #methods="+totalNM+" in #classes="+numClasses); + if (verbose > 1) Utils.log.fine("expecting #fields="+totalNF+ + " and #methods="+totalNM+" in #classes="+numClasses); List fields = new ArrayList<>(totalNF); field_descr.readFrom(in); @@ -1393,7 +1517,8 @@ class PackageReader extends BandStructure { MultiBand xxx_attr_bands = attrBands[ctype]; long flagMask = attrFlagMask[ctype]; if (verbose > 1) { - Utils.log.fine("scanning flags and attrs for "+Attribute.contextName(ctype)+"["+holders.size()+"]"); + Utils.log.fine("scanning flags and attrs for "+ + Attribute.contextName(ctype)+"["+holders.size()+"]"); } // Fetch the attribute layout definitions which govern the bands @@ -1751,8 +1876,10 @@ class PackageReader extends BandStructure { bc_local, bc_label, bc_intref, bc_floatref, bc_longref, bc_doubleref, bc_stringref, + bc_loadablevalueref, bc_classref, bc_fieldref, bc_methodref, bc_imethodref, + bc_indyref, bc_thisfield, bc_superfield, bc_thismethod, bc_supermethod, bc_initref, @@ -2099,7 +2226,8 @@ class PackageReader extends BandStructure { case _ildc: case _cldc: case _fldc: - case _aldc: + case _sldc: + case _qldc: origBC = _ldc; size = 1; ldcRefSet.add(ref); @@ -2107,7 +2235,8 @@ class PackageReader extends BandStructure { case _ildc_w: case _cldc_w: case _fldc_w: - case _aldc_w: + case _sldc_w: + case _qldc_w: origBC = _ldc_w; break; case _lldc2_w: @@ -2136,6 +2265,9 @@ class PackageReader extends BandStructure { int argSize = ((MemberEntry)ref).descRef.typeRef.computeSize(true); buf[pc++] = (byte)( 1 + argSize ); buf[pc++] = 0; + } else if (origBC == _invokedynamic) { + buf[pc++] = 0; + buf[pc++] = 0; } assert(Instruction.opLength(origBC) == (pc - curPC)); continue; diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java index 0f7f51a7ec3..d40a6d3889e 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,7 @@ package com.sun.java.util.jar.pack; -import com.sun.java.util.jar.pack.ConstantPool.ClassEntry; -import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry; -import com.sun.java.util.jar.pack.ConstantPool.Entry; -import com.sun.java.util.jar.pack.ConstantPool.Index; -import com.sun.java.util.jar.pack.ConstantPool.IndexGroup; -import com.sun.java.util.jar.pack.ConstantPool.MemberEntry; -import com.sun.java.util.jar.pack.ConstantPool.NumberEntry; -import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry; -import com.sun.java.util.jar.pack.ConstantPool.StringEntry; +import com.sun.java.util.jar.pack.ConstantPool.*; import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.Package.File; import com.sun.java.util.jar.pack.Package.InnerClass; @@ -281,7 +273,7 @@ class PackageWriter extends BandStructure { void writeArchiveHeader() throws IOException { // for debug only: number of words optimized away - int headerDiscountForDebug = 0; + int headerSizeForDebug = AH_LENGTH_MIN; // AO_HAVE_SPECIAL_FORMATS is set if non-default // coding techniques are used, or if there are @@ -293,8 +285,8 @@ class PackageWriter extends BandStructure { if (haveSpecial) archiveOptions |= AO_HAVE_SPECIAL_FORMATS; } - if (!haveSpecial) - headerDiscountForDebug += AH_SPECIAL_FORMAT_LEN; + if (haveSpecial) + headerSizeForDebug += AH_SPECIAL_FORMAT_LEN; // AO_HAVE_FILE_HEADERS is set if there is any // file or segment envelope information present. @@ -305,8 +297,8 @@ class PackageWriter extends BandStructure { if (haveFiles) archiveOptions |= AO_HAVE_FILE_HEADERS; } - if (!haveFiles) - headerDiscountForDebug += AH_FILE_HEADER_LEN; + if (haveFiles) + headerSizeForDebug += AH_FILE_HEADER_LEN; // AO_HAVE_CP_NUMBERS is set if there are any numbers // in the global constant pool. (Numbers are in 15% of classes.) @@ -316,8 +308,19 @@ class PackageWriter extends BandStructure { if (haveNumbers) archiveOptions |= AO_HAVE_CP_NUMBERS; } - if (!haveNumbers) - headerDiscountForDebug += AH_CP_NUMBER_LEN; + if (haveNumbers) + headerSizeForDebug += AH_CP_NUMBER_LEN; + + // AO_HAVE_CP_EXTRAS is set if there are constant pool entries + // beyond the Java 6 version of the class file format. + boolean haveCPExtra = testBit(archiveOptions, AO_HAVE_CP_EXTRAS); + if (!haveCPExtra) { + haveCPExtra |= pkg.cp.haveExtraTags(); + if (haveCPExtra) + archiveOptions |= AO_HAVE_CP_EXTRAS; + } + if (haveCPExtra) + headerSizeForDebug += AH_CP_EXTRA_LEN; assert(pkg.package_majver > 0); // caller must specify! archive_header_0.putInt(pkg.package_minver); @@ -355,18 +358,18 @@ class PackageWriter extends BandStructure { assert(attrDefsWritten.length == 0); } - writeConstantPoolCounts(haveNumbers); + writeConstantPoolCounts(haveNumbers, haveCPExtra); archive_header_1.putInt(pkg.getAllInnerClasses().size()); archive_header_1.putInt(pkg.default_class_minver); archive_header_1.putInt(pkg.default_class_majver); archive_header_1.putInt(pkg.classes.size()); - // Sanity: Make sure we came out to 26 (less optional fields): + // Sanity: Make sure we came out to 29 (less optional fields): assert(archive_header_0.length() + archive_header_S.length() + archive_header_1.length() - == AH_LENGTH - headerDiscountForDebug); + == headerSizeForDebug); // Figure out all the sizes now, first cut: archiveSize0 = 0; @@ -394,9 +397,8 @@ class PackageWriter extends BandStructure { assert(all_bands.outputSize() == archiveSize0+archiveSize1); } - void writeConstantPoolCounts(boolean haveNumbers) throws IOException { - for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) { - byte tag = ConstantPool.TAGS_IN_ORDER[k]; + void writeConstantPoolCounts(boolean haveNumbers, boolean haveCPExtra) throws IOException { + for (byte tag : ConstantPool.TAGS_IN_ORDER) { int count = pkg.cp.getIndexByTag(tag).size(); switch (tag) { case CONSTANT_Utf8: @@ -416,6 +418,17 @@ class PackageWriter extends BandStructure { continue; } break; + + case CONSTANT_MethodHandle: + case CONSTANT_MethodType: + case CONSTANT_InvokeDynamic: + case CONSTANT_BootstrapMethod: + // Omit counts for newer entities if possible. + if (!haveCPExtra) { + assert(count == 0); + continue; + } + break; } archive_header_1.putInt(count); } @@ -449,8 +462,7 @@ class PackageWriter extends BandStructure { if (verbose > 0) Utils.log.info("Writing CP"); - for (int k = 0; k < ConstantPool.TAGS_IN_ORDER.length; k++) { - byte tag = ConstantPool.TAGS_IN_ORDER[k]; + for (byte tag : ConstantPool.TAGS_IN_ORDER) { Index index = cp.getIndexByTag(tag); Entry[] cpMap = index.cpMap; @@ -530,8 +542,52 @@ class PackageWriter extends BandStructure { case CONSTANT_InterfaceMethodref: writeMemberRefs(tag, cpMap, cp_Imethod_class, cp_Imethod_desc); break; + case CONSTANT_MethodHandle: + for (int i = 0; i < cpMap.length; i++) { + MethodHandleEntry e = (MethodHandleEntry) cpMap[i]; + cp_MethodHandle_refkind.putInt(e.refKind); + cp_MethodHandle_member.putRef(e.memRef); + } + break; + case CONSTANT_MethodType: + for (int i = 0; i < cpMap.length; i++) { + MethodTypeEntry e = (MethodTypeEntry) cpMap[i]; + cp_MethodType.putRef(e.typeRef); + } + break; + case CONSTANT_InvokeDynamic: + for (int i = 0; i < cpMap.length; i++) { + InvokeDynamicEntry e = (InvokeDynamicEntry) cpMap[i]; + cp_InvokeDynamic_spec.putRef(e.bssRef); + cp_InvokeDynamic_desc.putRef(e.descRef); + } + break; + case CONSTANT_BootstrapMethod: + for (int i = 0; i < cpMap.length; i++) { + BootstrapMethodEntry e = (BootstrapMethodEntry) cpMap[i]; + cp_BootstrapMethod_ref.putRef(e.bsmRef); + cp_BootstrapMethod_arg_count.putInt(e.argRefs.length); + for (Entry argRef : e.argRefs) { + cp_BootstrapMethod_arg.putRef(argRef); + } + } + break; default: - assert(false); + throw new AssertionError("unexpected CP tag in package"); + } + } + if (optDumpBands || verbose > 1) { + for (byte tag = CONSTANT_GroupFirst; tag < CONSTANT_GroupLimit; tag++) { + Index index = cp.getIndexByTag(tag); + if (index == null || index.isEmpty()) continue; + Entry[] cpMap = index.cpMap; + if (verbose > 1) + Utils.log.info("Index group "+ConstantPool.tagName(tag)+" contains "+cpMap.length+" entries."); + if (optDumpBands) { + try (PrintStream ps = new PrintStream(getDumpStream(index.debugName, tag, ".gidx", index))) { + printArrayTo(ps, cpMap, 0, cpMap.length, true); + } + } } } } @@ -988,6 +1044,8 @@ class PackageWriter extends BandStructure { for (Class cls : pkg.classes) { // Replace "obvious" SourceFile attrs by null. cls.minimizeSourceFile(); + // BootstrapMethods should never have been inserted. + assert(cls.getAttribute(Package.attrBootstrapMethodsEmpty) == null); } } @@ -1325,9 +1383,7 @@ class PackageWriter extends BandStructure { // %%% Add a stress mode which issues _ref/_byte_escape. if (verbose > 3) Utils.log.fine(i.toString()); - if (i.isNonstandard() - && (!p200.getBoolean(Utils.COM_PREFIX+"invokedynamic") - || i.getBC() != _xxxunusedxxx)) { + if (i.isNonstandard()) { // Crash and burn with a complaint if there are funny // bytecodes in this class file. String complaint = code.getMethod() @@ -1427,24 +1483,6 @@ class PackageWriter extends BandStructure { continue; } - switch (bc) { - case _xxxunusedxxx: // %%% pretend this is invokedynamic - { - i.setNonstandardLength(3); - int refx = i.getShortAt(1); - Entry ref = (refx == 0)? null: curCPMap[refx]; - // transmit the opcode, carefully: - bc_codes.putByte(_byte_escape); - bc_escsize.putInt(1); // one byte of opcode - bc_escbyte.putByte(bc); // the opcode - // transmit the CP reference, carefully: - bc_codes.putByte(_ref_escape); - bc_escrefsize.putInt(2); // two bytes of ref - bc_escref.putRef(ref); // the ref - continue; - } - } - int branch = i.getBranchLabel(); if (branch >= 0) { bc_codes.putByte(bc); @@ -1458,7 +1496,7 @@ class PackageWriter extends BandStructure { CPRefBand bc_which; int vbc = bc; switch (i.getCPTag()) { - case CONSTANT_Literal: + case CONSTANT_LoadableValue: switch (ref.tag) { case CONSTANT_Integer: bc_which = bc_intref; @@ -1489,8 +1527,8 @@ class PackageWriter extends BandStructure { case CONSTANT_String: bc_which = bc_stringref; switch (bc) { - case _ldc: vbc = _aldc; break; - case _ldc_w: vbc = _aldc_w; break; + case _ldc: vbc = _sldc; break; + case _ldc_w: vbc = _sldc_w; break; default: assert(false); } break; @@ -1503,8 +1541,16 @@ class PackageWriter extends BandStructure { } break; default: - bc_which = null; - assert(false); + // CONSTANT_MethodHandle, etc. + if (getPackageMajver() < JAVA7_PACKAGE_MAJOR_VERSION) { + throw new IOException("bad package major version for Java 7 ldc"); + } + bc_which = bc_loadablevalueref; + switch (bc) { + case _ldc: vbc = _qldc; break; + case _ldc_w: vbc = _qldc_w; break; + default: assert(false); + } } break; case CONSTANT_Class: @@ -1517,6 +1563,8 @@ class PackageWriter extends BandStructure { bc_which = bc_methodref; break; case CONSTANT_InterfaceMethodref: bc_which = bc_imethodref; break; + case CONSTANT_InvokeDynamic: + bc_which = bc_indyref; break; default: bc_which = null; assert(false); @@ -1532,6 +1580,12 @@ class PackageWriter extends BandStructure { assert(i.getLength() == 5); // Make sure the discarded bytes are sane: assert(i.getConstant() == (1+((MemberEntry)ref).descRef.typeRef.computeSize(true)) << 8); + } else if (bc == _invokedynamic) { + if (getPackageMajver() < JAVA7_PACKAGE_MAJOR_VERSION) { + throw new IOException("bad package major version for Java 7 invokedynamic"); + } + assert(i.getLength() == 5); + assert(i.getConstant() == 0); // last 2 bytes MBZ } else { // Make sure there is nothing else to write. assert(i.getLength() == ((bc == _ldc)?2:3)); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/TLGlobals.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/TLGlobals.java index fc9d0998870..12316768bb2 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/TLGlobals.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/TLGlobals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,10 @@ import com.sun.java.util.jar.pack.ConstantPool.ClassEntry; import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry; import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry; import com.sun.java.util.jar.pack.ConstantPool.MemberEntry; +import com.sun.java.util.jar.pack.ConstantPool.MethodHandleEntry; +import com.sun.java.util.jar.pack.ConstantPool.MethodTypeEntry; +import com.sun.java.util.jar.pack.ConstantPool.InvokeDynamicEntry; +import com.sun.java.util.jar.pack.ConstantPool.BootstrapMethodEntry; import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry; import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry; import java.util.HashMap; @@ -56,6 +60,10 @@ class TLGlobals { private final Map signatureEntries; private final Map descriptorEntries; private final Map memberEntries; + private final Map methodHandleEntries; + private final Map methodTypeEntries; + private final Map invokeDynamicEntries; + private final Map bootstrapMethodEntries; TLGlobals() { utf8Entries = new HashMap<>(); @@ -64,6 +72,10 @@ class TLGlobals { signatureEntries = new HashMap<>(); descriptorEntries = new HashMap<>(); memberEntries = new HashMap<>(); + methodHandleEntries = new HashMap<>(); + methodTypeEntries = new HashMap<>(); + invokeDynamicEntries = new HashMap<>(); + bootstrapMethodEntries = new HashMap<>(); props = new PropMap(); } @@ -94,4 +106,20 @@ class TLGlobals { Map getMemberEntries() { return memberEntries; } + + Map getMethodHandleEntries() { + return methodHandleEntries; + } + + Map getMethodTypeEntries() { + return methodTypeEntries; + } + + Map getInvokeDynamicEntries() { + return invokeDynamicEntries; + } + + Map getBootstrapMethodEntries() { + return bootstrapMethodEntries; + } } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java index f9d26eb306a..06ecaef5bbf 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -60,7 +60,7 @@ class Utils { * If >3, print tons of comments (e.g., processing of references). * (installer only) */ - static final String DEBUG_VERBOSE = Utils.COM_PREFIX+"verbose"; + static final String DEBUG_VERBOSE = COM_PREFIX+"verbose"; /* * Disables use of native code, prefers the Java-coded implementation. @@ -134,35 +134,11 @@ class Utils { // to the engine code, especially the native code. static final ThreadLocal currentInstance = new ThreadLocal<>(); - // convenience methods to access the TL globals + // convenience method to access the TL globals static TLGlobals getTLGlobals() { return currentInstance.get(); } - static Map getUtf8Entries() { - return getTLGlobals().getUtf8Entries(); - } - - static Map getClassEntries() { - return getTLGlobals().getClassEntries(); - } - - static Map getLiteralEntries() { - return getTLGlobals().getLiteralEntries(); - } - - static Map getDescriptorEntries() { - return getTLGlobals().getDescriptorEntries(); - } - - static Map getSignatureEntries() { - return getTLGlobals().getSignatureEntries(); - } - - static Map getMemberEntries() { - return getTLGlobals().getMemberEntries(); - } - static PropMap currentPropMap() { Object obj = currentInstance.get(); if (obj instanceof PackerImpl) @@ -173,8 +149,19 @@ class Utils { } static final boolean nolog - = Boolean.getBoolean(Utils.COM_PREFIX+"nolog"); + = Boolean.getBoolean(COM_PREFIX+"nolog"); + static final boolean SORT_MEMBERS_DESCR_MAJOR + = Boolean.getBoolean(COM_PREFIX+"sort.members.descr.major"); + + static final boolean SORT_HANDLES_KIND_MAJOR + = Boolean.getBoolean(COM_PREFIX+"sort.handles.kind.major"); + + static final boolean SORT_INDY_BSS_MAJOR + = Boolean.getBoolean(COM_PREFIX+"sort.indy.bss.major"); + + static final boolean SORT_BSS_BSM_MAJOR + = Boolean.getBoolean(COM_PREFIX+"sort.bss.bsm.major"); static class Pack200Logger { private final String name; diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp index 88955faec34..08cdc8d3e76 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012, 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 @@ -188,9 +188,13 @@ void band::setIndexByTag(byte tag) { entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) { CHECK_0; assert(ix_->ixTag == ixTag - || (ixTag == CONSTANT_Literal - && ix_->ixTag >= CONSTANT_Integer - && ix_->ixTag <= CONSTANT_String)); + || ((ixTag == CONSTANT_All || + ixTag == CONSTANT_LoadableValue || + ixTag == CONSTANT_AnyMember) + || (ixTag == CONSTANT_FieldSpecific && + ix_->ixTag >= CONSTANT_Integer && + ix_->ixTag <= CONSTANT_String)) + ); int n = vs[0].getInt() - nullOK; // Note: band-local nullOK means null encodes as 0. // But nullOKwithCaller means caller is willing to tolerate a null. @@ -270,22 +274,15 @@ int band::getIntCount(int tag) { #define NO_INDEX 0 struct band_init { -#ifndef PRODUCT int bn; const char* name; -#endif int defc; int index; }; -#ifdef PRODUCT -#define BAND_INIT(name, cspec, ix) \ - { cspec, ix } -#else #define BAND_INIT(name, cspec, ix) \ { e_##name, #name, /*debug only*/ \ cspec, ix } -#endif const band_init all_band_inits[] = { //BAND_INIT(archive_magic, BYTE1_spec, 0), @@ -314,6 +311,14 @@ const band_init all_band_inits[] = { BAND_INIT(cp_Method_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), BAND_INIT(cp_Imethod_class, DELTA5_spec, INDEX(CONSTANT_Class)), BAND_INIT(cp_Imethod_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), + BAND_INIT(cp_MethodHandle_refkind, DELTA5_spec, 0), + BAND_INIT(cp_MethodHandle_member, UDELTA5_spec, INDEX(CONSTANT_AnyMember)), + BAND_INIT(cp_MethodType, UDELTA5_spec, INDEX(CONSTANT_Signature)), + BAND_INIT(cp_BootstrapMethod_ref, DELTA5_spec, INDEX(CONSTANT_MethodHandle)), + BAND_INIT(cp_BootstrapMethod_arg_count, UDELTA5_spec, 0), + BAND_INIT(cp_BootstrapMethod_arg, DELTA5_spec, INDEX(CONSTANT_LoadableValue)), + BAND_INIT(cp_InvokeDynamic_spec, DELTA5_spec, INDEX(CONSTANT_BootstrapMethod)), + BAND_INIT(cp_InvokeDynamic_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), BAND_INIT(attr_definition_headers, BYTE1_spec, 0), BAND_INIT(attr_definition_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), BAND_INIT(attr_definition_layout, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), @@ -333,7 +338,7 @@ const band_init all_band_inits[] = { BAND_INIT(field_attr_count, UNSIGNED5_spec, 0), BAND_INIT(field_attr_indexes, UNSIGNED5_spec, 0), BAND_INIT(field_attr_calls, UNSIGNED5_spec, 0), - BAND_INIT(field_ConstantValue_KQ, UNSIGNED5_spec, INDEX(CONSTANT_Literal)), + BAND_INIT(field_ConstantValue_KQ, UNSIGNED5_spec, INDEX(CONSTANT_FieldSpecific)), BAND_INIT(field_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), BAND_INIT(field_metadata_bands, -1, -1), BAND_INIT(field_attr_bands, -1, -1), @@ -415,10 +420,12 @@ const band_init all_band_inits[] = { BAND_INIT(bc_longref, DELTA5_spec, INDEX(CONSTANT_Long)), BAND_INIT(bc_doubleref, DELTA5_spec, INDEX(CONSTANT_Double)), BAND_INIT(bc_stringref, DELTA5_spec, INDEX(CONSTANT_String)), + BAND_INIT(bc_loadablevalueref, DELTA5_spec, INDEX(CONSTANT_LoadableValue)), BAND_INIT(bc_classref, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)), BAND_INIT(bc_fieldref, DELTA5_spec, INDEX(CONSTANT_Fieldref)), BAND_INIT(bc_methodref, UNSIGNED5_spec, INDEX(CONSTANT_Methodref)), BAND_INIT(bc_imethodref, DELTA5_spec, INDEX(CONSTANT_InterfaceMethodref)), + BAND_INIT(bc_indyref, DELTA5_spec, INDEX(CONSTANT_InvokeDynamic)), BAND_INIT(bc_thisfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)), BAND_INIT(bc_superfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)), BAND_INIT(bc_thismethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)), @@ -471,7 +478,7 @@ void band::initIndexes(unpacker* u) { for (int i = 0; i < BAND_LIMIT; i++) { band* scan = &tmp_all_bands[i]; uint tag = scan->ixTag; // Cf. #define INDEX(tag) above - if (tag != 0 && tag != CONSTANT_Literal && (tag & SUBINDEX_BIT) == 0) { + if (tag != 0 && tag != CONSTANT_FieldSpecific && (tag & SUBINDEX_BIT) == 0) { scan->setIndex(u->cp.getIndex(tag)); } } diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h b/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h index 8e15dcb0111..b8e322aa1db 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/bands.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,7 @@ struct cpindex; struct unpacker; struct band { -#ifndef PRODUCT const char* name; -#endif int bn; // band_number of this band coding* defc; // default coding method cpindex* ix; // CP entry mapping, if CPRefBand @@ -162,6 +160,14 @@ enum band_number { e_cp_Method_desc, e_cp_Imethod_class, e_cp_Imethod_desc, + e_cp_MethodHandle_refkind, + e_cp_MethodHandle_member, + e_cp_MethodType, + e_cp_BootstrapMethod_ref, + e_cp_BootstrapMethod_arg_count, + e_cp_BootstrapMethod_arg, + e_cp_InvokeDynamic_spec, + e_cp_InvokeDynamic_desc, // bands which define transmission of attributes e_attr_definition_headers, @@ -284,11 +290,13 @@ enum band_number { e_bc_longref, e_bc_doubleref, e_bc_stringref, + e_bc_loadablevalueref, e_bc_classref, e_bc_fieldref, e_bc_methodref, e_bc_imethodref, + e_bc_indyref, // _self_linker_op family e_bc_thisfield, @@ -343,6 +351,14 @@ enum band_number { #define cp_Method_desc all_bands[e_cp_Method_desc] #define cp_Imethod_class all_bands[e_cp_Imethod_class] #define cp_Imethod_desc all_bands[e_cp_Imethod_desc] +#define cp_MethodHandle_refkind all_bands[e_cp_MethodHandle_refkind] +#define cp_MethodHandle_member all_bands[e_cp_MethodHandle_member] +#define cp_MethodType all_bands[e_cp_MethodType] +#define cp_BootstrapMethod_ref all_bands[e_cp_BootstrapMethod_ref] +#define cp_BootstrapMethod_arg_count all_bands[e_cp_BootstrapMethod_arg_count] +#define cp_BootstrapMethod_arg all_bands[e_cp_BootstrapMethod_arg] +#define cp_InvokeDynamic_spec all_bands[e_cp_InvokeDynamic_spec] +#define cp_InvokeDynamic_desc all_bands[e_cp_InvokeDynamic_desc] #define attr_definition_headers all_bands[e_attr_definition_headers] #define attr_definition_name all_bands[e_attr_definition_name] #define attr_definition_layout all_bands[e_attr_definition_layout] @@ -437,10 +453,12 @@ enum band_number { #define bc_longref all_bands[e_bc_longref] #define bc_doubleref all_bands[e_bc_doubleref] #define bc_stringref all_bands[e_bc_stringref] +#define bc_loadablevalueref all_bands[e_bc_loadablevalueref] #define bc_classref all_bands[e_bc_classref] #define bc_fieldref all_bands[e_bc_fieldref] #define bc_methodref all_bands[e_bc_methodref] #define bc_imethodref all_bands[e_bc_imethodref] +#define bc_indyref all_bands[e_bc_indyref] #define bc_thisfield all_bands[e_bc_thisfield] #define bc_superfield all_bands[e_bc_superfield] #define bc_thismethod all_bands[e_bc_thismethod] diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h b/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h index 22a6b6c3e58..a3a8c553368 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -49,61 +49,82 @@ #define JAVA6_PACKAGE_MAJOR_VERSION 160 #define JAVA6_PACKAGE_MINOR_VERSION 1 +#define JAVA7_PACKAGE_MAJOR_VERSION 170 +#define JAVA7_PACKAGE_MINOR_VERSION 1 // magic number for gzip streams (for processing pack200-gzip data) #define GZIP_MAGIC 0x1F8B0800 #define GZIP_MAGIC_MASK 0xFFFFFF00 // last byte is variable "flg" field enum { - CONSTANT_None, - CONSTANT_Utf8, - CONSTANT_unused2, /* unused, was Unicode */ - CONSTANT_Integer, - CONSTANT_Float, - CONSTANT_Long, - CONSTANT_Double, - CONSTANT_Class, - CONSTANT_String, - CONSTANT_Fieldref, - CONSTANT_Methodref, - CONSTANT_InterfaceMethodref, - CONSTANT_NameandType, + CONSTANT_None = 0, + CONSTANT_Utf8 = 1, + CONSTANT_unused = 2, /* unused, was Unicode */ + CONSTANT_Integer = 3, + CONSTANT_Float = 4, + CONSTANT_Long = 5, + CONSTANT_Double = 6, + CONSTANT_Class = 7, + CONSTANT_String = 8, + CONSTANT_Fieldref = 9, + CONSTANT_Methodref = 10, + CONSTANT_InterfaceMethodref = 11, + CONSTANT_NameandType = 12, + CONSTANT_unused13 = 13, + CONSTANT_unused14 = 14, + CONSTANT_MethodHandle = 15, + CONSTANT_MethodType = 16, + CONSTANT_unused17 = 17, + CONSTANT_InvokeDynamic = 18, + CONSTANT_Limit = 19, + CONSTANT_Signature = CONSTANT_unused13, + CONSTANT_BootstrapMethod = CONSTANT_unused17, // used only for InvokeDynamic + CONSTANT_All = 50, // combined global map + CONSTANT_LoadableValue = 51, // used for 'KL' and qldc operands + CONSTANT_AnyMember = 52, // union of refs to field or (interface) method + CONSTANT_FieldSpecific = 53, // used only for 'KQ' ConstantValue attrs + CONSTANT_GroupFirst = CONSTANT_All, // start group marker + CONSTANT_GroupLimit = 54, // end group marker - CONSTANT_Signature = 13, - CONSTANT_All = 14, - CONSTANT_Limit = 15, - CONSTANT_NONE = 0, - - CONSTANT_Literal = 20, //pseudo-tag for debugging - CONSTANT_Member = 21, //pseudo-tag for debugging + // CONSTANT_MethodHandle reference kinds + REF_getField = 1, + REF_getStatic = 2, + REF_putField = 3, + REF_putStatic = 4, + REF_invokeVirtual = 5, + REF_invokeStatic = 6, + REF_invokeSpecial = 7, + REF_newInvokeSpecial = 8, + REF_invokeInterface = 9, SUBINDEX_BIT = 64, // combined with CONSTANT_xxx for ixTag ACC_STATIC = 0x0008, ACC_IC_LONG_FORM = (1<<16), //for ic_flags - CLASS_ATTR_SourceFile = 17, - CLASS_ATTR_EnclosingMethod = 18, - CLASS_ATTR_InnerClasses = 23, - CLASS_ATTR_ClassFile_version = 24, - FIELD_ATTR_ConstantValue = 17, - METHOD_ATTR_Code = 17, - METHOD_ATTR_Exceptions = 18, - METHOD_ATTR_RuntimeVisibleParameterAnnotations = 23, + CLASS_ATTR_SourceFile = 17, + CLASS_ATTR_EnclosingMethod = 18, + CLASS_ATTR_InnerClasses = 23, + CLASS_ATTR_ClassFile_version = 24, + CLASS_ATTR_BootstrapMethods = 25, + FIELD_ATTR_ConstantValue = 17, + METHOD_ATTR_Code = 17, + METHOD_ATTR_Exceptions = 18, + METHOD_ATTR_RuntimeVisibleParameterAnnotations = 23, METHOD_ATTR_RuntimeInvisibleParameterAnnotations = 24, - METHOD_ATTR_AnnotationDefault = 25, - CODE_ATTR_StackMapTable = 0, - CODE_ATTR_LineNumberTable = 1, - CODE_ATTR_LocalVariableTable = 2, + METHOD_ATTR_AnnotationDefault = 25, + CODE_ATTR_StackMapTable = 0, + CODE_ATTR_LineNumberTable = 1, + CODE_ATTR_LocalVariableTable = 2, CODE_ATTR_LocalVariableTypeTable = 3, //X_ATTR_Synthetic = 12, // ACC_SYNTHETIC; not predefined - X_ATTR_Signature = 19, - X_ATTR_Deprecated = 20, - X_ATTR_RuntimeVisibleAnnotations = 21, + X_ATTR_Signature = 19, + X_ATTR_Deprecated = 20, + X_ATTR_RuntimeVisibleAnnotations = 21, X_ATTR_RuntimeInvisibleAnnotations = 22, - X_ATTR_OVERFLOW = 16, - X_ATTR_LIMIT_NO_FLAGS_HI = 32, - X_ATTR_LIMIT_FLAGS_HI = 63, + X_ATTR_OVERFLOW = 16, + X_ATTR_LIMIT_NO_FLAGS_HI = 32, + X_ATTR_LIMIT_FLAGS_HI = 63, #define O_ATTR_DO(F) \ F(X_ATTR_OVERFLOW,01) \ @@ -121,6 +142,7 @@ enum { F(CLASS_ATTR_InnerClasses,InnerClasses) \ F(CLASS_ATTR_EnclosingMethod,EnclosingMethod) \ F(CLASS_ATTR_ClassFile_version,02) \ + F(CLASS_ATTR_BootstrapMethods,BootstrapMethods) \ /*(end)*/ #define FIELD_ATTR_DO(F) \ F(FIELD_ATTR_ConstantValue,ConstantValue) \ @@ -175,7 +197,7 @@ enum { AO_HAVE_SPECIAL_FORMATS = 1<<0, AO_HAVE_CP_NUMBERS = 1<<1, AO_HAVE_ALL_CODE_FLAGS = 1<<2, - AO_3_UNUSED_MBZ = 1<<3, + AO_HAVE_CP_EXTRAS = 1<<3, AO_HAVE_FILE_HEADERS = 1<<4, AO_DEFLATE_HINT = 1<<5, AO_HAVE_FILE_MODTIME = 1<<6, @@ -185,11 +207,13 @@ enum { AO_HAVE_FIELD_FLAGS_HI = 1<<10, AO_HAVE_METHOD_FLAGS_HI = 1<<11, AO_HAVE_CODE_FLAGS_HI = 1<<12, + AO_UNUSED_MBZ = (-1)<<13, // options bits reserved for future use. + #define ARCHIVE_BIT_DO(F) \ F(AO_HAVE_SPECIAL_FORMATS) \ F(AO_HAVE_CP_NUMBERS) \ F(AO_HAVE_ALL_CODE_FLAGS) \ - /*F(AO_3_UNUSED_MBZ)*/ \ + F(AO_HAVE_CP_EXTRAS) \ F(AO_HAVE_FILE_HEADERS) \ F(AO_DEFLATE_HINT) \ F(AO_HAVE_FILE_MODTIME) \ @@ -215,14 +239,14 @@ enum { NO_MODTIME = 0, // null modtime value // meta-coding - _meta_default = 0, + _meta_default = 0, _meta_canon_min = 1, _meta_canon_max = 115, - _meta_arb = 116, - _meta_run = 117, - _meta_pop = 141, - _meta_limit = 189, - _meta_error = 255, + _meta_arb = 116, + _meta_run = 117, + _meta_pop = 141, + _meta_limit = 189, + _meta_error = 255, _xxx_1_end }; @@ -416,7 +440,7 @@ enum { bc_invokespecial = 183, // 0xb7 bc_invokestatic = 184, // 0xb8 bc_invokeinterface = 185, // 0xb9 - bc_xxxunusedxxx = 186, // 0xba + bc_invokedynamic = 186, // 0xba bc_new = 187, // 0xbb bc_newarray = 188, // 0xbc bc_anewarray = 189, // 0xbd @@ -455,17 +479,19 @@ enum { _invokeinit_limit = _invokeinit_op+3, _xldc_op = _invokeinit_limit, - bc_aldc = bc_ldc, + bc_sldc = bc_ldc, // previously named bc_aldc bc_cldc = _xldc_op+0, bc_ildc = _xldc_op+1, bc_fldc = _xldc_op+2, - bc_aldc_w = bc_ldc_w, + bc_sldc_w = bc_ldc_w, // previously named bc_aldc_w bc_cldc_w = _xldc_op+3, bc_ildc_w = _xldc_op+4, bc_fldc_w = _xldc_op+5, bc_lldc2_w = bc_ldc2_w, bc_dldc2_w = _xldc_op+6, - _xldc_limit = _xldc_op+7, - + // anything other primitive, string, or class must be handled with qldc: + bc_qldc = _xldc_op+7, + bc_qldc_w = _xldc_op+8, + _xldc_limit = _xldc_op+9, _xxx_3_end }; diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h b/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h index e49cade19b8..7fe36ffe576 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -109,7 +109,8 @@ typedef DWORDLONG julong; #define dup2(a,b) _dup2(a,b) #define strcasecmp(s1, s2) _stricmp(s1,s2) #define tempname _tempname -#define sleep Sleep +#define sleep Sleep +#define snprintf _snprintf #else typedef signed char byte; #ifdef _LP64 diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp index cee146d4db4..d7c51978ded 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, 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 @@ -81,7 +81,12 @@ static const byte TAGS_IN_ORDER[] = { CONSTANT_NameandType, CONSTANT_Fieldref, CONSTANT_Methodref, - CONSTANT_InterfaceMethodref + CONSTANT_InterfaceMethodref, + // constants defined as of JDK 7 + CONSTANT_MethodHandle, + CONSTANT_MethodType, + CONSTANT_BootstrapMethod, + CONSTANT_InvokeDynamic }; #define N_TAGS_IN_ORDER (sizeof TAGS_IN_ORDER) @@ -101,6 +106,11 @@ static const char* TAG_NAME[] = { "InterfaceMethodref", "NameandType", "*Signature", + "unused14", + "MethodHandle", + "MethodType", + "*BootstrapMethod", + "InvokeDynamic", 0 }; @@ -114,9 +124,13 @@ static const char* ATTR_CONTEXT_NAME[] = { // match ATTR_CONTEXT_NAME, etc. #endif - -// REQUESTED must be -2 for u2 and REQUESTED_LDC must be -1 for u1 -enum { NOT_REQUESTED = 0, REQUESTED = -2, REQUESTED_LDC = -1 }; +// Note that REQUESTED_LDC comes first, then the normal REQUESTED, +// in the regular constant pool. +enum { REQUESTED_NONE = -1, + // The codes below REQUESTED_NONE are in constant pool output order, + // for the sake of outputEntry_cmp: + REQUESTED_LDC = -99, REQUESTED +}; #define NO_INORD ((uint)-1) @@ -146,7 +160,7 @@ struct entry { void requestOutputIndex(cpool& cp, int req = REQUESTED); int getOutputIndex() { - assert(outputIndex > NOT_REQUESTED); + assert(outputIndex > REQUESTED_NONE); return outputIndex; } @@ -167,12 +181,12 @@ struct entry { } entry* memberClass() { - assert(tagMatches(CONSTANT_Member)); + assert(tagMatches(CONSTANT_AnyMember)); return ref(0); } entry* memberDescr() { - assert(tagMatches(CONSTANT_Member)); + assert(tagMatches(CONSTANT_AnyMember)); return ref(1); } @@ -199,9 +213,9 @@ struct entry { return (tag2 == tag) || (tag2 == CONSTANT_Utf8 && tag == CONSTANT_Signature) #ifndef PRODUCT - || (tag2 == CONSTANT_Literal + || (tag2 == CONSTANT_FieldSpecific && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class) - || (tag2 == CONSTANT_Member + || (tag2 == CONSTANT_AnyMember && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref) #endif ; @@ -309,6 +323,7 @@ void unpacker::free() { code_fixup_offset.free(); code_fixup_source.free(); requested_ics.free(); + cp.requested_bsms.free(); cur_classfile_head.free(); cur_classfile_tail.free(); for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) @@ -448,12 +463,12 @@ maybe_inline int unpacker::putref_index(entry* e, int size) { if (e == null) return 0; - else if (e->outputIndex > NOT_REQUESTED) + else if (e->outputIndex > REQUESTED_NONE) return e->outputIndex; else if (e->tag == CONSTANT_Signature) return putref_index(e->ref(0), size); else { - e->requestOutputIndex(cp, -size); + e->requestOutputIndex(cp, (size == 1 ? REQUESTED_LDC : REQUESTED)); // Later on we'll fix the bits. class_fixup_type.addByte(size); class_fixup_offset.add((int)wpoffset()); @@ -515,28 +530,33 @@ void unpacker::saveTo(bytes& b, byte* ptr, size_t len) { b.copyFrom(ptr, len); } +bool testBit(int archive_options, int bitMask) { + return (archive_options & bitMask) != 0; +} + // Read up through band_headers. // Do the archive_size dance to set the size of the input mega-buffer. void unpacker::read_file_header() { // Read file header to determine file type and total size. enum { MAGIC_BYTES = 4, - AH_LENGTH_0 = 3, //minver, majver, options are outside of archive_size + AH_LENGTH_0 = 3, // archive_header_0 = {minver, majver, options} + AH_LENGTH_MIN = 15, // observed in spec {header_0[3], cp_counts[8], class_counts[4]} AH_LENGTH_0_MAX = AH_LENGTH_0 + 1, // options might have 2 bytes - AH_LENGTH = 26, //maximum archive header length (w/ all fields) + AH_LENGTH = 30, //maximum archive header length (w/ all fields) // Length contributions from optional header fields: - AH_FILE_HEADER_LEN = 5, // sizehi/lo/next/modtime/files - AH_ARCHIVE_SIZE_LEN = 2, // sizehi/lo only; part of AH_FILE_HEADER_LEN - AH_CP_NUMBER_LEN = 4, // int/float/long/double - AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers - AH_LENGTH_MIN = AH_LENGTH - -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN), - ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN), + AH_LENGTH_S = 2, // archive_header_S = optional {size_hi, size_lo} + AH_ARCHIVE_SIZE_HI = 0, // offset in archive_header_S + AH_ARCHIVE_SIZE_LO = 1, // offset in archive_header_S + AH_FILE_HEADER_LEN = 5, // file_counts = {{size_hi, size_lo), next, modtile, files} + AH_SPECIAL_FORMAT_LEN = 2, // special_count = {layouts, band_headers} + AH_CP_NUMBER_LEN = 4, // cp_number_counts = {int, float, long, double} + AH_CP_EXTRA_LEN = 4, // cp_attr_counts = {MH, MT, InDy, BSM} + ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - AH_LENGTH_0 - AH_LENGTH_S, FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN }; assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic - assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size // An absolute minimum null archive is magic[4], {minver,majver,options}[3], // archive_size[0], cp_counts[8], class_counts[4], for a total of 19 bytes. // (Note that archive_size is optional; it may be 0..10 bytes in length.) @@ -622,23 +642,32 @@ void unpacker::read_file_header() { // Read the first 3 values from the header. value_stream hdr; int hdrVals = 0; - int hdrValsSkipped = 0; // debug only + int hdrValsSkipped = 0; // for assert hdr.init(rp, rplimit, UNSIGNED5_spec); minver = hdr.getInt(); majver = hdr.getInt(); hdrVals += 2; - if (magic != (int)JAVA_PACKAGE_MAGIC || - (majver != JAVA5_PACKAGE_MAJOR_VERSION && - majver != JAVA6_PACKAGE_MAJOR_VERSION) || - (minver != JAVA5_PACKAGE_MINOR_VERSION && - minver != JAVA6_PACKAGE_MINOR_VERSION)) { + int majmin[3][2] = { + {JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION}, + {JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION}, + {JAVA7_PACKAGE_MAJOR_VERSION, JAVA7_PACKAGE_MINOR_VERSION} + }; + int majminfound = false; + for (int i = 0 ; i < 3 ; i++) { + if (majver == majmin[i][0] && minver == majmin[i][1]) { + majminfound = true; + break; + } + } + if (majminfound == null) { char message[200]; sprintf(message, "@" ERROR_FORMAT ": magic/ver = " - "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n", + "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d OR %08X/%d.%d\n", magic, majver, minver, JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION, - JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION); + JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION, + JAVA_PACKAGE_MAGIC, JAVA7_PACKAGE_MAJOR_VERSION, JAVA7_PACKAGE_MINOR_VERSION); abort(message); } CHECK; @@ -646,18 +675,26 @@ void unpacker::read_file_header() { archive_options = hdr.getInt(); hdrVals += 1; assert(hdrVals == AH_LENGTH_0); // first three fields only + bool haveSizeHi = testBit(archive_options, AO_HAVE_FILE_SIZE_HI); + bool haveModTime = testBit(archive_options, AO_HAVE_FILE_MODTIME); + bool haveFileOpt = testBit(archive_options, AO_HAVE_FILE_OPTIONS); -#define ORBIT(bit) |(bit) - int OPTION_LIMIT = (0 ARCHIVE_BIT_DO(ORBIT)); -#undef ORBIT - if ((archive_options & ~OPTION_LIMIT) != 0) { - fprintf(errstrm, "Warning: Illegal archive options 0x%x\n", - archive_options); - abort("illegal archive options"); + bool haveSpecial = testBit(archive_options, AO_HAVE_SPECIAL_FORMATS); + bool haveFiles = testBit(archive_options, AO_HAVE_FILE_HEADERS); + bool haveNumbers = testBit(archive_options, AO_HAVE_CP_NUMBERS); + bool haveCPExtra = testBit(archive_options, AO_HAVE_CP_EXTRAS); + + if (majver < JAVA7_PACKAGE_MAJOR_VERSION) { + if (haveCPExtra) { + abort("Format bits for Java 7 must be zero in previous releases"); + return; + } + } + if (testBit(archive_options, AO_UNUSED_MBZ)) { + abort("High archive option bits are reserved and must be zero"); return; } - - if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) { + if (haveFiles) { uint hi = hdr.getInt(); uint lo = hdr.getInt(); julong x = band::makeLong(hi, lo); @@ -738,13 +775,23 @@ void unpacker::read_file_header() { return; } - // read the rest of the header fields - ensure_input((AH_LENGTH-AH_LENGTH_0) * B_MAX); + // read the rest of the header fields int assertSkipped = AH_LENGTH_MIN - AH_LENGTH_0 - AH_LENGTH_S; + int remainingHeaders = AH_LENGTH_MIN - AH_LENGTH_0 - AH_LENGTH_S; + if (haveSpecial) + remainingHeaders += AH_SPECIAL_FORMAT_LEN; + if (haveFiles) + remainingHeaders += AH_FILE_HEADER_LEN; + if (haveNumbers) + remainingHeaders += AH_CP_NUMBER_LEN; + if (haveCPExtra) + remainingHeaders += AH_CP_EXTRA_LEN; + + ensure_input(remainingHeaders * B_MAX); CHECK; hdr.rp = rp; hdr.rplimit = rplimit; - if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) { + if (haveFiles) { archive_next_count = hdr.getInt(); CHECK_COUNT(archive_next_count); archive_modtime = hdr.getInt(); @@ -755,7 +802,7 @@ void unpacker::read_file_header() { hdrValsSkipped += 3; } - if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) { + if (haveSpecial) { band_headers_size = hdr.getInt(); CHECK_COUNT(band_headers_size); attr_definition_count = hdr.getInt(); @@ -767,7 +814,7 @@ void unpacker::read_file_header() { int cp_counts[N_TAGS_IN_ORDER]; for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++) { - if (!(archive_options & AO_HAVE_CP_NUMBERS)) { + if (!haveNumbers) { switch (TAGS_IN_ORDER[k]) { case CONSTANT_Integer: case CONSTANT_Float: @@ -778,6 +825,17 @@ void unpacker::read_file_header() { continue; } } + if (!haveCPExtra) { + switch(TAGS_IN_ORDER[k]) { + case CONSTANT_MethodHandle: + case CONSTANT_MethodType: + case CONSTANT_InvokeDynamic: + case CONSTANT_BootstrapMethod: + cp_counts[k] = 0; + hdrValsSkipped += 1; + continue; + } + } cp_counts[k] = hdr.getInt(); CHECK_COUNT(cp_counts[k]); hdrVals += 1; @@ -791,36 +849,26 @@ void unpacker::read_file_header() { CHECK_COUNT(class_count); hdrVals += 4; - // done with archive_header + // done with archive_header, time to reconcile to ensure + // we have read everything correctly hdrVals += hdrValsSkipped; assert(hdrVals == AH_LENGTH); -#ifndef PRODUCT - int assertSkipped = AH_LENGTH - AH_LENGTH_MIN; - if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) - assertSkipped -= AH_FILE_HEADER_LEN; - if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0) - assertSkipped -= AH_SPECIAL_FORMAT_LEN; - if ((archive_options & AO_HAVE_CP_NUMBERS) != 0) - assertSkipped -= AH_CP_NUMBER_LEN; - assert(hdrValsSkipped == assertSkipped); -#endif //PRODUCT - rp = hdr.rp; if (rp > rplimit) abort("EOF reading archive header"); // Now size the CP. #ifndef PRODUCT - bool x = (N_TAGS_IN_ORDER == cpool::NUM_COUNTS); - assert(x); + // bool x = (N_TAGS_IN_ORDER == CONSTANT_Limit); + // assert(x); #endif //PRODUCT cp.init(this, cp_counts); CHECK; default_file_modtime = archive_modtime; - if (default_file_modtime == 0 && !(archive_options & AO_HAVE_FILE_MODTIME)) + if (default_file_modtime == 0 && haveModTime) default_file_modtime = DEFAULT_ARCHIVE_MODTIME; // taken from driver - if ((archive_options & AO_DEFLATE_HINT) != 0) + if (testBit(archive_options, AO_DEFLATE_HINT)) default_file_options |= FO_DEFLATE_HINT; // meta-bytes, if any, immediately follow archive header @@ -876,7 +924,7 @@ void unpacker::finish() { // Cf. PackageReader.readConstantPoolCounts -void cpool::init(unpacker* u_, int counts[NUM_COUNTS]) { +void cpool::init(unpacker* u_, int counts[CONSTANT_Limit]) { this->u = u_; // Fill-pointer for CP. @@ -924,13 +972,16 @@ void cpool::init(unpacker* u_, int counts[NUM_COUNTS]) { first_extra_entry = &entries[nentries]; // Initialize the standard indexes. - tag_count[CONSTANT_All] = nentries; - tag_base[ CONSTANT_All] = 0; for (int tag = 0; tag < CONSTANT_Limit; tag++) { entry* cpMap = &entries[tag_base[tag]]; tag_index[tag].init(tag_count[tag], cpMap, tag); } + // Initialize *all* our entries once + for (int i = 0 ; i < maxentries ; i++) + entries[i].outputIndex = REQUESTED_NONE; + + initGroupIndexes(); // Initialize hashTab to a generous power-of-two size. uint pow2 = 1; uint target = maxentries + maxentries/2; // 60% full @@ -1281,6 +1332,70 @@ void unpacker::read_signature_values(entry* cpMap, int len) { //cp_Signature_classes.done(); } +maybe_inline +void unpacker::checkLegacy(const char* name) { + if (u->majver < JAVA7_PACKAGE_MAJOR_VERSION) { + char message[100]; + snprintf(message, 99, "unexpected band %s\n", name); + abort(message); + } +} + +maybe_inline +void unpacker::read_method_handle(entry* cpMap, int len) { + if (len > 0) { + checkLegacy(cp_MethodHandle_refkind.name); + } + cp_MethodHandle_refkind.readData(len); + cp_MethodHandle_member.setIndexByTag(CONSTANT_AnyMember); + cp_MethodHandle_member.readData(len); + for (int i = 0 ; i < len ; i++) { + entry& e = cpMap[i]; + e.value.i = cp_MethodHandle_refkind.getInt(); + e.refs = U_NEW(entry*, e.nrefs = 1); + e.refs[0] = cp_MethodHandle_member.getRef(); + CHECK; + } +} + +maybe_inline +void unpacker::read_method_type(entry* cpMap, int len) { + if (len > 0) { + checkLegacy(cp_MethodType.name); + } + cp_MethodType.setIndexByTag(CONSTANT_Signature); + cp_MethodType.readData(len); + for (int i = 0 ; i < len ; i++) { + entry& e = cpMap[i]; + e.refs = U_NEW(entry*, e.nrefs = 1); + e.refs[0] = cp_MethodType.getRef(); + } +} + +maybe_inline +void unpacker::read_bootstrap_methods(entry* cpMap, int len) { + if (len > 0) { + checkLegacy(cp_BootstrapMethod_ref.name); + } + cp_BootstrapMethod_ref.setIndexByTag(CONSTANT_MethodHandle); + cp_BootstrapMethod_ref.readData(len); + + cp_BootstrapMethod_arg_count.readData(len); + int totalArgCount = cp_BootstrapMethod_arg_count.getIntTotal(); + cp_BootstrapMethod_arg.setIndexByTag(CONSTANT_LoadableValue); + cp_BootstrapMethod_arg.readData(totalArgCount); + for (int i = 0; i < len; i++) { + entry& e = cpMap[i]; + int argc = cp_BootstrapMethod_arg_count.getInt(); + e.value.i = argc; + e.refs = U_NEW(entry*, e.nrefs = argc + 1); + e.refs[0] = cp_BootstrapMethod_ref.getRef(); + for (int j = 1 ; j < e.nrefs ; j++) { + e.refs[j] = cp_BootstrapMethod_arg.getRef(); + CHECK; + } + } +} // Cf. PackageReader.readConstantPool void unpacker::read_cp() { byte* rp0 = rp; @@ -1298,6 +1413,14 @@ void unpacker::read_cp() { cpMap[i].tag = tag; cpMap[i].inord = i; } + // Initialize the tag's CP index right away, since it might be needed + // in the next pass to initialize the CP for another tag. +#ifndef PRODUCT + cpindex* ix = &cp.tag_index[tag]; + assert(ix->ixTag == tag); + assert((int)ix->len == len); + assert(ix->base1 == cpMap); +#endif switch (tag) { case CONSTANT_Utf8: @@ -1344,19 +1467,27 @@ void unpacker::read_cp() { CONSTANT_Class, CONSTANT_NameandType, cpMap, len); break; + case CONSTANT_MethodHandle: + // consumes cp_MethodHandle_refkind and cp_MethodHandle_member + read_method_handle(cpMap, len); + break; + case CONSTANT_MethodType: + // consumes cp_MethodType + read_method_type(cpMap, len); + break; + case CONSTANT_InvokeDynamic: + read_double_refs(cp_InvokeDynamic_spec, CONSTANT_BootstrapMethod, + CONSTANT_NameandType, + cpMap, len); + break; + case CONSTANT_BootstrapMethod: + // consumes cp_BootstrapMethod_ref, cp_BootstrapMethod_arg_count and cp_BootstrapMethod_arg + read_bootstrap_methods(cpMap, len); + break; default: assert(false); break; } - - // Initialize the tag's CP index right away, since it might be needed - // in the next pass to initialize the CP for another tag. -#ifndef PRODUCT - cpindex* ix = &cp.tag_index[tag]; - assert(ix->ixTag == tag); - assert((int)ix->len == len); - assert(ix->base1 == cpMap); -#endif CHECK; } @@ -1791,7 +1922,12 @@ unpacker::attr_definitions::parseLayout(const char* lp, band** &res, case 'F': ixTag = CONSTANT_Float; break; case 'D': ixTag = CONSTANT_Double; break; case 'S': ixTag = CONSTANT_String; break; - case 'Q': ixTag = CONSTANT_Literal; break; + case 'Q': ixTag = CONSTANT_FieldSpecific; break; + + // new in 1.7 + case 'M': ixTag = CONSTANT_MethodHandle; break; + case 'T': ixTag = CONSTANT_MethodType; break; + case 'L': ixTag = CONSTANT_LoadableValue; break; } } else { switch (*lp++) { @@ -1803,6 +1939,11 @@ unpacker::attr_definitions::parseLayout(const char* lp, band** &res, case 'I': ixTag = CONSTANT_InterfaceMethodref; break; case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref case 'Q': ixTag = CONSTANT_All; break; //untyped_ref + + // new in 1.7 + case 'Y': ixTag = CONSTANT_InvokeDynamic; break; + case 'B': ixTag = CONSTANT_BootstrapMethod; break; + case 'N': ixTag = CONSTANT_AnyMember; break; } } if (ixTag == CONSTANT_None) { @@ -1873,13 +2014,13 @@ void unpacker::read_attr_defs() { // Decide whether bands for the optional high flag words are present. attr_defs[ATTR_CONTEXT_CLASS] - .setHaveLongFlags((archive_options & AO_HAVE_CLASS_FLAGS_HI) != 0); + .setHaveLongFlags(testBit(archive_options, AO_HAVE_CLASS_FLAGS_HI)); attr_defs[ATTR_CONTEXT_FIELD] - .setHaveLongFlags((archive_options & AO_HAVE_FIELD_FLAGS_HI) != 0); + .setHaveLongFlags(testBit(archive_options, AO_HAVE_FIELD_FLAGS_HI)); attr_defs[ATTR_CONTEXT_METHOD] - .setHaveLongFlags((archive_options & AO_HAVE_METHOD_FLAGS_HI) != 0); + .setHaveLongFlags(testBit(archive_options, AO_HAVE_METHOD_FLAGS_HI)); attr_defs[ATTR_CONTEXT_CODE] - .setHaveLongFlags((archive_options & AO_HAVE_CODE_FLAGS_HI) != 0); + .setHaveLongFlags(testBit(archive_options, AO_HAVE_CODE_FLAGS_HI)); // Set up built-in attrs. // (The simple ones are hard-coded. The metadata layouts are not.) @@ -2579,7 +2720,7 @@ void unpacker::putlayout(band** body) { // It has data, so unparse an element. if (b.ixTag != CONSTANT_None) { assert(le_kind == EK_REF); - if (b.ixTag == CONSTANT_Literal) + if (b.ixTag == CONSTANT_FieldSpecific) e = b.getRefUsing(cp.getKQIndex()); else e = b.getRefN(); @@ -2653,13 +2794,13 @@ void unpacker::putlayout(band** body) { void unpacker::read_files() { file_name.readData(file_count); - if ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0) + if (testBit(archive_options, AO_HAVE_FILE_SIZE_HI)) file_size_hi.readData(file_count); file_size_lo.readData(file_count); - if ((archive_options & AO_HAVE_FILE_MODTIME) != 0) + if (testBit(archive_options, AO_HAVE_FILE_MODTIME)) file_modtime.readData(file_count); int allFiles = file_count + class_count; - if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0) { + if (testBit(archive_options, AO_HAVE_FILE_OPTIONS)) { file_options.readData(file_count); // FO_IS_CLASS_STUB might be set, causing overlap between classes and files for (int i = 0; i < file_count; i++) { @@ -2703,7 +2844,7 @@ void unpacker::get_code_header(int& max_stack, max_stack = sc % mod; max_na_locals = sc / mod; // caller must add static, siglen handler_count = nh; - if ((archive_options & AO_HAVE_ALL_CODE_FLAGS) != 0) + if (testBit(archive_options, AO_HAVE_ALL_CODE_FLAGS)) cflags = -1; else cflags = 0; // this one has no attributes @@ -2777,12 +2918,14 @@ band* unpacker::ref_band_for_op(int bc) { return &bc_longref; case bc_dldc2_w: return &bc_doubleref; - case bc_aldc: - case bc_aldc_w: + case bc_sldc: + case bc_sldc_w: return &bc_stringref; case bc_cldc: case bc_cldc_w: return &bc_classref; + case bc_qldc: case bc_qldc_w: + return &bc_loadablevalueref; case bc_getstatic: case bc_putstatic: @@ -2796,6 +2939,8 @@ band* unpacker::ref_band_for_op(int bc) { return &bc_methodref; case bc_invokeinterface: return &bc_imethodref; + case bc_invokedynamic: + return &bc_indyref; case bc_new: case bc_anewarray: @@ -3131,6 +3276,71 @@ void cpool::expandSignatures() { } } +bool isLoadableValue(int tag) { + switch(tag) { + case CONSTANT_Integer: + case CONSTANT_Float: + case CONSTANT_Long: + case CONSTANT_Double: + case CONSTANT_String: + case CONSTANT_Class: + case CONSTANT_MethodHandle: + case CONSTANT_MethodType: + return true; + default: + return false; + } +} +/* + * this method can be used to size an array using null as the parameter, + * thereafter can be reused to initialize the array using a valid pointer + * as a parameter. + */ +int cpool::initLoadableValues(entry** loadable_entries) { + int loadable_count = 0; + for (int i = 0; i < (int)N_TAGS_IN_ORDER; i++) { + int tag = TAGS_IN_ORDER[i]; + if (!isLoadableValue(tag)) + continue; + if (loadable_entries != NULL) { + for (int n = 0 ; n < tag_count[tag] ; n++) { + loadable_entries[loadable_count + n] = &entries[tag_base[tag] + n]; + } + } + loadable_count += tag_count[tag]; + } + return loadable_count; +} + +// Initialize various views into the constant pool. +void cpool::initGroupIndexes() { + // Initialize All + int all_count = 0; + for (int tag = CONSTANT_None ; tag < CONSTANT_Limit ; tag++) { + all_count += tag_count[tag]; + } + entry* all_entries = &entries[tag_base[CONSTANT_None]]; + tag_group_count[CONSTANT_All - CONSTANT_All] = all_count; + tag_group_index[CONSTANT_All - CONSTANT_All].init(all_count, all_entries, CONSTANT_All); + + // Initialize LoadableValues + int loadable_count = initLoadableValues(NULL); + entry** loadable_entries = U_NEW(entry*, loadable_count); + initLoadableValues(loadable_entries); + tag_group_count[CONSTANT_LoadableValue - CONSTANT_All] = loadable_count; + tag_group_index[CONSTANT_LoadableValue - CONSTANT_All].init(loadable_count, + loadable_entries, CONSTANT_LoadableValue); + +// Initialize AnyMembers + int any_count = tag_count[CONSTANT_Fieldref] + + tag_count[CONSTANT_Methodref] + + tag_count[CONSTANT_InterfaceMethodref]; + entry *any_entries = &entries[tag_base[CONSTANT_Fieldref]]; + tag_group_count[CONSTANT_AnyMember - CONSTANT_All] = any_count; + tag_group_index[CONSTANT_AnyMember - CONSTANT_All].init(any_count, + any_entries, CONSTANT_AnyMember); +} + void cpool::initMemberIndexes() { // This function does NOT refer to any class schema. // It is totally internal to the cpool. @@ -3238,13 +3448,13 @@ void cpool::initMemberIndexes() { } void entry::requestOutputIndex(cpool& cp, int req) { - assert(outputIndex <= NOT_REQUESTED); // must not have assigned indexes yet + assert(outputIndex <= REQUESTED_NONE); // must not have assigned indexes yet if (tag == CONSTANT_Signature) { ref(0)->requestOutputIndex(cp, req); return; } assert(req == REQUESTED || req == REQUESTED_LDC); - if (outputIndex != NOT_REQUESTED) { + if (outputIndex != REQUESTED_NONE) { if (req == REQUESTED_LDC) outputIndex = req; // this kind has precedence return; @@ -3252,31 +3462,52 @@ void entry::requestOutputIndex(cpool& cp, int req) { outputIndex = req; //assert(!cp.outputEntries.contains(this)); assert(tag != CONSTANT_Signature); - cp.outputEntries.add(this); + // The BSMs are jetisoned to a side table, however all references + // that the BSMs refer to, need to be considered. + if (tag == CONSTANT_BootstrapMethod) { + // this is a a pseudo-op entry; an attribute will be generated later on + cp.requested_bsms.add(this); + } else { + // all other tag types go into real output file CP: + cp.outputEntries.add(this); + } for (int j = 0; j < nrefs; j++) { ref(j)->requestOutputIndex(cp); } } void cpool::resetOutputIndexes() { - int i; - int noes = outputEntries.length(); + /* + * reset those few entries that are being used in the current class + * (Caution since this method is called after every class written, a loop + * over every global constant pool entry would be a quadratic cost.) + */ + + int noes = outputEntries.length(); entry** oes = (entry**) outputEntries.base(); - for (i = 0; i < noes; i++) { + for (int i = 0 ; i < noes ; i++) { entry& e = *oes[i]; - e.outputIndex = NOT_REQUESTED; + e.outputIndex = REQUESTED_NONE; + } + + // do the same for bsms and reset them if required + int nbsms = requested_bsms.length(); + entry** boes = (entry**) requested_bsms.base(); + for (int i = 0 ; i < nbsms ; i++) { + entry& e = *boes[i]; + e.outputIndex = REQUESTED_NONE; } outputIndexLimit = 0; outputEntries.empty(); #ifndef PRODUCT - // they must all be clear now - for (i = 0; i < (int)nentries; i++) - assert(entries[i].outputIndex == NOT_REQUESTED); + // ensure things are cleared out + for (int i = 0; i < (int)maxentries; i++) + assert(entries[i].outputIndex == REQUESTED_NONE); #endif } static const byte TAG_ORDER[CONSTANT_Limit] = { - 0, 1, 0, 2, 3, 4, 5, 7, 6, 10, 11, 12, 9, 8 + 0, 1, 0, 2, 3, 4, 5, 7, 6, 10, 11, 12, 9, 8, 0, 13, 14, 15, 16 }; extern "C" @@ -3323,10 +3554,18 @@ void cpool::computeOutputIndexes() { if (nentries > 100) checkStep = nentries / 100; for (i = (int)(checkStart++ % checkStep); i < (int)nentries; i += checkStep) { entry& e = entries[i]; - if (e.outputIndex != NOT_REQUESTED) { - assert(outputEntries.contains(&e)); + if (e.tag == CONSTANT_BootstrapMethod) { + if (e.outputIndex != REQUESTED_NONE) { + assert(requested_bsms.contains(&e)); + } else { + assert(!requested_bsms.contains(&e)); + } } else { - assert(!outputEntries.contains(&e)); + if (e.outputIndex != REQUESTED_NONE) { + assert(outputEntries.contains(&e)); + } else { + assert(!outputEntries.contains(&e)); + } } } @@ -3348,7 +3587,7 @@ void cpool::computeOutputIndexes() { int nextIndex = 1; // always skip index #0 in output cpool for (i = 0; i < noes; i++) { entry& e = *oes[i]; - assert(e.outputIndex == REQUESTED || e.outputIndex == REQUESTED_LDC); + assert(e.outputIndex >= REQUESTED_LDC); e.outputIndex = nextIndex++; if (e.isDoubleWord()) nextIndex++; // do not use the next index } @@ -3396,7 +3635,7 @@ char* entry::string() { default: if (nrefs == 0) { buf = getbuf(20); - sprintf((char*)buf.ptr, "", tag); + sprintf((char*)buf.ptr, TAG_NAME[tag]); } else if (nrefs == 1) { return refs[0]->string(); } else { @@ -3674,6 +3913,7 @@ void unpacker::reset_cur_classfile() { class_fixup_offset.empty(); class_fixup_ref.empty(); requested_ics.empty(); + cp.requested_bsms.empty(); } cpindex* cpool::getKQIndex() { @@ -3931,13 +4171,15 @@ void unpacker::write_bc_ops() { case bc_ildc: case bc_cldc: case bc_fldc: - case bc_aldc: + case bc_sldc: + case bc_qldc: origBC = bc_ldc; break; case bc_ildc_w: case bc_cldc_w: case bc_fldc_w: - case bc_aldc_w: + case bc_sldc_w: + case bc_qldc_w: origBC = bc_ldc_w; break; case bc_lldc2_w: @@ -3962,6 +4204,10 @@ void unpacker::write_bc_ops() { int argSize = ref->memberDescr()->descrType()->typeSize(); putu1_fast(1 + argSize); putu1_fast(0); + } else if (origBC == bc_invokedynamic) { + // pad the next two byte + putu1_fast(0); + putu1_fast(0); } continue; } @@ -4353,49 +4599,12 @@ int raw_address_cmp(const void* p1p, const void* p2p) { return (p1 > p2)? 1: (p1 < p2)? -1: 0; } -void unpacker::write_classfile_tail() { - cur_classfile_tail.empty(); - set_output(&cur_classfile_tail); - - int i, num; - - attr_definitions& ad = attr_defs[ATTR_CONTEXT_CLASS]; - - bool haveLongFlags = ad.haveLongFlags(); - julong kflags = class_flags_hi.getLong(class_flags_lo, haveLongFlags); - julong indexMask = ad.flagIndexMask(); - - cur_class = class_this.getRef(); - cur_super = class_super.getRef(); - - CHECK; - - if (cur_super == cur_class) cur_super = null; - // special representation for java/lang/Object - - putu2((ushort)(kflags & ~indexMask)); - putref(cur_class); - putref(cur_super); - - putu2(num = class_interface_count.getInt()); - for (i = 0; i < num; i++) { - putref(class_interface.getRef()); - } - - write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD); - write_members(class_method_count.getInt(), ATTR_CONTEXT_METHOD); - CHECK; - - cur_class_has_local_ics = false; // may be set true by write_attrs - - - int naOffset = (int)wpoffset(); - int na = write_attrs(ATTR_CONTEXT_CLASS, (kflags & indexMask)); - - - // at the very last, choose which inner classes (if any) pertain to k: +/* + * writes the InnerClass attributes and returns the updated attribute + */ +int unpacker::write_ics(int naOffset, int na) { #ifdef ASSERT - for (i = 0; i < ic_count; i++) { + for (int i = 0; i < ic_count; i++) { assert(!ics[i].requested); } #endif @@ -4416,7 +4625,7 @@ void unpacker::write_classfile_tail() { // include it and all its outers. int noes = cp.outputEntries.length(); entry** oes = (entry**) cp.outputEntries.base(); - for (i = 0; i < noes; i++) { + for (int i = 0; i < noes; i++) { entry& e = *oes[i]; if (e.tag != CONSTANT_Class) continue; // wrong sort for (inner_class* ic = cp.getIC(&e); @@ -4442,10 +4651,10 @@ void unpacker::write_classfile_tail() { // Note: extra_ics will be freed up by next call to get_next_file(). } } - for (i = 0; i < num_extra_ics; i++) { + for (int i = 0; i < num_extra_ics; i++) { inner_class& extra_ic = extra_ics[i]; extra_ic.inner = class_InnerClasses_RC.getRef(); - CHECK; + CHECK_0; // Find the corresponding equivalent global IC: inner_class* global_ic = cp.getIC(extra_ic.inner); int flags = class_InnerClasses_F.getInt(); @@ -4493,7 +4702,7 @@ void unpacker::write_classfile_tail() { putu2(local_ics); PTRLIST_QSORT(requested_ics, raw_address_cmp); int num_global_ics = requested_ics.length(); - for (i = -num_global_ics; i < num_extra_ics; i++) { + for (int i = -num_global_ics; i < num_extra_ics; i++) { inner_class* ic; if (i < 0) ic = (inner_class*) requested_ics.get(num_global_ics+i); @@ -4512,17 +4721,99 @@ void unpacker::write_classfile_tail() { } // Tidy up global 'requested' bits: - for (i = requested_ics.length(); --i >= 0; ) { + for (int i = requested_ics.length(); --i >= 0; ) { inner_class* ic = (inner_class*) requested_ics.get(i); ic->requested = false; } requested_ics.empty(); + return na; +} +/* + * Writes the BootstrapMethods attribute and returns the updated attribute count + */ +int unpacker::write_bsms(int naOffset, int na) { + cur_class_local_bsm_count = cp.requested_bsms.length(); + if (cur_class_local_bsm_count > 0) { + int noes = cp.outputEntries.length(); + entry** oes = (entry**) cp.outputEntries.base(); + PTRLIST_QSORT(cp.requested_bsms, outputEntry_cmp); + // append the BootstrapMethods attribute (after the InnerClasses attr): + putref(cp.sym[cpool::s_BootstrapMethods]); + int sizeOffset = (int)wpoffset(); + byte* sizewp = wp; + putu4(-99); // attr size will be patched + putu2(cur_class_local_bsm_count); + int written_bsms = 0; + for (int i = 0 ; i < cur_class_local_bsm_count ; i++) { + entry* e = (entry*)cp.requested_bsms.get(i); + assert(e->outputIndex != REQUESTED_NONE); + // output index is the index within the array + e->outputIndex = i; + putref(e->refs[0]); // bsm + putu2(e->nrefs-1); // number of args after bsm + for (int j = 1; j < e->nrefs; j++) { + putref(e->refs[j]); + } + written_bsms += 1; + } + assert(written_bsms == cur_class_local_bsm_count); // else insane + putu4_at(sizewp, (int)(wp - (sizewp+4))); // size of code attr + putu2_at(wp_at(naOffset), ++na); // increment class attr count + } + return na; +} + +void unpacker::write_classfile_tail() { + + cur_classfile_tail.empty(); + set_output(&cur_classfile_tail); + + int i, num; + + attr_definitions& ad = attr_defs[ATTR_CONTEXT_CLASS]; + + bool haveLongFlags = ad.haveLongFlags(); + julong kflags = class_flags_hi.getLong(class_flags_lo, haveLongFlags); + julong indexMask = ad.flagIndexMask(); + + cur_class = class_this.getRef(); + cur_super = class_super.getRef(); CHECK; + + if (cur_super == cur_class) cur_super = null; + // special representation for java/lang/Object + + putu2((ushort)(kflags & ~indexMask)); + putref(cur_class); + putref(cur_super); + + putu2(num = class_interface_count.getInt()); + for (i = 0; i < num; i++) { + putref(class_interface.getRef()); + } + + write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD); + write_members(class_method_count.getInt(), ATTR_CONTEXT_METHOD); + CHECK; + + cur_class_has_local_ics = false; // may be set true by write_attrs + + int naOffset = (int)wpoffset(); // note the attr count location + int na = write_attrs(ATTR_CONTEXT_CLASS, (kflags & indexMask)); + CHECK; + + na = write_bsms(naOffset, na); + CHECK; + + // choose which inner classes (if any) pertain to k: + na = write_ics(naOffset, na); + CHECK; + close_output(); + cp.computeOutputIndexes(); // rewrite CP references in the tail - cp.computeOutputIndexes(); int nextref = 0; for (i = 0; i < (int)class_fixup_type.size(); i++) { int type = class_fixup_type.getByte(i); @@ -4579,9 +4870,18 @@ void unpacker::write_classfile_head() { case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: case CONSTANT_NameandType: + case CONSTANT_InvokeDynamic: putu2(e.refs[0]->getOutputIndex()); putu2(e.refs[1]->getOutputIndex()); break; + case CONSTANT_MethodHandle: + putu1(e.value.i); + putu2(e.refs[0]->getOutputIndex()); + break; + case CONSTANT_MethodType: + putu2(e.refs[0]->getOutputIndex()); + break; + case CONSTANT_BootstrapMethod: // should not happen default: abort(ERROR_INTERNAL); } @@ -4620,11 +4920,11 @@ unpacker::file* unpacker::get_next_file() { entry* e = file_name.getRef(); CHECK_0; cur_file.name = e->utf8String(); - bool haveLongSize = ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0); + bool haveLongSize = (testBit(archive_options, AO_HAVE_FILE_SIZE_HI)); cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize); - if ((archive_options & AO_HAVE_FILE_MODTIME) != 0) + if (testBit(archive_options, AO_HAVE_FILE_MODTIME)) cur_file.modtime += file_modtime.getInt(); //relative to archive modtime - if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0) + if (testBit(archive_options, AO_HAVE_FILE_OPTIONS)) cur_file.options |= file_options.getInt() & ~suppress_file_options; } else if (classes_written < class_count) { // there is a class for a missing file record diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h index 0f66b7ef6f5..cec7a88b24e 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012, 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,9 +22,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - - - // Global Structures struct jar; struct gunzip; @@ -70,6 +67,9 @@ struct cpool { cpindex tag_index[CONSTANT_Limit]; ptrlist tag_extras[CONSTANT_Limit]; + int tag_group_count[CONSTANT_GroupLimit - CONSTANT_GroupFirst]; + cpindex tag_group_index[CONSTANT_GroupLimit - CONSTANT_GroupFirst]; + cpindex* member_indexes; // indexed by 2*CONSTANT_Class.inord cpindex* getFieldIndex(entry* classRef); cpindex* getMethodIndex(entry* classRef); @@ -82,6 +82,7 @@ struct cpool { int outputIndexLimit; // index limit after renumbering ptrlist outputEntries; // list of entry* needing output idx assigned + ptrlist requested_bsms; // which bsms need output? entry** hashTab; uint hashTabLength; @@ -100,24 +101,36 @@ struct cpool { entry* sym[s_LIMIT]; // read counts from hdr, allocate main arrays - enum { NUM_COUNTS = 12 }; - void init(unpacker* u, int counts[NUM_COUNTS]); + void init(unpacker* u, int counts[CONSTANT_Limit]); // pointer to outer unpacker, for error checks etc. unpacker* u; int getCount(byte tag) { - assert((uint)tag < CONSTANT_Limit); - return tag_count[tag]; + if ((uint)tag >= CONSTANT_GroupFirst) { + assert((uint)tag < CONSTANT_GroupLimit); + return tag_group_count[(uint)tag - CONSTANT_GroupFirst]; + } else { + assert((uint)tag < CONSTANT_Limit); + return tag_count[(uint)tag]; + } } cpindex* getIndex(byte tag) { - assert((uint)tag < CONSTANT_Limit); - return &tag_index[tag]; + if ((uint)tag >= CONSTANT_GroupFirst) { + assert((uint)tag < CONSTANT_GroupLimit); + return &tag_group_index[(uint)tag - CONSTANT_GroupFirst]; + } else { + assert((uint)tag < CONSTANT_Limit); + return &tag_index[(uint)tag]; + } } + cpindex* getKQIndex(); // uses cur_descr void expandSignatures(); + void initGroupIndexes(); void initMemberIndexes(); + int initLoadableValues(entry** loadable_entries); void computeOutputOrder(); void computeOutputIndexes(); @@ -234,6 +247,7 @@ struct unpacker { int cur_descr_flags; // flags corresponding to cur_descr int cur_class_minver, cur_class_majver; bool cur_class_has_local_ics; + int cur_class_local_bsm_count; fillbytes cur_classfile_head; fillbytes cur_classfile_tail; int files_written; // also tells which file we're working on @@ -412,7 +426,7 @@ struct unpacker { void abort(const char* s = null); bool aborting() { return abort_message != null; } static unpacker* current(); // find current instance - + void checkLegacy(const char* name); // Output management void set_output(fillbytes* which) { assert(wp == null); @@ -464,6 +478,8 @@ struct unpacker { void write_bc_ops(); void write_members(int num, int attrc); // attrc=ATTR_CONTEXT_FIELD/METHOD int write_attrs(int attrc, julong indexBits); + int write_ics(int naOffset, int na); + int write_bsms(int naOffset, int na); // The readers void read_bands(); @@ -484,6 +500,9 @@ struct unpacker { void read_single_refs(band& cp_band, byte refTag, entry* cpMap, int len); void read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag, entry* cpMap, int len); void read_signature_values(entry* cpMap, int len); + void read_method_handle(entry* cpMap, int len); + void read_method_type(entry* cpMap, int len); + void read_bootstrap_methods(entry* cpMap, int len); }; inline void cpool::abort(const char* msg) { u->abort(msg); } diff --git a/jdk/test/tools/pack200/AttributeTests.java b/jdk/test/tools/pack200/AttributeTests.java index e7107996cc8..69547083025 100644 --- a/jdk/test/tools/pack200/AttributeTests.java +++ b/jdk/test/tools/pack200/AttributeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ import java.util.Arrays; import java.util.List; /* * @test - * @bug 6982312 + * @bug 6746111 * @summary tests various classfile format and attribute handling by pack200 * @compile -XDignore.symbol.file Utils.java AttributeTests.java * @run main AttributeTests @@ -36,40 +36,8 @@ import java.util.List; public class AttributeTests { public static void main(String... args) throws Exception { - test6982312(); test6746111(); } - /* - * This is an interim test, which ensures pack200 handles JSR-292 related - * classfile changes seamlessly, until all the classfile changes in jdk7 - * and jdk8 are fully supported. At that time this test should be jettisoned, - * along with the associated jar file. - * - * The jar file contains sources and classes noting the classes were - * derived by using the javac from the lambda project, - * see http://openjdk.java.net/projects/lambda/. - * Therefore the classes contained in the jar cannot be compiled, using - * the standard jdk7's javac compiler. - */ - static void test6982312() throws IOException { - String pack200Cmd = Utils.getPack200Cmd(); - File dynJar = new File(".", "dyn.jar"); - Utils.copyFile(new File(Utils.TEST_SRC_DIR, "dyn.jar"), dynJar); - File testJar = new File(".", "test.jar"); - List cmds = new ArrayList(); - cmds.add(pack200Cmd); - cmds.add("--repack"); - cmds.add(testJar.getAbsolutePath()); - cmds.add(dynJar.getAbsolutePath()); - Utils.runExec(cmds); - /* - * compare the repacked jar bit-wise, as all the files - * should be transmitted "as-is". - */ - Utils.doCompareBitWise(dynJar.getAbsoluteFile(), testJar.getAbsoluteFile()); - testJar.delete(); - dynJar.delete(); - } /* * this test checks to see if we get the expected strings for output diff --git a/jdk/test/tools/pack200/PackageVersionTest.java b/jdk/test/tools/pack200/PackageVersionTest.java index 538b92ecafc..8569781a6ec 100644 --- a/jdk/test/tools/pack200/PackageVersionTest.java +++ b/jdk/test/tools/pack200/PackageVersionTest.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,9 @@ public class PackageVersionTest { public final static int JAVA6_PACKAGE_MAJOR_VERSION = 160; public final static int JAVA6_PACKAGE_MINOR_VERSION = 1; + public final static int JAVA7_PACKAGE_MAJOR_VERSION = 170; + public final static int JAVA7_PACKAGE_MINOR_VERSION = 1; + public static void main(String... args) { if (!javaHome.getName().endsWith("jre")) { throw new RuntimeException("Error: requires an SDK to run"); @@ -68,9 +71,8 @@ public class PackageVersionTest { verifyPack("Test6.class", JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION); - // TODO: change this to the java7 package version as needed. - verifyPack("Test7.class", JAVA6_PACKAGE_MAJOR_VERSION, - JAVA6_PACKAGE_MINOR_VERSION); + verifyPack("Test7.class", JAVA7_PACKAGE_MAJOR_VERSION, + JAVA7_PACKAGE_MINOR_VERSION); // test for resource file, ie. no class files verifyPack("Test6.java", JAVA5_PACKAGE_MAJOR_VERSION, diff --git a/jdk/test/tools/pack200/Utils.java b/jdk/test/tools/pack200/Utils.java index 8158f486ca2..0e2269822f5 100644 --- a/jdk/test/tools/pack200/Utils.java +++ b/jdk/test/tools/pack200/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2012, 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 @@ -129,8 +129,10 @@ class Utils { init(); List cmds = new ArrayList(); cmds.add(getJavaCmd()); - cmds.add("-jar"); - cmds.add(VerifierJar.getName()); + cmds.add("-cp"); + cmds.add(Utils.locateJar("tools.jar") + + System.getProperty("path.separator") + VerifierJar.getName()); + cmds.add("sun.tools.pack.verify.Main"); cmds.add(reference.getAbsolutePath()); cmds.add(specimen.getAbsolutePath()); cmds.add("-O"); @@ -142,8 +144,10 @@ class Utils { init(); List cmds = new ArrayList(); cmds.add(getJavaCmd()); - cmds.add("-jar"); - cmds.add(VerifierJar.getName()); + cmds.add("-cp"); + cmds.add(Utils.locateJar("tools.jar") + + System.getProperty("path.separator") + VerifierJar.getName()); + cmds.add("sun.tools.pack.verify.Main"); cmds.add(reference.getName()); cmds.add(specimen.getName()); cmds.add("-O"); diff --git a/jdk/test/tools/pack200/dyn.jar b/jdk/test/tools/pack200/dyn.jar deleted file mode 100644 index b04c2a9e825b1201cbdcd2f863478587356ce7ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1963 zcmWIWW@Zs#U|`^2c-v!byUlj8x<8PY48(j4G7O%1X{kl2dC94IS&3zdp&^_M%yyOw zeXja1^eL_2W?*D_%gn&Q!pOwHaQck4r>>W`k6$Q9*_Y52&z@?XKJOEF;_8Jh&z`P& z`t;FLuXCO{dSM)%x_XQ!#ipxFOHtEy5RuHx&d1H~Dgj+?o~Swaqc4$yzY58#_4Sl{Zs zK1N`(P0!DM{(Pq5+3)o?!x{Pm^cS_5vYX4^Dcab_%RZZL$JIOc?Efp&&5J&J z=-6~~d%L_{J9>4+%Qw7zu&!J7&gQ_)4~--ILzkQ}Zp%4qpLSyJh1!!F?gUP>k>KBL zWG8fY!i+f+I}fFpj2|xI=~uL$ zkhtQcUy01OlWZHOh`cIXJ9*VNCqdTg^}E$KrAtkp;VisbBV)^7SJ6;g8TY@1P7gxV zoqZ3yeCZ&WxT5E3)as}DZb=zFU!QQ!=V^JEYd1ydk=th%pPgRsJ_l;JD(&o4jh)@- zwWCkP-)+-!7YRSfFum*5YeM%=G&{q$B%a)b5y)b zwJOz*uCiBV%6}cV@65ixN5d?m|2AuH(AGFp&}uOIAnTsh#yS(rC#G@x&6+I~S(2RG z`$tyfgMjOs%cs?Bqg7q|zFg0UpMSmnu{k24Yy>8hHCO-V{Q#!jtH8tpNx!g!0#Cns z*wabxgwt7v4Fp`j|LbzRYmwkHb;`bM(bP@qwxH_&xZN!d;>-5V zZnR9_VX*A&31gWn3qEP>s(H_5^(eYzm1)&G#g5UUOfiZzss^bF!HmfdN?7ky zNHN!(bDk=ue`?P6PYtskvaDB-+A{6PyHj;vpKf)3@?}b+#L3%UDGJwTU%g*;d-p2- z$@}*1{@-4=%JSQoZ(MdvD`MLTXh ze=o;Jx9t;vvHJn3BPhRd!$>;GTaTX<&! z>tUC>PX(QYmO5pfd;Eb3;hgEAdbULcnR=?gsB8mbkaI#(i%XEQeBYLSY*{|G|E%|6 z2Z5va&2od1bFyEDe|)s@>xBln)lDKxoK`t?v*+JVxw7S?+b6|u=RYl}5IFxY@R5or z7vGyVpDI4j-hSU+em+CrMYDyA!>$LKUohC%xvX(oqb}p$BjI&bY70ttZD)Gw_++BP z-H)QNsSl?->YT&2X38OD#$uV&jo#vQ>#pcswLQ8d=GECJo3|t^$Xe8to7Q{Yovlpg zO;Z0%VXvS@w|ASESIWJ4{j%rIl|xpmn11Jp-11!Z#v*v7{G?i8cl~ZfR(}!hHLXQ{ ztx5&A3c1?02YlEoYQj@nb6 zJ(PCYe5GmG-o<}d&sL^Rtv`ELM@Do?<*HfF|IN-#j!a6u`ZKO+yUN**-Xr08)7ENv?Yzx!DhnpCbSR-8VV}J@feDk z#Sso&(s%$^J9y^7425KPpqZcykH<{RWRGkn0}BI6CIFfT$^>}K!%Vjbj~{642bzbR bih<^VQZa^ktZblwVg3?iFylWjC2)mwwRynnZR_RD z>uBj~$?I(CYR`*w^>uTyJB%*Mcpxl|L9we zlyMFP`n8p4={Jdzz$9&VEGh~FIw90d+nsu=Pies4yaOU2z%$TX@QqVSlcdvGdT~2H z%&9kyk&U_rb;!hMZHD)X@dtfhGe;o<<8!ByJ_HT@sF>4K#X%;_=i`g?6n>%4w$%|k z>v4@GEb1T1nXfv1FthDL%n$fJ(68@j^}6eKRKfz|s_JK!r={MV=C8!h;o$k)oL`!Q zAB%W31Igg6;>#gp_V1`Al)BlGAX(aPr?5dyuqGrtgOXkAf@b8@4cPdyI~lGAv>97z z$lS`1*Q%Z#HA=kR_`RRuS-H5{eC4w{6g@2R)?_&wMdDW%T1sjb8#39F3t009%S-~9 zdaSFQ9lvL5y8hUdIZ*jpEiU%j5l`ptqQn94nFAIT5+2kMS#j@*GUwN>r*SFG#TfPi zPP2E{ITca-tn*|P3S9loRT!OVtsR=p@*_l-b{Nmxf{vW)3zifv{_%;R#5YnXRfGeQ@ON947Y5tdk8q3C$Yh1RSK)1xVg<5YT@ zm>I|WO-Xcec#qT6ox-P5xw$uEAVqz9oap+2{!?WX4QE1YN8igiJM9K#<0#JvCrVTt zO<*ZD11`Xm`U6wQ|2OEc3Njc*e)N_e`QomBs9x*}O$8v9#PTeaXrq!v}Xt)fdNc)p;7Xbsv(e<}4*%^13Smbh) zMtv4v6_)9$$W|(lObLFKd@~w0NKaODmQ%D(M_-GTv-vdwDZBBF`; zCySA@a(nJUj(FxS9aMSKq0+e%e=$fQCjJ`47Aul1*`XjlA`95L{R?p#h8I$N9yv?G z<`~MCvY*5)h~I%Dd*UEfmuMlubb>v#JR@%&MApyxbIYFI>X~RuWXHP*Tr<`c&bi23 z8I-`4qa1eBH$90Cj!7Iw?p`H~Ns)Vi0s2M({z6MM9!0n`lj;7u_Hb!)!Xffrs=$cq zQ(+<(#$;8Js_5}q>)vRS*glt5=9$@c;|LzesWRQqc(aCf56bf={Pr=6XcN&n#-M#a zFS>X9YIJX+Bz~S@Uv#?uL%~`C7zE;gy7H&h{dXr4`CmHGW#efxy5g_%IrZ!@%bMf> zF`obl!iwpdY^#zmp6pwAn8@3%9wJW%aye9n{V@%Jjk40cP~{P3mo#B!7vy9^5x2`I zv!H4zRvfA5L*~(B4ZA__abK~G_0jilN^;aPymIxYI^PDR%!Qw9N*+$v&v>1C)%c%K z*$-kFYEWg1Cd{TS`ehI8Jc^t3vAX((_vx(8&dKhtaDh|CGo@~N@j4o5l78ZxBeGMJ zQUIzP^G@I>mheoiJ8$5SSNF8oI`~WH*o`fzptkpCsha1;-Lt*l-1JU$d$v^e{64VSx3*Q7d>^V5*;}*qR%@4`2od-k8iI2-B6U;ybv?^%nT129Y{HluH1BnmX_JJ^VS372#<_(!2&q>Z#g4~3PY*r=DOr?#$=CZ= z6pgt)sB>~_t=OeH>XuWKh-K9HB}cbv$Um3qE)$qmO~mKcbI6dDVk>AcEzxI3c@soO z>U*{>>oe9Qe|1D=W>Xi~MUJyK=;!-ze&qDdA`3*e#fj)Tl5Xl-I(u0~OzN$Y^utqy z(}r2K#>+7oEdwzHD&%l#Sh2Gh|JV9;$`B=rs4Ne!m zz8dX36~FQZ^?YJd&Vc#+7@D|sl;bGc64fh+XKc@G)iu=_z+}mc$8zQxc9WKFT{$zN z<^Jn~-~em(NeAxzEDt$)B*L(Tj}wS14IhYgJF1 zw=st+*p?*|clR|T_-aaG)Qm*YZmS)VGXY%at#wfnK`T3UT4i=`DobDY3A|0@e16&8 z_fetKH<7>nBAUk+;c8<>XNQ4<58vboTT7kNyQTf zdHO3j+~>xa*M`yMF@T;)3aXX#W>2FgQ`h24c_uBLriA(Xt8qPkLYo?%)U+pt$r0?d zx0$N0c?(fLVkO+<^f%5Aku~DFm8GfEHFkz+bezfZrK~j7)iHTX^}^Y0UHJXn@;6pV z0cv5#<*XNb-o!+A2#hubM8TT@*!q|#ks|+ z+Z%?{s4Zun+W9CJB;|a0m}5demqgtA(~2~2oRMYY$-RIq0m&*a)j$h2`)u68_2QsOdu<&6xfRfDf)T8Mfr zWS=<*&ZIp78xqCGM^AGBS$ znVt~+UTZ6cZrG2;<0|jmb6IhrpDYpzhN+P(eoSIk%?C%-3o)epGjp1qYW~wff6b4t zpFO#=K0ec<^d8}J_oiZsqS#f3BOYyh93firtgo_h^S%6}chqjmp;3nsB`VomOd&#O zFTR1>MRQ>a^LX}1?1)w0am*vzsw@Y?@F=o^?FUFR^qs3qNh1!xzS-M&+7N|+SxZ_o zDr{`pt2#=BGY!$LCU{)v~fe5)TD#_S-L-M+BZPSU*E!<;B z^8>-kt=pc3{WcM(dGr%&!dIhrwUXyjyfx8OJ1mh>#lxj5wTgN9Y(hV|f?YdZi#p=s zU2<*i6S7il5|$wM$%D-bd51`O=ym3}bqwqIO6MA~AC<1e(+0=BsT|h&8K-DoT%*j8 zI~V4!9LhZHt-vQar>QPu+c{aGa@r@t!oRmhNJ1k|xs>+_wS1?we0VPmA*@KmNSDG? z_KxBwJlx9cOQVCslN}#=)HG{Weaz<(0_`}i?M0Ss7he1w7TFn=CxCkF=HYHx%vw^H zrl6En?fXy8_d0JZm?Vo|J=w&PV;CjG$v}mx5#Dtk}PN77Q1ymMs7YynK$@uobdijAzU`)W4rV^WJdA52E=>zon}CU z%cLVt*u0oYV=TMiy|7*R*GGglW-E++1v%YcL=cZR@0p`s+Aoz=4LeK>-Nb30_@bkU zZ%QeIjOt9xDIxu=&f%eo9~aF}ZdZ9_<92|R0Jjfc`=q5!^|Dv|bfD8#t|3y9tfa$F z+C-O5I8JXAousTvkW2h&)QSl0nmOt57gblbfxJp-OiRgx{Of~Ser{duA1iZ3!?&3Q zHhEfE?U>%7KFfXP3DLLVxiYgtKt3fhw<(S^c6}3&kVlw6{MCv`gVENN^h3%~ys0_c zUWJ{YN%zv2nyvGju1$BCX)IF+cV$Kow~_5_%zNQ*>k$)o?DRZ6m+#skQJ;V%Bbwbb zQ!UZV`WEZhddIedYpw4;Nj3Q^_R3E5a1H5yTKL*ehRW^5JPAizv^6d*W#H#cjSqOT zXRB?0Dw$4L5mv(DiFxQBYq;b(% zVL;3OP_D&V+^v(+=5f7*Thu`p<$Neoa^+Ze^5(dORilmfF4}&G&nmbj+gLPs!=An~ zW7Ryc1;ysPDf!Mrjko`+D{Ey#%zNuCf_-1UbczhmN95DDPK9(tOGti}YVsU<`Ve{G zA6E%z43+Bbv!Y54qfAD2AkmeShCs~cIR=f_3Q`kPGrSi_F7zD!Bwuu%BFgu3Zl zIHzH=(0;_|9lIQ*8WD+A&s}ZhC`^&~=^NRKWwOwegkQaD7gn=e*N_}R@NASq@R=6w z)n1fEYZzgoaIz)#V^apPQY|W)k-);RD8bbdMk|6Y0ob-X+kFn>a=Byo=i~EY;y{m4tEROT$EU2U+^ex}3Y= zhSB$%ufDFMGjFoe)?VqX*MGc?5I>YS$@5(fJf(;}P2Klo$)OGxk5owA|DYn4y3wB9 ziNbi#rgf@waJ4|XLkNHDI}G#d&baaldt~Db+K-NZTTH+f`RjXQ&dl<+j6}l(jodA} zM<1MhsT!@~ZMQu|G5C+}H-wDy&e6GOZzsm5U%}J}j%N$imY_aPX)n(b`19AdPjv^L zRaaJ^i0W5){;H^;m-|3E@%V9}FyEtBZ;`06*Amv-_+FR-RHg$Kt(Dfd@$+jQ61g$qQe-piM=!o`g-W z^owg>Rh)4rjdpov4jMeKu~dJ%XuL)|aewXfq4sB&vrzQQuk@O$zpy@i!Vv3j=Ve@@>PhyaAM9u63Md?Nze*^oZ>0xn#mr}Y!6nE+H{OS$#ji%2& zpYlwcObmi&Zl@cVZ#ccUjiR6*+>LhjUdO!l;c%A3md;;;{d^_4H2y_@a%r+6uLGUi z;%lyh{6#aZoIp|Ej4odBsk{@V{W&@lp;xT;Xg^j8j*{`-!qn=gE?SxJkv*Zgi*haD z8{XtePlg5der%jc`P613;Pf%=H1725rRP}aiKrrd2jTQ!^EPC@Gd!qSDvmCQ5Kf25 zi1xsHyj|u`zO>_U8oDCgVSU6wG)ySry0IfBni}7H#TSR|n3tcfHQI^iMXPrF?grsb zaPu8f5E)^f;Z2#>jUZAHE*s=K@F@~dS>>Y0e#Wu>t=;;l_7) zsdwMxyi0@BZ*YG00-vHiZ7L@6Jwu4ts^}@pJGPY{{983kf@Z*RyIzz>W@q2^o$Gf# zZmQX&>9HdyiJyQcfIAyS3llx^5vI(8!^fBTAmv((gfR@&Y6 zNH)gQ$)05|>O4#N-JPTQQ(jrRgu*!Ovbw$_UIn; zW>dTp6p9NPL6U-VDZCCy>Olklu^#)qE(J%57d~1B&~s3&WeD8}0#W)C6qo2S6eVzf z9vTkX=H{Upnji)WVvj&U1m~Ew_#mFkU^gm)*cgMYj|bw_By3uK5ZODiSH(ai`-Pn^ z0OCttSjL6lJ%LMH5xm535!jQ963$HFluev>V9N{_PR6kIn;?z`!@>zcG>C(Z!$IUp zg8jJI4hsO=1c5vqmJV90(qW7jp$9Wz+!y#O8}=4V32d8#A;$(`8DRV-*I}5^1@?}> zxFSG2(8mcr0MSbg9)&~l_ssX7qg>#MHe47C@s~E70V@u$)P_@oEC6Jb2rLN1$_MFe z!-KTZRKe2TlQ+%s~?t9T2Jm7X;bM z3qh+6prs2J2CnMD89^JbE~uafG8<*i_-%=&}jOYn`Ax0t&koIzr^d}2&4DJ+4UJhRs+IvOnhqu5g_H_SSPndh3G!1pH@`%K&4f#`8m0ArN9N z2n7G%0#NTQLm{5FmNqW7|MC9ZG6MH=@&iye`n`FV3z~WeJT`)JfM?MHQfyu&Y~YC? zHr>Czt1x3w2UP`Fjeoza#uv0+4+t`bgKYw+zMziTz>qOq4y5EJAnhmugiYYLn87dQ z#b#Z)Y`zzYK_H()ArRVst9AMlHXzxFeI0ma0>1)!mxJEe??_<42NO6e0UqSHyM`N+ z6%Yz`7bsE=pfrWkfkLneQ3463aC|7XB4BW7^ECxi=O_W`m$V6_FcDQ41n>}rkpY{g zaAMFA>{1NSUNwN>KAaPzs`o+BI~P#YVFn}P|8v&(7pMAn0Z(Ys##IQx#tz<%KQK1C6fab+R`Y;$SKxg(lJC7Oo08@1F;1-xY=z@MJztlCE z!NGr-fZhvRZw0UlB1j3$!2&HS!2;{DU=+YaI*bs|H2-~AV7H_M+|A+mu<+{3=X5}} z`R_cHpck~R7WioXyH$XFlmY5F4_vc=gH0I#J1HfgW&t`feFq)sMqmO!g2ivgYzt5s zv delta 1849 zcmZWpeN0nV6uKn3RYsX5kr@0BHcYMd>y4|sel=W5+4hu`!9>oVmaOEP$y*gTIiW1y zIkD`P?RWRITOw7)=oogc?c;TX5HZ3k{&)Qn>CBYMByz?k{gA*>_in|PohO0@=(6y{ zGrk2wndr+ZKK3NSr7aDK2-!__*$8b%4AlrdL3M*f;E|Op^Ucl{@2))WPH#BD!CnlKPEoI$eUTk>? zPgR7l#K=0Z?7&zhd!&kZCp({k*zRZh;t&&$v+u+rCQq_I#3IH&WOoq8`dJrRZ6C38 zv02j|t_1o9Sh7g*$q>6BQob2vgF^c0o2*XY{t5QXe#GJCsJ-_P^SAQ@Q3*3m^6$aJ zh?y6m*&L=ko2kku(Ig_83>@f_OmNu3pU240kA*zWlL|aM|Mx?{)CSHiF6&XFh1>&u|s8j#yB3*>mEfKjC;;h_=k+oKg+;gOJ zFsML>RV(BJVLBQ_Q;s%IM|9Y#qOnvd0BJTY-*Yx(H=xGG(@|xoV7sB)##4}WG;=j= za~UNrlgX3+QoSi}lQXZ;QSb3Ylrf4ybfOHVn>n^L=75qd`)f3BHoWNKPoUOX7fKJj4NWdyinL$QC_h|r@#RSW5>&ki zDJ^^%(lsrp5c^ODQwz^RjyFn)n=SoxKAdjRcHpuITvxzAEoVuQO%mUVg5!md->Svo z)r%C^T?{R)93L{kyQn~aE7!5O7Z?Hc6=s0Pm5fJf;XPIKv)N;}Vc@urC4#}t=b;AP zUj<6ssPXk)bou+3QaF3gp{^y`X*7;}`qO)y5HT`m74d8Hp_!Rba-8YmoLk$p5jR&^ zmOt!L`xs03ud;Y1BFjsKaQH?KpD&i!KWFW6UC`#?sz@&yWXhFsHi(y9jPyAro$6w6 zVgQ%+qep8Fe0Ws(i}y9-vRrY4B9|8TS$5sw0z$-4=IGq(WpH(fCBt5?wy1+%)HyrK zpgqV8k^6iF9n|s-{O0AQ88hX@TsF7e-$#fTi{{8)xCYfej_)VnBd0*SkL&1E4fKR; a=Y6PUuf%iWN%|sEL@e_Nx%)EiJNXCDBjq6g diff --git a/jdk/test/tools/pack200/pack200-verifier/make/build.xml b/jdk/test/tools/pack200/pack200-verifier/make/build.xml index 76e5f72cf89..b783ffda881 100644 --- a/jdk/test/tools/pack200/pack200-verifier/make/build.xml +++ b/jdk/test/tools/pack200/pack200-verifier/make/build.xml @@ -1,5 +1,5 @@ - + @@ -22,7 +22,7 @@ diff --git a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java index 4a3af66344e..0579b5b99cd 100644 --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java +++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012, 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 @@ -24,16 +24,58 @@ */ package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*- +import com.sun.tools.classfile.AccessFlags; +import com.sun.tools.classfile.Annotation; +import com.sun.tools.classfile.Annotation.*; +import com.sun.tools.classfile.AnnotationDefault_attribute; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.Attributes; +import com.sun.tools.classfile.BootstrapMethods_attribute; +import com.sun.tools.classfile.CharacterRangeTable_attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.CompilationID_attribute; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPool.*; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.ConstantValue_attribute; +import com.sun.tools.classfile.DefaultAttribute; +import com.sun.tools.classfile.Deprecated_attribute; +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; +import com.sun.tools.classfile.EnclosingMethod_attribute; +import com.sun.tools.classfile.Exceptions_attribute; +import com.sun.tools.classfile.Field; +import com.sun.tools.classfile.InnerClasses_attribute; +import com.sun.tools.classfile.InnerClasses_attribute.Info; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Instruction.TypeKind; +import com.sun.tools.classfile.LineNumberTable_attribute; +import com.sun.tools.classfile.LocalVariableTable_attribute; +import com.sun.tools.classfile.LocalVariableTypeTable_attribute; +import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.Opcode; +import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; +import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.Signature_attribute; +import com.sun.tools.classfile.SourceDebugExtension_attribute; +import com.sun.tools.classfile.SourceFile_attribute; +import com.sun.tools.classfile.SourceID_attribute; +import com.sun.tools.classfile.StackMapTable_attribute; +import com.sun.tools.classfile.StackMapTable_attribute.*; +import com.sun.tools.classfile.StackMap_attribute; +import com.sun.tools.classfile.Synthetic_attribute; import java.util.*; -import java.util.jar.*; -import java.lang.reflect.*; import java.io.*; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import xmlkit.XMLKit.Element; /* - * @author jrose + * @author jrose, ksrini */ -public class ClassReader extends ClassSyntax { +public class ClassReader { private static final CommandLineParser CLP = new CommandLineParser("" + "-source: +> = \n" @@ -41,23 +83,24 @@ public class ClassReader extends ClassSyntax { + "-encoding: +> = \n" + "-jcov $ \n -nojcov !-jcov \n" + "-verbose $ \n -noverbose !-verbose \n" - + "-pretty $ \n -nopretty !-pretty \n" + "-keepPath $ \n -nokeepPath !-keepPath \n" + "-keepCP $ \n -nokeepCP !-keepCP \n" - + "-keepBytes $ \n -nokeepBytes !-keepBytes \n" - + "-parseBytes $ \n -noparseBytes !-parseBytes \n" - + "-resolveRefs $ \n -noresolveRefs !-resolveRefs \n" + "-keepOrder $ \n -nokeepOrder !-keepOrder \n" - + "-keepSizes $ \n -nokeepSizes !-keepSizes \n" + "-continue $ \n -nocontinue !-continue \n" - + "-attrDef & \n" + "-@ >-@ . \n" + "- +? \n" + "\n"); + + // Protected state for representing the class file. + protected Element cfile; // + protected Element cpool; // + protected Element klass; // + protected List thePool; // stringified flattened Constant Pool + public static void main(String[] ava) throws IOException { - ArrayList av = new ArrayList(Arrays.asList(ava)); - HashMap props = new HashMap(); + ArrayList av = new ArrayList<>(Arrays.asList(ava)); + HashMap props = new HashMap<>(); props.put("-encoding:", "UTF8"); // default props.put("-keepOrder", null); // CLI default props.put("-pretty", "1"); // CLI default @@ -80,7 +123,7 @@ public class ClassReader extends ClassSyntax { } */ if (av.isEmpty()) { - av.add("doit"); //to enter this loop + av.add(""); //to enter this loop } boolean readList = false; for (String a : av) { @@ -119,7 +162,7 @@ public class ClassReader extends ClassSyntax { private static void doFile(String a, File source, File dest, ClassReader options, String encoding, - boolean contError) throws IOException { + boolean contError) throws IOException { if (!contError) { doFile(a, source, dest, options, encoding); } else { @@ -127,40 +170,49 @@ public class ClassReader extends ClassSyntax { doFile(a, source, dest, options, encoding); } catch (Exception ee) { System.out.println("Error processing " + source + ": " + ee); + ee.printStackTrace(); } } } - private static void doJar(String a, File source, File dest, ClassReader options, - String encoding, Boolean contError) throws IOException { + private static void doJar(String a, File source, File dest, + ClassReader options, String encoding, + Boolean contError) throws IOException { try { JarFile jf = new JarFile(source); - for (JarEntry je : Collections.list((Enumeration) jf.entries())) { + for (JarEntry je : Collections.list(jf.entries())) { String name = je.getName(); if (!name.endsWith(".class")) { continue; } - doStream(name, jf.getInputStream(je), dest, options, encoding); + try { + doStream(name, jf.getInputStream(je), dest, options, encoding); + } catch (Exception e) { + if (contError) { + System.out.println("Error processing " + source + ": " + e); + e.printStackTrace(); + continue; + } + } } } catch (IOException ioe) { - if (contError) { - System.out.println("Error processing " + source + ": " + ioe); - } else { - throw ioe; - } + throw ioe; } } private static void doStream(String a, InputStream in, File dest, - ClassReader options, String encoding) throws IOException { + ClassReader options, String encoding) throws IOException { File f = new File(a); ClassReader cr = new ClassReader(options); - Element e = cr.readFrom(in); + Element e; + if (options.verbose) { + System.out.println("Reading " + f); + } + e = cr.readFrom(in); OutputStream out; if (dest == null) { - //System.out.println(e.prettyString()); out = System.out; } else { File outf = new File(dest, f.isAbsolute() ? f.getName() : f.getPath()); @@ -202,20 +254,8 @@ public class ClassReader extends ClassSyntax { } - public static BufferedReader makeReader(InputStream in, String encoding) throws IOException { - // encoding in DEFAULT, '', UTF8, 8BIT, , or any valid encoding name - if (encoding.equals("8BIT")) { - encoding = EIGHT_BIT_CHAR_ENCODING; - } - if (encoding.equals("UTF8")) { - encoding = UTF8_ENCODING; - } - if (encoding.equals("DEFAULT")) { - encoding = null; - } - if (encoding.equals("-")) { - encoding = null; - } + public static BufferedReader makeReader(InputStream in, + String encoding) throws IOException { Reader inw; in = new BufferedInputStream(in); // add buffering if (encoding == null) { @@ -226,20 +266,8 @@ public class ClassReader extends ClassSyntax { return new BufferedReader(inw); // add buffering } - public static Writer makeWriter(OutputStream out, String encoding) throws IOException { - // encoding in DEFAULT, '', UTF8, 8BIT, , or any valid encoding name - if (encoding.equals("8BIT")) { - encoding = EIGHT_BIT_CHAR_ENCODING; - } - if (encoding.equals("UTF8")) { - encoding = UTF8_ENCODING; - } - if (encoding.equals("DEFAULT")) { - encoding = null; - } - if (encoding.equals("-")) { - encoding = null; - } + public static Writer makeWriter(OutputStream out, + String encoding) throws IOException { Writer outw; if (encoding == null) { outw = new OutputStreamWriter(out); @@ -252,12 +280,9 @@ public class ClassReader extends ClassSyntax { public Element result() { return cfile; } + protected InputStream in; protected ByteArrayOutputStream buf = new ByteArrayOutputStream(1024); - protected byte cpTag[]; - protected String cpName[]; - protected String[] callables; // varies - public static final String REF_PREFIX = "#"; // input options public boolean pretty = false; public boolean verbose = false; @@ -270,7 +295,7 @@ public class ClassReader extends ClassSyntax { public boolean keepSizes = false; public ClassReader() { - super.cfile = new Element("ClassFile"); + cfile = new Element("ClassFile"); } public ClassReader(ClassReader options) { @@ -283,12 +308,7 @@ public class ClassReader extends ClassSyntax { verbose = options.verbose; keepPath = options.keepPath; keepCP = options.keepCP; - keepBytes = options.keepBytes; - parseBytes = options.parseBytes; - resolveRefs = options.resolveRefs; - keepSizes = options.keepSizes; keepOrder = options.keepOrder; - attrTypes = options.attrTypes; } public void copyOptionsFrom(Map options) { @@ -304,274 +324,177 @@ public class ClassReader extends ClassSyntax { if (options.containsKey("-keepCP")) { keepCP = (options.get("-keepCP") != null); } - if (options.containsKey("-keepBytes")) { - keepBytes = (options.get("-keepBytes") != null); - } - if (options.containsKey("-parseBytes")) { - parseBytes = (options.get("-parseBytes") != null); - } - if (options.containsKey("-resolveRefs")) { - resolveRefs = (options.get("-resolveRefs") != null); - } - if (options.containsKey("-keepSizes")) { - keepSizes = (options.get("-keepSizes") != null); - } if (options.containsKey("-keepOrder")) { keepOrder = (options.get("-keepOrder") != null); } - if (options.containsKey("-attrDef")) { - addAttrTypes(options.get("-attrDef").split(" ")); - } - if (options.get("-jcov") != null) { - addJcovAttrTypes(); - } + } + + protected String getCpString(int i) { + return thePool.get(i); } public Element readFrom(InputStream in) throws IOException { - this.in = in; - // read the file header - int magic = u4(); - if (magic != 0xCAFEBABE) { - throw new RuntimeException("bad magic number " + Integer.toHexString(magic)); + try { + this.in = in; + ClassFile c = ClassFile.read(in); + // read the file header + if (c.magic != 0xCAFEBABE) { + throw new RuntimeException("bad magic number " + + Integer.toHexString(c.magic)); + } + cfile.setAttr("magic", "" + c.magic); + int minver = c.minor_version; + int majver = c.major_version; + cfile.setAttr("minver", "" + minver); + cfile.setAttr("majver", "" + majver); + readCP(c); + readClass(c); + return result(); + } catch (InvalidDescriptor | ConstantPoolException ex) { + throw new IOException("Fatal error", ex); } - cfile.setAttr("magic", "" + magic); - int minver = u2(); - int majver = u2(); - cfile.setAttr("minver", "" + minver); - cfile.setAttr("majver", "" + majver); - readCP(); - readClass(); - return result(); } public Element readFrom(File file) throws IOException { - InputStream in = null; - try { - in = new FileInputStream(file); - Element e = readFrom(new BufferedInputStream(in)); + try (InputStream strm = new FileInputStream(file)) { + Element e = readFrom(new BufferedInputStream(strm)); if (keepPath) { e.setAttr("path", file.toString()); } return e; - } finally { - if (in != null) { - in.close(); - } } } - private void readClass() throws IOException { + private void readClass(ClassFile c) throws IOException, + ConstantPoolException, + InvalidDescriptor { klass = new Element("Class"); cfile.add(klass); - int flags = u2(); - String thisk = cpRef(); - String superk = cpRef(); + String thisk = c.getName(); + klass.setAttr("name", thisk); - boolean flagsSync = ((flags & Modifier.SYNCHRONIZED) != 0); - flags &= ~Modifier.SYNCHRONIZED; - String flagString = flagString(flags, klass); - if (!flagsSync) { - if (flagString.length() > 0) { - flagString += " "; - } - flagString += "!synchronized"; + + AccessFlags af = new AccessFlags(c.access_flags.flags); + klass.setAttr("flags", flagString(af, klass)); + if (!"java/lang/Object".equals(thisk)) { + klass.setAttr("super", c.getSuperclassName()); } - klass.setAttr("flags", flagString); - klass.setAttr("super", superk); - for (int len = u2(), i = 0; i < len; i++) { - String interk = cpRef(); - klass.add(new Element("Interface", "name", interk)); + for (int i : c.interfaces) { + klass.add(new Element("Interface", "name", getCpString(i))); + } + readFields(c, klass); + readMethods(c, klass); + readAttributesFor(c, c.attributes, klass); + klass.trimToSize(); + } + + private void readFields(ClassFile c, Element klass) throws IOException { + int len = c.fields.length; + Element fields = new Element(len); + for (Field f : c.fields) { + Element field = new Element("Field"); + field.setAttr("name", getCpString(f.name_index)); + field.setAttr("type", getCpString(f.descriptor.index)); + field.setAttr("flags", flagString(f.access_flags.flags, field)); + readAttributesFor(c, f.attributes, field); + + field.trimToSize(); + fields.add(field); + } + if (!keepOrder) { + fields.sort(); } - Element fields = readMembers("Field"); klass.addAll(fields); - Element methods = readMembers("Method"); + } + + + private void readMethods(ClassFile c, Element klass) throws IOException { + int len = c.methods.length; + Element methods = new Element(len); + for (Method m : c.methods) { + Element member = new Element("Method"); + member.setAttr("name", getCpString(m.name_index)); + member.setAttr("type", getCpString(m.descriptor.index)); + member.setAttr("flags", flagString(m.access_flags.flags, member)); + readAttributesFor(c, m.attributes, member); + + member.trimToSize(); + methods.add(member); + } if (!keepOrder) { methods.sort(); } klass.addAll(methods); - readAttributesFor(klass); - klass.trimToSize(); - if (keepSizes) { - attachTo(cfile, formatAttrSizes()); - } - if (paddingSize != 0) { - cfile.setAttr("padding", "" + paddingSize); - } } - private Element readMembers(String kind) throws IOException { - int len = u2(); - Element members = new Element(len); - for (int i = 0; i < len; i++) { - Element member = new Element(kind); - int flags = u2(); - String name = cpRef(); - String type = cpRef(); - member.setAttr("name", name); - member.setAttr("type", type); - member.setAttr("flags", flagString(flags, member)); - readAttributesFor(member); - member.trimToSize(); - members.add(member); + private AccessFlags.Kind getKind(Element e) { + switch(e.getName()) { + case "Class": + return AccessFlags.Kind.Class; + case "InnerClass": + return AccessFlags.Kind.InnerClass; + case "Field": + return AccessFlags.Kind.Field ; + case "Method": + return AccessFlags.Kind.Method; + default: throw new RuntimeException("should not reach here"); } - return members; } protected String flagString(int flags, Element holder) { - // Superset of Modifier.toString. - int kind = 0; - if (holder.getName() == "Field") { - kind = 1; + return flagString(new AccessFlags(flags), holder); + } + protected String flagString(AccessFlags af, Element holder) { + return flagString(af, holder.getName()); + } + protected String flagString(int flags, String kind) { + return flagString(new AccessFlags(flags), kind); + } + protected String flagString(AccessFlags af, String kind) { + Set mods = null; + switch (kind) { + case "Class": + mods = af.getClassFlags(); + break; + case "InnerClass": + mods = af.getInnerClassFlags(); + break; + case "Field": + mods = af.getFieldFlags(); + break; + case "Method": + mods = af.getMethodFlags(); + break; + default: + throw new RuntimeException("should not reach here"); } - if (holder.getName() == "Method") { - kind = 2; + StringBuilder sb = new StringBuilder(); + for (String x : mods) { + sb.append(x.substring(x.indexOf('_') + 1).toLowerCase()).append(" "); } - StringBuffer sb = new StringBuffer(); - for (int i = 0; flags != 0; i++, flags >>>= 1) { - if ((flags & 1) != 0) { - if (sb.length() > 0) { - sb.append(' '); - } - if (i < modifierNames.length) { - String[] names = modifierNames[i]; - String name = (kind < names.length) ? names[kind] : null; - for (String name2 : names) { - if (name != null) { - break; - } - name = name2; - } - sb.append(name); - } else { - sb.append("#").append(1 << i); - } - } - } - return sb.toString(); + return sb.toString().trim(); } - private void readAttributesFor(Element x) throws IOException { - Element prevCurrent; - Element y = new Element(); - if (x.getName() == "Code") { - prevCurrent = currentCode; - currentCode = x; - } else { - prevCurrent = currentMember; - currentMember = x; - } - for (int len = u2(), i = 0; i < len; i++) { - int ref = u2(); - String uname = cpName(ref).intern(); - String refName = uname; - if (!resolveRefs) { - refName = (REF_PREFIX + ref).intern(); - } - String qname = (x.getName() + "." + uname).intern(); - String wname = ("*." + uname).intern(); - String type = attrTypes.get(qname); - if (type == null || "".equals(type)) { - type = attrTypes.get(wname); - } - if ("".equals(type)) { - type = null; - } - int size = u4(); - int[] countVar = attrSizes.get(qname); - if (countVar == null) { - attrSizes.put(qname, countVar = new int[2]); - } - countVar[0] += 1; - countVar[1] += size; - buf.reset(); - for (int j = 0; j < size; j++) { - buf.write(u1()); - } - if (type == null && size == 0) { - y.add(new Element(uname)); // , etc. - } else if (type == null) { - //System.out.println("Warning: No attribute type description: "+qname); - // write cdata attribute - Element a = new Element("Attribute", - new String[]{"Name", refName}, - buf.toString(EIGHT_BIT_CHAR_ENCODING)); - a.addContent(getCPDigest()); - y.add(a); - } else if (type.equals("")) { - // ignore this attribute... - } else { - InputStream in0 = in; - int fileSize0 = fileSize; - ByteArrayInputStream in1 = new ByteArrayInputStream(buf.toByteArray()); - boolean ok = false; - try { - in = in1; - // parse according to type desc. - Element aval; - if (type.equals("...")) { - // delve into Code attribute - aval = readCode(); - } else if (type.equals("...")) { - // delve into StackMap attribute - aval = readStackMap(false); - } else if (type.equals("...")) { - // delve into StackMap attribute - aval = readStackMap(true); - } else if (type.startsWith("[")) { - aval = readAttributeCallables(type); - } else { - aval = readAttribute(type); - } - //System.out.println("attachTo 1 "+y+" <- "+aval); - attachTo(y, aval); - if (false - && in1.available() != 0) { - throw new RuntimeException("extra bytes in " + qname + " :" + in1.available()); - } - ok = true; - } finally { - in = in0; - fileSize = fileSize0; - if (!ok) { - System.out.println("*** Failed to read " + type); - } - } - } - } - if (x.getName() == "Code") { - currentCode = prevCurrent; - } else { - currentMember = prevCurrent; + + protected void readAttributesFor(ClassFile c, Attributes attrs, Element x) { + Element container = new Element(); + AttributeVisitor av = new AttributeVisitor(this, c); + for (Attribute a : attrs) { + av.visit(a, container); } if (!keepOrder) { - y.sort(); - y.sortAttrs(); + container.sort(); } - //System.out.println("attachTo 2 "+x+" <- "+y); - attachTo(x, y); + x.addAll(container); } - private int fileSize = 0; - private int paddingSize = 0; - private HashMap attrSizes = new HashMap(); - private Element formatAttrSizes() { - Element e = new Element("Sizes"); - e.setAttr("fileSize", "" + fileSize); - for (Map.Entry ie : attrSizes.entrySet()) { - int[] countVar = ie.getValue(); - e.add(new Element("AttrSize", - "name", ie.getKey().toString(), - "count", "" + countVar[0], - "size", "" + countVar[1])); - } - return e; - } + private int fileSize = 0; + private HashMap attrSizes = new HashMap<>(); private void attachTo(Element x, Object aval0) { if (aval0 == null) { return; } - //System.out.println("attachTo "+x+" : "+aval0); if (!(aval0 instanceof Element)) { x.add(aval0); return; @@ -589,7 +512,6 @@ public class ClassReader extends ClassSyntax { } private void attachAttrTo(Element x, String aname, String aval) { - //System.out.println("attachAttrTo "+x+" : "+aname+"="+aval); String aval0 = x.getAttr(aname); if (aval0 != null) { aval = aval0 + " " + aval; @@ -597,407 +519,1003 @@ public class ClassReader extends ClassSyntax { x.setAttr(aname, aval); } - private Element readAttributeCallables(String type) throws IOException { - assert (callables == null); - callables = getBodies(type); - Element res = readAttribute(callables[0]); - callables = null; - return res; - } - - private Element readAttribute(String type) throws IOException { - //System.out.println("readAttribute "+type); - Element aval = new Element(); - String nextAttrName = null; - for (int len = type.length(), next, i = 0; i < len; i = next) { - String value; - switch (type.charAt(i)) { - case '<': - assert (nextAttrName == null); - next = type.indexOf('>', ++i); - String form = type.substring(i, next++); - if (form.indexOf('=') < 0) { - // elem_placement = '<' elemname '>' - assert (aval.attrSize() == 0); - assert (aval.isAnonymous()); - aval.setName(form.intern()); - } else { - // attr_placement = '<' attrname '=' (value)? '>' - int eqPos = form.indexOf('='); - nextAttrName = form.substring(0, eqPos).intern(); - if (eqPos != form.length() - 1) { - value = form.substring(eqPos + 1); - attachAttrTo(aval, nextAttrName, value); - nextAttrName = null; - } - // ...else subsequent type parsing will find the attr value - // and add it as "nextAttrName". - } - continue; - case '(': - next = type.indexOf(')', ++i); - int callee = Integer.parseInt(type.substring(i, next++)); - attachTo(aval, readAttribute(callables[callee])); - continue; - case 'N': // replication = 'N' int '[' type ... ']' - { - int count = getInt(type.charAt(i + 1), false); - assert (count >= 0); - next = i + 2; - String type1 = getBody(type, next); - next += type1.length() + 2; // skip body and brackets - for (int j = 0; j < count; j++) { - attachTo(aval, readAttribute(type1)); - } - } - continue; - case 'T': // union = 'T' any_int union_case* '(' ')' '[' body ']' - int tagValue; - if (type.charAt(++i) == 'S') { - tagValue = getInt(type.charAt(++i), true); - } else { - tagValue = getInt(type.charAt(i), false); - } - attachAttrTo(aval, "tag", "" + tagValue); // always named "tag" - ++i; // skip the int type char - // union_case = '(' uc_tag (',' uc_tag)* ')' '[' body ']' - // uc_tag = ('-')? digit+ - for (boolean foundCase = false;; i = next) { - assert (type.charAt(i) == '('); - next = type.indexOf(')', ++i); - assert (next >= i); - if (type.charAt(next - 1) == '\\' - && type.charAt(next - 2) != '\\') // Skip an escaped paren. - { - next = type.indexOf(')', next + 1); - } - String caseStr = type.substring(i, next++); - String type1 = getBody(type, next); - next += type1.length() + 2; // skip body and brackets - boolean lastCase = (caseStr.length() == 0); - if (!foundCase - && (lastCase || matchTag(tagValue, caseStr))) { - foundCase = true; - // Execute this body. - attachTo(aval, readAttribute(type1)); - } - if (lastCase) { - break; - } - } - continue; - case 'B': - case 'H': - case 'I': // int = oneof "BHI" - next = i + 1; - value = "" + getInt(type.charAt(i), false); - break; - case 'K': - assert ("IJFDLQ".indexOf(type.charAt(i + 1)) >= 0); - assert (type.charAt(i + 2) == 'H'); // only H works for now - next = i + 3; - value = cpRef(); - break; - case 'R': - assert ("CSDFMIU?".indexOf(type.charAt(i + 1)) >= 0); - assert (type.charAt(i + 2) == 'H'); // only H works for now - next = i + 3; - value = cpRef(); - break; - case 'P': // bci = 'P' int - next = i + 2; - value = "" + getInt(type.charAt(i + 1), false); - break; - case 'S': // signed_int = 'S' int - next = i + 2; - value = "" + getInt(type.charAt(i + 1), true); - break; - case 'F': - next = i + 2; - value = flagString(getInt(type.charAt(i + 1), false), currentMember); - break; - default: - throw new RuntimeException("bad attr format '" + type.charAt(i) + "': " + type); - } - // store the value - if (nextAttrName != null) { - attachAttrTo(aval, nextAttrName, value); - nextAttrName = null; - } else { - attachTo(aval, value); + private void readCP(ClassFile c) throws IOException { + cpool = new Element("ConstantPool", c.constant_pool.size()); + ConstantPoolVisitor cpv = new ConstantPoolVisitor(cpool, c, + c.constant_pool.size()); + for (int i = 1 ; i < c.constant_pool.size() ; i++) { + try { + cpv.visit(c.constant_pool.get(i), i); + } catch (InvalidIndex ex) { + // can happen periodically when accessing doubles etc. ignore it + // ex.printStackTrace(); } } - //System.out.println("readAttribute => "+aval); - assert (nextAttrName == null); - return aval; - } - - private int getInt(char ch, boolean signed) throws IOException { - if (signed) { - switch (ch) { - case 'B': - return (byte) u1(); - case 'H': - return (short) u2(); - case 'I': - return (int) u4(); + thePool = cpv.getPoolList(); + if (verbose) { + for (int i = 0; i < thePool.size(); i++) { + System.out.println("[" + i + "]: " + thePool.get(i)); } - } else { - switch (ch) { - case 'B': - return u1(); - case 'H': - return u2(); - case 'I': - return u4(); - } - } - assert ("BHIJ".indexOf(ch) >= 0); - return 0; - } - - private Element readCode() throws IOException { - int stack = u2(); - int local = u2(); - int length = u4(); - StringBuilder sb = new StringBuilder(length); - for (int i = 0; i < length; i++) { - sb.append((char) u1()); - } - String bytecodes = sb.toString(); - Element e = new Element("Code", - "stack", "" + stack, - "local", "" + local); - Element bytes = new Element("Bytes", (String[]) null, bytecodes); - if (keepBytes) { - e.add(bytes); - } - if (parseBytes) { - e.add(parseByteCodes(bytecodes)); - } - for (int len = u2(), i = 0; i < len; i++) { - int start = u2(); - int end = u2(); - int catsh = u2(); - String clasz = cpRef(); - e.add(new Element("Handler", - "start", "" + start, - "end", "" + end, - "catch", "" + catsh, - "class", clasz)); - } - readAttributesFor(e); - e.trimToSize(); - return e; - } - - private Element parseByteCodes(String bytecodes) { - Element e = InstructionSyntax.parse(bytecodes); - for (Element ins : e.elements()) { - Number ref = ins.getAttrNumber("ref"); - if (ref != null && resolveRefs) { - int id = ref.intValue(); - String val = cpName(id); - if (ins.getName().startsWith("ldc")) { - // Yuck: Arb. string cannot be an XML attribute. - ins.add(val); - val = ""; - byte tag = (id >= 0 && id < cpTag.length) ? cpTag[id] : 0; - if (tag != 0) { - ins.setAttrLong("tag", tag); - } - } - if (ins.getName() == "invokeinterface" - && computeInterfaceNum(val) == ins.getAttrLong("num")) { - ins.setAttr("num", null); // garbage bytes - } - ins.setAttr("ref", null); - ins.setAttr("val", val); - } - } - return e; - } - - private Element readStackMap(boolean hasXOption) throws IOException { - Element result = new Element(); - Element bytes = currentCode.findElement("Bytes"); - assert (bytes != null && bytes.size() == 1); - int byteLength = ((String) bytes.get(0)).length(); - boolean uoffsetIsU4 = (byteLength >= (1 << 16)); - boolean ulocalvarIsU4 = currentCode.getAttrLong("local") >= (1 << 16); - boolean ustackIsU4 = currentCode.getAttrLong("stack") >= (1 << 16); - if (hasXOption || uoffsetIsU4 || ulocalvarIsU4 || ustackIsU4) { - Element flags = new Element("StackMapFlags"); - if (hasXOption) { - flags.setAttr("hasXOption", "true"); - } - if (uoffsetIsU4) { - flags.setAttr("uoffsetIsU4", "true"); - } - if (ulocalvarIsU4) { - flags.setAttr("ulocalvarIsU4", "true"); - } - if (ustackIsU4) { - flags.setAttr("ustackIsU4", "true"); - } - currentCode.add(flags); - } - int frame_count = (uoffsetIsU4 ? u4() : u2()); - for (int i = 0; i < frame_count; i++) { - int bci = (uoffsetIsU4 ? u4() : u2()); - int flags = (hasXOption ? u1() : 0); - Element frame = new Element("Frame"); - result.add(frame); - if (flags != 0) { - frame.setAttr("flags", "" + flags); - } - frame.setAttr("bci", "" + bci); - // Scan local and stack types in this frame: - final int LOCALS = 0, STACK = 1; - for (int j = LOCALS; j <= STACK; j++) { - int typeSize; - if (j == LOCALS) { - typeSize = (ulocalvarIsU4 ? u4() : u2()); - } else { // STACK - typeSize = (ustackIsU4 ? u4() : u2()); - } - Element types = new Element(j == LOCALS ? "Local" : "Stack"); - for (int k = 0; k < typeSize; k++) { - int tag = u1(); - Element type = new Element(itemTagName(tag)); - types.add(type); - switch (tag) { - case ITEM_Object: - type.setAttr("class", cpRef()); - break; - case ITEM_Uninitialized: - case ITEM_ReturnAddress: - type.setAttr("bci", "" + (uoffsetIsU4 ? u4() : u2())); - break; - } - } - if (types.size() > 0) { - frame.add(types); - } - } - } - return result; - } - - private void readCP() throws IOException { - int cpLen = u2(); - cpTag = new byte[cpLen]; - cpName = new String[cpLen]; - int cpTem[][] = new int[cpLen][]; - for (int i = 1; i < cpLen; i++) { - cpTag[i] = (byte) u1(); - switch (cpTag[i]) { - case CONSTANT_Utf8: - buf.reset(); - for (int len = u2(), j = 0; j < len; j++) { - buf.write(u1()); - } - cpName[i] = buf.toString(UTF8_ENCODING); - break; - case CONSTANT_Integer: - cpName[i] = String.valueOf((int) u4()); - break; - case CONSTANT_Float: - cpName[i] = String.valueOf(Float.intBitsToFloat(u4())); - break; - case CONSTANT_Long: - cpName[i] = String.valueOf(u8()); - i += 1; - break; - case CONSTANT_Double: - cpName[i] = String.valueOf(Double.longBitsToDouble(u8())); - i += 1; - break; - case CONSTANT_Class: - case CONSTANT_String: - cpTem[i] = new int[]{u2()}; - break; - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - case CONSTANT_NameAndType: - cpTem[i] = new int[]{u2(), u2()}; - break; - } - } - for (int i = 1; i < cpLen; i++) { - switch (cpTag[i]) { - case CONSTANT_Class: - case CONSTANT_String: - cpName[i] = cpName[cpTem[i][0]]; - break; - case CONSTANT_NameAndType: - cpName[i] = cpName[cpTem[i][0]] + " " + cpName[cpTem[i][1]]; - break; - } - } - // do fieldref et al after nameandtype are all resolved - for (int i = 1; i < cpLen; i++) { - switch (cpTag[i]) { - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - cpName[i] = cpName[cpTem[i][0]] + " " + cpName[cpTem[i][1]]; - break; - } - } - cpool = new Element("ConstantPool", cpName.length); - for (int i = 0; i < cpName.length; i++) { - if (cpName[i] == null) { - continue; - } - cpool.add(new Element(cpTagName(cpTag[i]), - new String[]{"id", "" + i}, - cpName[i])); } if (keepCP) { cfile.add(cpool); } } +} - private String cpRef() throws IOException { - int ref = u2(); - if (resolveRefs) { - return cpName(ref); - } else { - return REF_PREFIX + ref; +class ConstantPoolVisitor implements ConstantPool.Visitor { + final List slist; + final Element xpool; + final ClassFile cf; + final ConstantPool cfpool; + final List bsmlist; + + + public ConstantPoolVisitor(Element xpool, ClassFile cf, int size) { + slist = new ArrayList<>(size); + for (int i = 0 ; i < size; i++) { + slist.add(null); + } + this.xpool = xpool; + this.cf = cf; + this.cfpool = cf.constant_pool; + bsmlist = readBSM(); + } + + public List getPoolList() { + return Collections.unmodifiableList(slist); + } + + public List getBSMList() { + return Collections.unmodifiableList(bsmlist); + } + + public String visit(CPInfo c, int index) { + return c.accept(this, index); + } + + private List readBSM() { + BootstrapMethods_attribute bsmAttr = + (BootstrapMethods_attribute) cf.getAttribute(Attribute.BootstrapMethods); + if (bsmAttr != null) { + List out = + new ArrayList<>(bsmAttr.bootstrap_method_specifiers.length); + for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsms : + bsmAttr.bootstrap_method_specifiers) { + int index = bsms.bootstrap_method_ref; + try { + String value = slist.get(index); + String bsmStr = value; + if (value == null) { + value = visit(cfpool.get(index), index); + slist.set(index, value); + } + bsmStr = value; + for (int idx : bsms.bootstrap_arguments) { + value = slist.get(idx); + if (value == null) { + value = visit(cfpool.get(idx), idx); + slist.set(idx, value); + } + bsmStr = bsmStr.concat("," + value); + } + out.add(bsmStr); + } catch (InvalidIndex ex) { + ex.printStackTrace(); + } + } + return out; + } + return new ArrayList<>(0); + } + + @Override + public String visitClass(CONSTANT_Class_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.name_index), c.name_index); + slist.set(p, value); + xpool.add(new Element("CONSTANT_Class", + new String[]{"id", p.toString()}, + value)); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitDouble(CONSTANT_Double_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + value = Double.toString(c.value); + slist.set(p, value); + xpool.add(new Element("CONSTANT_Double", + new String[]{"id", p.toString()}, + value)); + } + return value; + } + + @Override + public String visitFieldref(CONSTANT_Fieldref_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.class_index), c.class_index); + value = value.concat(" " + visit(cfpool.get(c.name_and_type_index), + c.name_and_type_index)); + slist.set(p, value); + xpool.add(new Element("CONSTANT_Fieldref", + new String[]{"id", p.toString()}, + value)); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitFloat(CONSTANT_Float_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + value = Float.toString(c.value); + slist.set(p, value); + xpool.add(new Element("CONSTANT_Float", + new String[]{"id", p.toString()}, + value)); + } + return value; + } + + @Override + public String visitInteger(CONSTANT_Integer_info cnstnt, Integer p) { + String value = slist.get(p); + if (value == null) { + value = Integer.toString(cnstnt.value); + slist.set(p, value); + xpool.add(new Element("CONSTANT_Integer", + new String[]{"id", p.toString()}, + value)); + } + return value; + } + + @Override + public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info c, + Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.class_index), c.class_index); + value = value.concat(" " + + visit(cfpool.get(c.name_and_type_index), + c.name_and_type_index)); + slist.set(p, value); + xpool.add(new Element("CONSTANT_InterfaceMethodref", + new String[]{"id", p.toString()}, + value)); + + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = bsmlist.get(c.bootstrap_method_attr_index) + " " + + visit(cfpool.get(c.name_and_type_index), c.name_and_type_index); + slist.set(p, value); + xpool.add(new Element("CONSTANT_InvokeDynamic", + new String[]{"id", p.toString()}, + value)); + + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitLong(CONSTANT_Long_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + value = Long.toString(c.value); + slist.set(p, value); + xpool.add(new Element("CONSTANT_Long", + new String[]{"id", p.toString()}, + value)); + } + return value; + } + + @Override + public String visitNameAndType(CONSTANT_NameAndType_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.name_index), c.name_index); + value = value.concat(" " + + visit(cfpool.get(c.type_index), c.type_index)); + slist.set(p, value); + xpool.add(new Element("CONSTANT_NameAndType", + new String[]{"id", p.toString()}, + value)); + } catch (InvalidIndex ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitMethodref(CONSTANT_Methodref_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.class_index), c.class_index); + value = value.concat(" " + + visit(cfpool.get(c.name_and_type_index), + c.name_and_type_index)); + slist.set(p, value); + xpool.add(new Element("CONSTANT_Methodref", + new String[]{"id", p.toString()}, + value)); + + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitMethodHandle(CONSTANT_MethodHandle_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = c.reference_kind.name(); + value = value.concat(" " + + visit(cfpool.get(c.reference_index), c.reference_index)); + slist.set(p, value); + xpool.add(new Element("CONSTANT_MethodHandle", + new String[]{"id", p.toString()}, + value)); + + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitMethodType(CONSTANT_MethodType_info c, Integer p) { + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.descriptor_index), c.descriptor_index); + slist.set(p, value); + xpool.add(new Element("CONSTANT_MethodType", + new String[]{"id", p.toString()}, + value)); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitString(CONSTANT_String_info c, Integer p) { + try { + + String value = slist.get(p); + if (value == null) { + value = c.getString(); + slist.set(p, value); + xpool.add(new Element("CONSTANT_String", + new String[]{"id", p.toString()}, + value)); + } + return value; + } catch (ConstantPoolException ex) { + throw new RuntimeException("Fatal error", ex); } } - private String cpName(int id) { - if (id >= 0 && id < cpName.length) { - return cpName[id]; - } else { - return "[CP#" + Integer.toHexString(id) + "]"; + @Override + public String visitUtf8(CONSTANT_Utf8_info cnstnt, Integer p) { + String value = slist.get(p); + if (value == null) { + value = cnstnt.value; + slist.set(p, value); + xpool.add(new Element("CONSTANT_Utf8", + new String[]{"id", p.toString()}, + value)); } - } + return value; - private long u8() throws IOException { - return ((long) u4() << 32) + (((long) u4() << 32) >>> 32); - } - - private int u4() throws IOException { - return (u2() << 16) + u2(); - } - - private int u2() throws IOException { - return (u1() << 8) + u1(); - } - - private int u1() throws IOException { - int x = in.read(); - if (x < 0) { - paddingSize++; - return 0; // error recovery - } - fileSize++; - assert (x == (x & 0xFF)); - return x; } } +class AttributeVisitor implements Attribute.Visitor { + final ClassFile cf; + final ClassReader x; + final AnnotationsElementVisitor aev; + final InstructionVisitor iv; + + public AttributeVisitor(ClassReader x, ClassFile cf) { + this.x = x; + this.cf = cf; + iv = new InstructionVisitor(x, cf); + aev = new AnnotationsElementVisitor(x, cf); + } + + public void visit(Attribute a, Element parent) { + a.accept(this, parent); + } + + @Override + public Element visitBootstrapMethods(BootstrapMethods_attribute bm, Element p) { + Element e = new Element(x.getCpString(bm.attribute_name_index)); + for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsm : bm.bootstrap_method_specifiers) { + Element be = new Element("BootstrapMethodSpecifier"); + be.setAttr("ref", x.getCpString(bsm.bootstrap_method_ref)); + if (bsm.bootstrap_arguments.length > 0) { + Element bme = new Element("MethodArguments"); + for (int index : bsm.bootstrap_arguments) { + bme.add(x.getCpString(index)); + } + bme.trimToSize(); + be.add(bme); + } + be.trimToSize(); + e.add(be); + } + e.trimToSize(); + if (!x.keepOrder) { + e.sort(); + } + p.add(e); + return null; + } + + @Override + public Element visitDefault(DefaultAttribute da, Element p) { + Element e = new Element(x.getCpString(da.attribute_name_index)); + StringBuilder sb = new StringBuilder(); + for (byte x : da.info) { + sb.append("0x").append(Integer.toHexString(x)).append(" "); + } + e.setAttr("bytes", sb.toString().trim()); + e.trimToSize(); + p.add(e); + return null; + } + + @Override + public Element visitAnnotationDefault(AnnotationDefault_attribute ad, Element p) { + Element e = new Element(x.getCpString(ad.attribute_name_index)); + e.setAttr("tag", "" + ad.default_value.tag); + Element child = aev.visit(ad.default_value, e); + if (child != null) { + e.add(child); + } + e.trimToSize(); + p.add(e); + return null; + } + + @Override + public Element visitCharacterRangeTable(CharacterRangeTable_attribute crt, + Element p) { + Element e = new Element(x.getCpString(crt.attribute_name_index)); + for (CharacterRangeTable_attribute.Entry ce : crt.character_range_table) { + e.setAttr("start_pc", "" + ce.start_pc); + e.setAttr("end_pc", "" + ce.end_pc); + e.setAttr("range_start", "" + ce.character_range_start); + e.setAttr("range_end", "" + ce.character_range_end); + e.setAttr("flags", x.flagString(ce.flags, "Method")); + } + e.trimToSize(); + p.add(e); + return null; + } + + private Element instructions(Element code, Code_attribute c) { + Element ielement = new Element("Instructions"); + for (Instruction ins : c.getInstructions()) { + ielement.add(iv.visit(ins)); + } + ielement.trimToSize(); + return ielement; + } + + @Override + public Element visitCode(Code_attribute c, Element p) { + Element e = null; + + e = new Element(x.getCpString(c.attribute_name_index), + "stack", "" + c.max_stack, + "local", "" + c.max_locals); + + e.add(instructions(e, c)); + + for (Code_attribute.Exception_data edata : c.exception_table) { + e.add(new Element("Handler", + "start", "" + edata.start_pc, + "end", "" + edata.end_pc, + "catch", "" + edata.handler_pc, + "class", x.getCpString(edata.catch_type))); + + } + this.x.readAttributesFor(cf, c.attributes, e); + e.trimToSize(); + p.add(e); + return null; + } + + @Override + public Element visitCompilationID(CompilationID_attribute cid, Element p) { + Element e = new Element(x.getCpString(cid.attribute_name_index), + x.getCpString(cid.compilationID_index)); + p.add(e); + return null; + } + + @Override + public Element visitConstantValue(ConstantValue_attribute cv, Element p) { + Element e = new Element(x.getCpString(cv.attribute_name_index)); + e.add(x.getCpString(cv.constantvalue_index)); + p.add(e); + return null; + } + + @Override + public Element visitDeprecated(Deprecated_attribute d, Element p) { + Element e = new Element(x.getCpString(d.attribute_name_index)); + p.add(e); + return null; + } + + @Override + public Element visitEnclosingMethod(EnclosingMethod_attribute em, Element p) { + Element e = new Element(x.getCpString(em.attribute_name_index)); + e.setAttr("class", x.getCpString(em.class_index)); + e.setAttr("desc", x.getCpString(em.method_index)); + e.trimToSize(); + p.add(e); + return null; + } + + @Override + public Element visitExceptions(Exceptions_attribute e, Element p) { + Element ee = new Element(x.getCpString(e.attribute_name_index)); + for (int idx : e.exception_index_table) { + Element n = new Element("Item"); + n.setAttr("class", x.getCpString(idx)); + ee.add(n); + } + ee.trimToSize(); + p.add(ee); + return null; + } + + @Override + public Element visitInnerClasses(InnerClasses_attribute ic, Element p) { + for (Info info : ic.classes) { + Element e = new Element(x.getCpString(ic.attribute_name_index)); + e.setAttr("class", x.getCpString(info.inner_class_info_index)); + e.setAttr("outer", x.getCpString(info.outer_class_info_index)); + e.setAttr("name", x.getCpString(info.inner_name_index)); + e.setAttr("flags", x.flagString(info.inner_class_access_flags, + "InnerClass")); + e.trimToSize(); + p.add(e); + } + return null; + } + + @Override + public Element visitLineNumberTable(LineNumberTable_attribute lnt, Element p) { + String name = x.getCpString(lnt.attribute_name_index); + for (LineNumberTable_attribute.Entry e : lnt.line_number_table) { + Element l = new Element(name); + l.setAttr("bci", "" + e.start_pc); + l.setAttr("line", "" + e.line_number); + l.trimToSize(); + p.add(l); + } + return null; // already added to parent + } + + @Override + public Element visitLocalVariableTable(LocalVariableTable_attribute lvt, + Element p) { + String name = x.getCpString(lvt.attribute_name_index); + for (LocalVariableTable_attribute.Entry e : lvt.local_variable_table) { + Element l = new Element(name); + l.setAttr("bci", "" + e.start_pc); + l.setAttr("span", "" + e.length); + l.setAttr("name", x.getCpString(e.name_index)); + l.setAttr("type", x.getCpString(e.descriptor_index)); + l.setAttr("slot", "" + e.index); + l.trimToSize(); + p.add(l); + } + return null; // already added to parent + } + + @Override + public Element visitLocalVariableTypeTable(LocalVariableTypeTable_attribute lvtt, + Element p) { + String name = x.getCpString(lvtt.attribute_name_index); + for (LocalVariableTypeTable_attribute.Entry e : lvtt.local_variable_table) { + Element l = new Element(name); + l.setAttr("bci", "" + e.start_pc); + l.setAttr("span", "" + e.length); + l.setAttr("name", x.getCpString(e.name_index)); + l.setAttr("type", x.getCpString(e.signature_index)); + l.setAttr("slot", "" + e.index); + l.trimToSize(); + p.add(l); + } + return null; // already added to parent + } + + private void parseAnnotations(Annotation[] ra, Element p) { + for (Annotation anno : ra) { + Element ea = new Element("Member"); + ea.setAttr("name", "" + x.getCpString(anno.type_index)); + for (Annotation.element_value_pair evp : anno.element_value_pairs) { + Element evpe = new Element("Element"); + evpe.setAttr("tag", "" + evp.value.tag); + evpe.setAttr("value", x.getCpString(evp.element_name_index)); + Element child = aev.visit(evp.value, evpe); + if (child != null) { + evpe.add(child); + } + ea.add(evpe); + } + ea.trimToSize(); + p.add(ea); + } + } + + @Override + public Element visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute rva, + Element p) { + Element e = new Element(x.getCpString(rva.attribute_name_index)); + parseAnnotations(rva.annotations, e); + e.trimToSize(); + p.add(e); + return null; + } + + @Override + public Element visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute ria, + Element p) { + Element e = new Element(x.getCpString(ria.attribute_name_index)); + parseAnnotations(ria.annotations, e); + e.trimToSize(); + p.add(e); + return null; + } + + @Override + public Element visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute rvpa, + Element p) { + Element e = new Element(x.getCpString(rvpa.attribute_name_index)); + for (Annotation[] pa : rvpa.parameter_annotations) { + parseAnnotations(pa, e); + } + p.add(e); + return null; + } + + @Override + public Element visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute ripa, + Element p) { + Element e = new Element(x.getCpString(ripa.attribute_name_index)); + for (Annotation[] pa : ripa.parameter_annotations) { + parseAnnotations(pa, e); + } + p.add(e); + return null; + } + + @Override + public Element visitSignature(Signature_attribute s, Element p) { + String aname = x.getCpString(s.attribute_name_index); + String sname = x.getCpString(s.signature_index); + Element se = new Element(aname); + se.add(sname); + se.trimToSize(); + p.add(se); + return null; + } + + @Override + public Element visitSourceDebugExtension(SourceDebugExtension_attribute sde, + Element p) { + String aname = x.getCpString(sde.attribute_name_index); + Element se = new Element(aname); + se.setAttr("val", sde.getValue()); + se.trimToSize(); + p.add(se); + return null; + } + + @Override + public Element visitSourceFile(SourceFile_attribute sf, Element p) { + String aname = x.getCpString(sf.attribute_name_index); + String sname = x.getCpString(sf.sourcefile_index); + Element se = new Element(aname); + se.add(sname); + se.trimToSize(); + p.add(se); + return null; + } + + @Override + public Element visitSourceID(SourceID_attribute sid, Element p) { + Element e = new Element(x.getCpString(sid.attribute_name_index)); + e.add(x.getCpString(sid.sourceID_index)); + e.trimToSize(); + p.add(e); + return null; + } + + @Override + public Element visitStackMap(StackMap_attribute sm, Element p) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Element visitStackMapTable(StackMapTable_attribute smt, Element p) { + Element stackmap = new Element(x.getCpString(smt.attribute_name_index)); + for (StackMapTable_attribute.stack_map_frame f : smt.entries) { + StackMapVisitor smv = new StackMapVisitor(x, cf, stackmap); + stackmap.add(smv.visit(f)); + } + stackmap.trimToSize(); + p.add(stackmap); + return null; + } + + @Override + public Element visitSynthetic(Synthetic_attribute s, Element p) { + Element e = new Element(x.getCpString(s.attribute_name_index)); + e.trimToSize(); + p.add(e); + return null; + } +} + +class StackMapVisitor implements StackMapTable_attribute.stack_map_frame.Visitor { + + final ClassFile cf; + final ClassReader x; + final Element parent; + + public StackMapVisitor(ClassReader x, ClassFile cf, Element parent) { + this.x = x; + this.cf = cf; + this.parent = parent; + } + + public Element visit(StackMapTable_attribute.stack_map_frame frame) { + return frame.accept(this, null); + } + + @Override + public Element visit_same_frame(same_frame sm_frm, Void p) { + Element e = new Element("SameFrame"); + e.setAttr("tag", "" + sm_frm.frame_type); + return e; + } + + @Override + public Element visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame s, Void p) { + Element e = new Element("SameLocals1StackItemFrame"); + e.setAttr("tag", "" + s.frame_type); + e.addAll(getVerificationTypeInfo("Stack", s.stack)); + e.trimToSize(); + return e; + } + + @Override + public Element visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended s, Void p) { + Element e = new Element("SameLocals1StackItemFrameExtended"); + e.setAttr("tag", "" + s.frame_type); + e.addAll(getVerificationTypeInfo("Stack", s.stack)); + e.trimToSize(); + return e; + } + + @Override + public Element visit_chop_frame(chop_frame c, Void p) { + Element e = new Element("Chop" + (251 - c.frame_type)); + e.setAttr("tag", "" + c.frame_type); + e.setAttr("offset", "" + c.offset_delta); + return e; + } + + @Override + public Element visit_same_frame_extended(same_frame_extended s, Void p) { + Element e = new Element("SameFrameExtended"); + e.setAttr("tag", "" + s.frame_type); + e.setAttr("offset", "" + s.offset_delta); + return e; + } + + @Override + public Element visit_append_frame(append_frame a, Void p) { + Element e = new Element("AppendFrame" + (a.frame_type - 251)); + e.setAttr("tag", "" + a.frame_type); + e.addAll(getVerificationTypeInfo("Local", a.locals)); + e.trimToSize(); + return e; + } + + @Override + public Element visit_full_frame(full_frame fl_frm, Void p) { + Element e = new Element("FullFrame"); + e.setAttr("tag", "" + fl_frm.frame_type); + e.addAll(getVerificationTypeInfo("Local", fl_frm.locals)); + e.trimToSize(); + return e; + } + + private Element getVerificationTypeInfo(String kind, + StackMapTable_attribute.verification_type_info velems[]) { + Element container = new Element(velems.length); + for (StackMapTable_attribute.verification_type_info v : velems) { + Element ve = null; + int offset = 0; + int index = 0; + switch (v.tag) { + case StackMapTable_attribute.verification_type_info.ITEM_Top: + ve = new Element("ITEM_Top"); + break; + case StackMapTable_attribute.verification_type_info.ITEM_Integer: + ve = new Element("ITEM_Integer"); + break; + case StackMapTable_attribute.verification_type_info.ITEM_Float: + ve = new Element("ITEM_Float"); + break; + case StackMapTable_attribute.verification_type_info.ITEM_Long: + ve = new Element("ITEM_Long"); + break; + case StackMapTable_attribute.verification_type_info.ITEM_Double: + ve = new Element("ITEM_Double"); + break; + case StackMapTable_attribute.verification_type_info.ITEM_Null: + ve = new Element("ITEM_Null"); + break; + case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized: + ve = new Element("ITEM_Uninitialized"); + offset = ((StackMapTable_attribute.Uninitialized_variable_info) v).offset; + ve.setAttr("offset", "" + offset); + break; + case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis: + ve = new Element("ITEM_UnitializedtThis"); + break; + case StackMapTable_attribute.verification_type_info.ITEM_Object: + ve = new Element("ITEM_Object"); + index = ((StackMapTable_attribute.Object_variable_info) v).cpool_index; + ve.setAttr("class", x.getCpString(index)); + break; + default: + ve = new Element("Unknown"); + } + Element kindE = new Element(kind); + kindE.setAttr("tag", "" + v.tag); + container.add(kindE); + kindE.add(ve); + } + container.trimToSize(); + return container; + } +} + +class InstructionVisitor implements Instruction.KindVisitor { + + final ClassReader x; + final ClassFile cf; + + public InstructionVisitor(ClassReader x, ClassFile cf) { + this.x = x; + this.cf = cf; + } + + public Element visit(Instruction i) { + Element ie = i.accept(this, null); + ie.trimToSize(); + return ie; + } + + @Override + public Element visitNoOperands(Instruction i, Void p) { + Opcode o = i.getOpcode(); + Element e = new Element(i.getMnemonic()); + if (o.opcode > 0xab && o.opcode <= 0xb1) { + e.setAttr("pc", "" + i.getPC()); + } + return e; + } + + @Override + public Element visitArrayType(Instruction i, TypeKind tk, Void p) { + Element ie = new Element(i.getMnemonic()); + ie.setAttr("num", "" + tk.value); + ie.setAttr("val", tk.name); + return ie; + } + + @Override + public Element visitBranch(Instruction i, int i1, Void p) { + Element ie = new Element(i.getMnemonic()); + ie.setAttr("lab", "" + (i.getPC() + i1)); + return ie; + } + + @Override + public Element visitConstantPoolRef(Instruction i, int i1, Void p) { + Element ie = new Element(i.getMnemonic()); + ie.setAttr("ref", x.getCpString(i1)); + return ie; + } + + @Override + public Element visitConstantPoolRefAndValue(Instruction i, int i1, int i2, Void p) { + // workaround for a potential bug in classfile + Element ie = new Element(i.getMnemonic()); + if (i.getOpcode().equals(Opcode.IINC_W)) { + ie.setAttr("loc", "" + i1); + ie.setAttr("num", "" + i2); + } else { + ie.setAttr("ref", x.getCpString(i1)); + ie.setAttr("val", "" + i2); + } + return ie; + } + + @Override + public Element visitLocal(Instruction i, int i1, Void p) { + Element ie = new Element(i.getMnemonic()); + ie.setAttr("loc", "" + i1); + return ie; + } + + @Override + public Element visitLocalAndValue(Instruction i, int i1, int i2, Void p) { + Element ie = new Element(i.getMnemonic()); + ie.setAttr("loc", "" + i1); + ie.setAttr("num", "" + i2); + return ie; + } + + @Override + public Element visitLookupSwitch(Instruction i, int i1, int i2, int[] ints, + int[] ints1, Void p) { + Element ie = new Element(i.getMnemonic()); + int pc = i.getPC(); + ie.setAttr("lab", "" + (pc + i1)); + for (int k = 0 ; k < i2 ; k++) { + Element c = new Element("Case"); + c.setAttr("num", "" + (ints[k])); + c.setAttr("lab", "" + (pc + ints1[k])); + c.trimToSize(); + ie.add(c); + } + return ie; + } + + @Override + public Element visitTableSwitch(Instruction i, int i1, int i2, int i3, + int[] ints, Void p) { + Element ie = new Element(i.getMnemonic()); + int pc = i.getPC(); + ie.setAttr("lab", "" + (pc + i1)); + for (int k : ints) { + Element c = new Element("Case"); + c.setAttr("num", "" + (k + i2)); + c.setAttr("lab", "" + (pc + k)); + c.trimToSize(); + ie.add(c); + } + return ie; + } + + @Override + public Element visitValue(Instruction i, int i1, Void p) { + Element ie = new Element(i.getMnemonic()); + ie.setAttr("num", "" + i1); + return ie; + } + + @Override + public Element visitUnknown(Instruction i, Void p) { + Element e = new Element(i.getMnemonic()); + e.setAttr("pc", "" + i.getPC()); + e.setAttr("opcode", "" + i.getOpcode().opcode); + return e; + } +} + +class AnnotationsElementVisitor implements Annotation.element_value.Visitor { + final ClassReader x; + final ClassFile cf; + + public AnnotationsElementVisitor(ClassReader x, ClassFile cf) { + this.x = x; + this.cf = cf; + } + + public Element visit(Annotation.element_value v, Element p) { + return v.accept(this, p); + } + + @Override + public Element visitPrimitive(Primitive_element_value e, Element p) { + Element el = new Element("String"); + el.setAttr("val", x.getCpString(e.const_value_index)); + el.trimToSize(); + return el; + } + + @Override + public Element visitEnum(Enum_element_value e, Element p) { + Element el = new Element("Enum"); + el.setAttr("name", x.getCpString(e.const_name_index)); + el.setAttr("type", x.getCpString(e.type_name_index)); + el.trimToSize(); + return el; + } + + @Override + public Element visitClass(Class_element_value c, Element p) { + Element el = new Element("Class"); + el.setAttr("name", x.getCpString(c.class_info_index)); + el.trimToSize(); + return el; + } + + @Override + public Element visitAnnotation(Annotation_element_value a, Element p) { + Element el = new Element("Annotation"); + Annotation anno = a.annotation_value; + for (Annotation.element_value_pair evp : anno.element_value_pairs) { + Element child = visit(evp.value, el); + if (child != null) { + el.add(child); + } + } + el.trimToSize(); + return el; + } + + @Override + public Element visitArray(Array_element_value a, Element p) { + Element el = new Element("Array"); + for (Annotation.element_value v : a.values) { + Element child = visit(v, el); + if (child != null) { + el.add(child); + } + } + el.trimToSize(); + return el; + } +} diff --git a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassSyntax.java b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassSyntax.java deleted file mode 100644 index d34ecbad004..00000000000 --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassSyntax.java +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (c) 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*- -import xmlkit.XMLKit.*; - -import java.util.*; -import java.security.MessageDigest; -import java.nio.ByteBuffer; -import xmlkit.XMLKit.Element; -/* - * @author jrose - */ -public abstract class ClassSyntax { - - public interface GetCPIndex { - - int getCPIndex(int tag, String name); // cp finder - } - public static final int CONSTANT_Utf8 = 1, - CONSTANT_Integer = 3, - CONSTANT_Float = 4, - CONSTANT_Long = 5, - CONSTANT_Double = 6, - CONSTANT_Class = 7, - CONSTANT_String = 8, - CONSTANT_Fieldref = 9, - CONSTANT_Methodref = 10, - CONSTANT_InterfaceMethodref = 11, - CONSTANT_NameAndType = 12; - private static final String[] cpTagName = { - /* 0: */null, - /* 1: */ "Utf8", - /* 2: */ null, - /* 3: */ "Integer", - /* 4: */ "Float", - /* 5: */ "Long", - /* 6: */ "Double", - /* 7: */ "Class", - /* 8: */ "String", - /* 9: */ "Fieldref", - /* 10: */ "Methodref", - /* 11: */ "InterfaceMethodref", - /* 12: */ "NameAndType", - null - }; - private static final Set cpTagNames; - - static { - Set set = new HashSet(Arrays.asList(cpTagName)); - set.remove(null); - cpTagNames = Collections.unmodifiableSet(set); - } - public static final int ITEM_Top = 0, // replicates by [1..4,1..4] - ITEM_Integer = 1, // (ditto) - ITEM_Float = 2, - ITEM_Double = 3, - ITEM_Long = 4, - ITEM_Null = 5, - ITEM_UninitializedThis = 6, - ITEM_Object = 7, - ITEM_Uninitialized = 8, - ITEM_ReturnAddress = 9, - ITEM_LIMIT = 10; - private static final String[] itemTagName = { - "Top", - "Integer", - "Float", - "Double", - "Long", - "Null", - "UninitializedThis", - "Object", - "Uninitialized", - "ReturnAddress",}; - private static final Set itemTagNames; - - static { - Set set = new HashSet(Arrays.asList(itemTagName)); - set.remove(null); - itemTagNames = Collections.unmodifiableSet(set); - } - protected static final HashMap attrTypesBacking; - protected static final Map attrTypesInit; - - static { - HashMap at = new HashMap(); - - //at.put("*.Deprecated", ""); - //at.put("*.Synthetic", ""); - ////at.put("Field.ConstantValue", "KQH"); - //at.put("Class.SourceFile", "RUH"); - at.put("Method.Bridge", ""); - at.put("Method.Varargs", ""); - at.put("Class.Enum", ""); - at.put("*.Signature", "RSH"); - //at.put("*.Deprecated", ""); - //at.put("*.Synthetic", ""); - at.put("Field.ConstantValue", "KQH"); - at.put("Class.SourceFile", "RUH"); - at.put("Class.InnerClasses", "NH[RCHRCHRUHFH]"); - at.put("Code.LineNumberTable", "NH[PHH]"); - at.put("Code.LocalVariableTable", "NH[PHHRUHRSHH]"); - at.put("Code.LocalVariableTypeTable", "NH[PHHRUHRSHH]"); - at.put("Method.Exceptions", "NH[RCH]"); - at.put("Method.Code", "..."); - at.put("Code.StackMapTable", "..."); - //at.put("Code.StkMapX", "..."); - if (true) { - at.put("Code.StackMapTable", - "[NH[(1)]]" - + "[TB" - + "(64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79" - + ",80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95" - + ",96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111" - + ",112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127" - + ")[(4)]" - + "(247)[H(4)]" - + "(248)[H]" - + "(249)[H]" - + "(250)[H]" - + "(251)[H]" - + "(252)[H(4)]" - + "(253)[H(4)(4)]" - + "(254)[H(4)(4)(4)]" - + "(255)[H(2)(3)]" - + "()[]]" - + "[NH[(4)]]" - + "[NH[(4)]]" - + "[TB" - + ("(0)[]" - + "(1)[](2)[](3)[](4)[]" - + "(5)[](6)[]" - + "(7)[RCH]" - + "(8)[PH]" - + "()[]]")); - } - - at.put("Class.EnclosingMethod", "RCHRDH");//RDNH - - // Layouts of metadata attrs: - String vpf = "["; - String ipf = "["; - String apf = "["; - String mdanno2 = "" - + "RSHNH[RUH(3)]]" - + ("[TB" - + "(\\B,\\C,\\I,\\S,\\Z)[KIH]" - + "(\\D)[KDH]" - + "(\\F)[KFH]" - + "(\\J)[KJH]" - + "(\\c)[RSH]" - + "(\\e)[RSHRUH]" - + "(\\s)[RUH]" - + "(\\@)[(2)]" - + "(\\[)[NH[(3)]]" - + "()[]" - + "]"); - String visanno = "[NH[(2)]][(1)]" + vpf + mdanno2; - String invanno = "[NH[(2)]][(1)]" + ipf + mdanno2; - String vparamanno = "" - + "[NB[(1)]][NH[(2)]]" - + apf + mdanno2; - String iparamanno = "" - + "[NB[(1)]][NH[(2)]]" - + apf + mdanno2; - String mdannodef = "[(3)][(1)]" + apf + mdanno2; - String[] mdplaces = {"Class", "Field", "Method"}; - for (String place : mdplaces) { - at.put(place + ".RuntimeVisibleAnnotations", visanno); - at.put(place + ".RuntimeInvisibleAnnotations", invanno); - } - at.put("Method.RuntimeVisibleParameterAnnotations", vparamanno); - at.put("Method.RuntimeInvisibleParameterAnnotations", iparamanno); - at.put("Method.AnnotationDefault", mdannodef); - - attrTypesBacking = at; - attrTypesInit = Collections.unmodifiableMap(at); - } - - ; - private static final String[] jcovAttrTypes = { - "Code.CoverageTable=NH[PHHII]", - "Code.CharacterRangeTable=NH[PHPOHIIH]", - "Class.SourceID=RUH", - "Class.CompilationID=RUH" - }; - protected static final String[][] modifierNames = { - {"public"}, - {"private"}, - {"protected"}, - {"static"}, - {"final"}, - {"synchronized"}, - {null, "volatile", "bridge"}, - {null, "transient", "varargs"}, - {null, null, "native"}, - {"interface"}, - {"abstract"}, - {"strictfp"}, - {"synthetic"}, - {"annotation"}, - {"enum"},}; - protected static final String EIGHT_BIT_CHAR_ENCODING = "ISO8859_1"; - protected static final String UTF8_ENCODING = "UTF8"; - // What XML tags are used by this syntax, apart from attributes? - protected static final Set nonAttrTags; - - static { - HashSet tagSet = new HashSet(); - Collections.addAll(tagSet, new String[]{ - "ConstantPool",// the CP - "Class", // the class - "Interface", // implemented interfaces - "Method", // methods - "Field", // fields - "Handler", // exception handler pseudo-attribute - "Attribute", // unparsed attribute - "Bytes", // bytecodes - "Instructions" // bytecodes, parsed - }); - nonAttrTags = Collections.unmodifiableSet(tagSet); - } - - // Accessors. - public static Set nonAttrTags() { - return nonAttrTags; - } - - public static String cpTagName(int t) { - t &= 0xFF; - String ts = null; - if (t < cpTagName.length) { - ts = cpTagName[t]; - } - if (ts != null) { - return ts; - } - return ("UnknownTag" + (int) t).intern(); - } - - public static int cpTagValue(String name) { - for (int t = 0; t < cpTagName.length; t++) { - if (name.equals(cpTagName[t])) { - return t; - } - } - return 0; - } - - public static String itemTagName(int t) { - t &= 0xFF; - String ts = null; - if (t < itemTagName.length) { - ts = itemTagName[t]; - } - if (ts != null) { - return ts; - } - return ("UnknownItem" + (int) t).intern(); - } - - public static int itemTagValue(String name) { - for (int t = 0; t < itemTagName.length; t++) { - if (name.equals(itemTagName[t])) { - return t; - } - } - return -1; - } - - public void addJcovAttrTypes() { - addAttrTypes(jcovAttrTypes); - } - // Public methods for declaring attribute types. - protected Map attrTypes = attrTypesInit; - - public void addAttrType(String opt) { - int eqpos = opt.indexOf('='); - addAttrType(opt.substring(0, eqpos), opt.substring(eqpos + 1)); - } - - public void addAttrTypes(String[] opts) { - for (String opt : opts) { - addAttrType(opt); - } - } - - private void checkAttr(String attr) { - if (!attr.startsWith("Class.") - && !attr.startsWith("Field.") - && !attr.startsWith("Method.") - && !attr.startsWith("Code.") - && !attr.startsWith("*.")) { - throw new IllegalArgumentException("attr name must start with 'Class.', etc."); - } - String uattr = attr.substring(attr.indexOf('.') + 1); - if (nonAttrTags.contains(uattr)) { - throw new IllegalArgumentException("attr name must not be one of " + nonAttrTags); - } - } - - private void checkAttrs(Map at) { - for (String attr : at.keySet()) { - checkAttr(attr); - } - } - - private void modAttrs() { - if (attrTypes == attrTypesInit) { - // Make modifiable. - attrTypes = new HashMap(attrTypesBacking); - } - } - - public void addAttrType(String attr, String fmt) { - checkAttr(attr); - modAttrs(); - attrTypes.put(attr, fmt); - } - - public void addAttrTypes(Map at) { - checkAttrs(at); - modAttrs(); - attrTypes.putAll(at); - } - - public Map getAttrTypes() { - if (attrTypes == attrTypesInit) { - return attrTypes; - } - return Collections.unmodifiableMap(attrTypes); - } - - public void setAttrTypes(Map at) { - checkAttrs(at); - modAttrs(); - attrTypes.keySet().retainAll(at.keySet()); - attrTypes.putAll(at); - } - - // attr format helpers - protected static boolean matchTag(int tagValue, String caseStr) { - //System.out.println("matchTag "+tagValue+" in "+caseStr); - for (int pos = 0, max = caseStr.length(), comma; - pos < max; - pos = comma + 1) { - int caseValue; - if (caseStr.charAt(pos) == '\\') { - caseValue = caseStr.charAt(pos + 1); - comma = pos + 2; - assert (comma == max || caseStr.charAt(comma) == ','); - } else { - comma = caseStr.indexOf(',', pos); - if (comma < 0) { - comma = max; - } - caseValue = Integer.parseInt(caseStr.substring(pos, comma)); - } - if (tagValue == caseValue) { - return true; - } - } - return false; - } - - protected static String[] getBodies(String type) { - ArrayList bodies = new ArrayList(); - for (int i = 0; i < type.length();) { - String body = getBody(type, i); - bodies.add(body); - i += body.length() + 2; // skip body and brackets - } - return bodies.toArray(new String[bodies.size()]); - } - - protected static String getBody(String type, int i) { - assert (type.charAt(i) == '['); - int next = ++i; // skip bracket - for (int depth = 1; depth > 0; next++) { - switch (type.charAt(next)) { - case '[': - depth++; - break; - case ']': - depth--; - break; - case '(': - next = type.indexOf(')', next); - break; - case '<': - next = type.indexOf('>', next); - break; - } - assert (next > 0); - } - --next; // get before bracket - assert (type.charAt(next) == ']'); - return type.substring(i, next); - } - - public Element makeCPDigest(int length) { - MessageDigest md; - try { - md = MessageDigest.getInstance("MD5"); - } catch (java.security.NoSuchAlgorithmException ee) { - throw new Error(ee); - } - int items = 0; - for (Element e : cpool.elements()) { - if (items == length) { - break; - } - if (cpTagNames.contains(e.getName())) { - items += 1; - md.update((byte) cpTagValue(e.getName())); - try { - md.update(e.getText().toString().getBytes(UTF8_ENCODING)); - } catch (java.io.UnsupportedEncodingException ee) { - throw new Error(ee); - } - } - } - ByteBuffer bb = ByteBuffer.wrap(md.digest()); - String l0 = Long.toHexString(bb.getLong(0)); - String l1 = Long.toHexString(bb.getLong(8)); - while (l0.length() < 16) { - l0 = "0" + l0; - } - while (l1.length() < 16) { - l1 = "0" + l1; - } - return new Element("Digest", - "length", "" + items, - "bytes", l0 + l1); - } - - public Element getCPDigest(int length) { - if (length == -1) { - length = cpool.countAll(XMLKit.elementFilter(cpTagNames)); - } - for (Element md : cpool.findAllElements("Digest").elements()) { - if (md.getAttrLong("length") == length) { - return md; - } - } - Element md = makeCPDigest(length); - cpool.add(md); - return md; - } - - public Element getCPDigest() { - return getCPDigest(-1); - } - - public boolean checkCPDigest(Element md) { - return md.equals(getCPDigest((int) md.getAttrLong("length"))); - } - - public static int computeInterfaceNum(String intMethRef) { - intMethRef = intMethRef.substring(1 + intMethRef.lastIndexOf(' ')); - if (!intMethRef.startsWith("(")) { - return -1; - } - int signum = 1; // start with one for "this" - scanSig: - for (int i = 1; i < intMethRef.length(); i++) { - char ch = intMethRef.charAt(i); - signum++; - switch (ch) { - case ')': - --signum; - break scanSig; - case 'L': - i = intMethRef.indexOf(';', i); - break; - case '[': - while (ch == '[') { - ch = intMethRef.charAt(++i); - } - if (ch == 'L') { - i = intMethRef.indexOf(';', i); - } - break; - } - } - int num = (signum << 8) | 0; - //System.out.println("computeInterfaceNum "+intMethRef+" => "+num); - return num; - } - // Protected state for representing the class file. - protected Element cfile; // - protected Element cpool; // - protected Element klass; // - protected Element currentMember; // varies during scans - protected Element currentCode; // varies during scans -} diff --git a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassWriter.java b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassWriter.java deleted file mode 100644 index 037de37e540..00000000000 --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassWriter.java +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Copyright (c) 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*- - -import java.util.*; -import java.lang.reflect.*; -import java.io.*; -import xmlkit.XMLKit.Element; -/* - * @author jrose - */ -public class ClassWriter extends ClassSyntax implements ClassSyntax.GetCPIndex { - - private static final CommandLineParser CLP = new CommandLineParser("" - + "-source: +> = \n" - + "-dest: +> = \n" - + "-encoding: +> = \n" - + "-parseBytes $ \n" - + "- *? \n" - + "\n"); - - public static void main(String[] ava) throws IOException { - ArrayList av = new ArrayList(Arrays.asList(ava)); - HashMap props = new HashMap(); - props.put("-encoding:", "UTF8"); // default - CLP.parse(av, props); - File source = asFile(props.get("-source:")); - File dest = asFile(props.get("-dest:")); - String encoding = props.get("-encoding:"); - boolean parseBytes = props.containsKey("-parseBytes"); - boolean destMade = false; - - for (String a : av) { - File f; - File inf = new File(source, a); - System.out.println("Reading " + inf); - Element e; - if (inf.getName().endsWith(".class")) { - ClassReader cr = new ClassReader(); - cr.parseBytes = parseBytes; - e = cr.readFrom(inf); - f = new File(a); - } else if (inf.getName().endsWith(".xml")) { - InputStream in = new FileInputStream(inf); - Reader inw = ClassReader.makeReader(in, encoding); - e = XMLKit.readFrom(inw); - e.findAllInTree(XMLKit.and(XMLKit.elementFilter(nonAttrTags()), - XMLKit.methodFilter(Element.method("trimText")))); - //System.out.println(e); - inw.close(); - f = new File(a.substring(0, a.length() - ".xml".length()) + ".class"); - } else { - System.out.println("Warning: unknown input " + a); - continue; - } - // Now write it: - if (!destMade) { - destMade = true; - if (dest == null) { - dest = File.createTempFile("TestOut", ".dir", new File(".")); - dest.delete(); - System.out.println("Writing results to " + dest); - } - if (!(dest.isDirectory() || dest.mkdir())) { - throw new RuntimeException("Cannot create " + dest); - } - } - File outf = new File(dest, f.isAbsolute() ? f.getName() : f.getPath()); - outf.getParentFile().mkdirs(); - new ClassWriter(e).writeTo(outf); - } - } - - private static File asFile(String str) { - return (str == null) ? null : new File(str); - } - - public void writeTo(File file) throws IOException { - OutputStream out = null; - try { - out = new BufferedOutputStream(new FileOutputStream(file)); - writeTo(out); - } finally { - if (out != null) { - out.close(); - } - } - } - protected String[] callables; // varies - protected int cpoolSize = 0; - protected HashMap attrTypesByTag; - protected OutputStream out; - protected HashMap cpMap = new HashMap(); - protected ArrayList attrBufs = new ArrayList(); - - private void setupAttrTypes() { - attrTypesByTag = new HashMap(); - for (String key : attrTypes.keySet()) { - String pfx = key.substring(0, key.indexOf('.') + 1); - String val = attrTypes.get(key); - int pos = val.indexOf('<'); - if (pos >= 0) { - String tag = val.substring(pos + 1, val.indexOf('>', pos)); - attrTypesByTag.put(pfx + tag, key); - } - } - //System.out.println("attrTypesByTag: "+attrTypesByTag); - } - - protected ByteArrayOutputStream getAttrBuf() { - int nab = attrBufs.size(); - if (nab == 0) { - return new ByteArrayOutputStream(1024); - } - ByteArrayOutputStream ab = attrBufs.get(nab - 1); - attrBufs.remove(nab - 1); - return ab; - } - - protected void putAttrBuf(ByteArrayOutputStream ab) { - ab.reset(); - attrBufs.add(ab); - } - - public ClassWriter(Element root) { - this(root, null); - } - - public ClassWriter(Element root, ClassSyntax cr) { - if (cr != null) { - attrTypes = cr.attrTypes; - } - setupAttrTypes(); - if (root.getName() == "ClassFile") { - cfile = root; - cpool = root.findElement("ConstantPool"); - klass = root.findElement("Class"); - } else if (root.getName() == "Class") { - cfile = new Element("ClassFile", - new String[]{ - "magic", String.valueOf(0xCAFEBABE), - "minver", "0", "majver", "46",}); - cpool = new Element("ConstantPool"); - klass = root; - } else { - throw new IllegalArgumentException("bad element type " + root.getName()); - } - if (cpool == null) { - cpool = new Element("ConstantPool"); - } - - int cpLen = 1 + cpool.size(); - for (Element c : cpool.elements()) { - int id = (int) c.getAttrLong("id"); - int tag = cpTagValue(c.getName()); - setCPIndex(tag, c.getText().toString(), id); - switch (tag) { - case CONSTANT_Long: - case CONSTANT_Double: - cpLen += 1; - } - } - cpoolSize = cpLen; - } - - public int findCPIndex(int tag, String name) { - if (name == null) { - return 0; - } - int[] ids = cpMap.get(name.toString()); - return (ids == null) ? 0 : ids[tag]; - } - - public int getCPIndex(int tag, String name) { - //System.out.println("getCPIndex "+cpTagName(tag)+" "+name); - if (name == null) { - return 0; - } - int id = findCPIndex(tag, name); - if (id == 0) { - id = cpoolSize; - cpoolSize += 1; - setCPIndex(tag, name, id); - cpool.add(new Element(cpTagName(tag), - new String[]{"id", "" + id}, - new Object[]{name})); - int pos; - switch (tag) { - case CONSTANT_Long: - case CONSTANT_Double: - cpoolSize += 1; - break; - case CONSTANT_Class: - case CONSTANT_String: - getCPIndex(CONSTANT_Utf8, name); - break; - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - pos = name.indexOf(' '); - getCPIndex(CONSTANT_Class, name.substring(0, pos)); - getCPIndex(CONSTANT_NameAndType, name.substring(pos + 1)); - break; - case CONSTANT_NameAndType: - pos = name.indexOf(' '); - getCPIndex(CONSTANT_Utf8, name.substring(0, pos)); - getCPIndex(CONSTANT_Utf8, name.substring(pos + 1)); - break; - } - } - return id; - } - - public void setCPIndex(int tag, String name, int id) { - //System.out.println("setCPIndex id="+id+" tag="+tag+" name="+name); - int[] ids = cpMap.get(name); - if (ids == null) { - cpMap.put(name, ids = new int[13]); - } - if (ids[tag] != 0 && ids[tag] != id) { - System.out.println("Warning: Duplicate CP entries for " + ids[tag] + " and " + id); - } - //assert(ids[tag] == 0 || ids[tag] == id); - ids[tag] = id; - } - - public int parseFlags(String flagString) { - int flags = 0; - int i = -1; - for (String[] names : modifierNames) { - ++i; - for (String name : names) { - if (name == null) { - continue; - } - int pos = flagString.indexOf(name); - if (pos >= 0) { - flags |= (1 << i); - } - } - } - return flags; - } - - public void writeTo(OutputStream realOut) throws IOException { - OutputStream headOut = realOut; - ByteArrayOutputStream tailOut = new ByteArrayOutputStream(); - - // write the body of the class file first - this.out = tailOut; - writeClass(); - - // write the file header last - this.out = headOut; - u4((int) cfile.getAttrLong("magic")); - u2((int) cfile.getAttrLong("minver")); - u2((int) cfile.getAttrLong("majver")); - writeCP(); - - // recopy the file tail - this.out = null; - tailOut.writeTo(realOut); - } - - void writeClass() throws IOException { - int flags = parseFlags(klass.getAttr("flags")); - flags ^= Modifier.SYNCHRONIZED; - u2(flags); - cpRef(CONSTANT_Class, klass.getAttr("name")); - cpRef(CONSTANT_Class, klass.getAttr("super")); - Element interfaces = klass.findAllElements("Interface"); - u2(interfaces.size()); - for (Element e : interfaces.elements()) { - cpRef(CONSTANT_Class, e.getAttr("name")); - } - for (int isMethod = 0; isMethod <= 1; isMethod++) { - Element members = klass.findAllElements(isMethod != 0 ? "Method" : "Field"); - u2(members.size()); - for (Element m : members.elements()) { - writeMember(m, isMethod != 0); - } - } - writeAttributesFor(klass); - } - - private void writeMember(Element member, boolean isMethod) throws IOException { - //System.out.println("writeMember "+member); - u2(parseFlags(member.getAttr("flags"))); - cpRef(CONSTANT_Utf8, member.getAttr("name")); - cpRef(CONSTANT_Utf8, member.getAttr("type")); - writeAttributesFor(member); - } - - protected void writeAttributesFor(Element x) throws IOException { - LinkedHashSet attrNames = new LinkedHashSet(); - for (Element e : x.elements()) { - attrNames.add(e.getName()); // uniquifying - } - attrNames.removeAll(nonAttrTags()); - u2(attrNames.size()); - if (attrNames.isEmpty()) { - return; - } - Element prevCurrent; - if (x.getName() == "Code") { - prevCurrent = currentCode; - currentCode = x; - } else { - prevCurrent = currentMember; - currentMember = x; - } - OutputStream realOut = this.out; - for (String utag : attrNames) { - String qtag = x.getName() + "." + utag; - String wtag = "*." + utag; - String key = attrTypesByTag.get(qtag); - if (key == null) { - key = attrTypesByTag.get(wtag); - } - String type = attrTypes.get(key); - //System.out.println("tag "+qtag+" => key "+key+"; type "+type); - Element attrs = x.findAllElements(utag); - ByteArrayOutputStream attrBuf = getAttrBuf(); - if (type == null) { - if (attrs.size() != 1 || !attrs.get(0).equals(new Element(utag))) { - System.out.println("Warning: No attribute type description: " + qtag); - } - key = wtag; - } else { - try { - this.out = attrBuf; - // unparse according to type desc. - if (type.equals("...")) { - writeCode((Element) attrs.get(0)); // assume only 1 - } else if (type.equals("...")) { - writeStackMap(attrs, false); - } else if (type.equals("...")) { - writeStackMap(attrs, true); - } else if (type.startsWith("[")) { - writeAttributeRecursive(attrs, type); - } else { - writeAttribute(attrs, type); - } - } finally { - //System.out.println("Attr Bytes = \""+attrBuf.toString(EIGHT_BIT_CHAR_ENCODING).replace('"', (char)('"'|0x80))+"\""); - this.out = realOut; - } - } - cpRef(CONSTANT_Utf8, key.substring(key.indexOf('.') + 1)); - u4(attrBuf.size()); - attrBuf.writeTo(out); - putAttrBuf(attrBuf); - } - if (x.getName() == "Code") { - currentCode = prevCurrent; - } else { - currentMember = prevCurrent; - } - } - - private void writeAttributeRecursive(Element aval, String type) throws IOException { - assert (callables == null); - callables = getBodies(type); - writeAttribute(aval, callables[0]); - callables = null; - } - - private void writeAttribute(Element aval, String type) throws IOException { - //System.out.println("writeAttribute "+aval+" using "+type); - String nextAttrName = null; - boolean afterElemHead = false; - for (int len = type.length(), next, i = 0; i < len; i = next) { - int value; - char intKind; - int tag; - int sigChar; - String attrValue; - switch (type.charAt(i)) { - case '<': - assert (nextAttrName == null); - next = type.indexOf('>', i); - String form = type.substring(i + 1, next++); - if (form.indexOf('=') < 0) { - // elem_placement = '<' elemname '>' - if (aval.isAnonymous()) { - assert (aval.size() == 1); - aval = (Element) aval.get(0); - } - assert (aval.getName().equals(form)) : aval + " // " + form; - afterElemHead = true; - } else { - // attr_placement = '(' attrname '=' (value)? ')' - int eqPos = form.indexOf('='); - assert (eqPos >= 0); - nextAttrName = form.substring(0, eqPos).intern(); - if (eqPos != form.length() - 1) { - // value is implicit, not placed in file - nextAttrName = null; - } - afterElemHead = false; - } - continue; - case '(': - next = type.indexOf(')', ++i); - int callee = Integer.parseInt(type.substring(i, next++)); - writeAttribute(aval, callables[callee]); - continue; - case 'N': // replication = 'N' int '[' type ... ']' - { - assert (nextAttrName == null); - afterElemHead = false; - char countType = type.charAt(i + 1); - next = i + 2; - String type1 = getBody(type, next); - Element elems = aval; - if (type1.startsWith("<")) { - // Select only matching members of aval. - String elemName = type1.substring(1, type1.indexOf('>')); - elems = aval.findAllElements(elemName); - } - putInt(elems.size(), countType); - next += type1.length() + 2; // skip body and brackets - for (Element elem : elems.elements()) { - writeAttribute(elem, type1); - } - } - continue; - case 'T': // union = 'T' any_int union_case* '(' ')' '[' body ']' - // write the value - value = (int) aval.getAttrLong("tag"); - assert (aval.getAttr("tag") != null) : aval; - intKind = type.charAt(++i); - if (intKind == 'S') { - intKind = type.charAt(++i); - } - putInt(value, intKind); - nextAttrName = null; - afterElemHead = false; - ++i; // skip the int type char - // union_case = '(' ('-')? digit+ ')' '[' body ']' - for (boolean foundCase = false;;) { - assert (type.charAt(i) == '('); - next = type.indexOf(')', ++i); - assert (next >= i); - String caseStr = type.substring(i, next++); - String type1 = getBody(type, next); - next += type1.length() + 2; // skip body and brackets - boolean lastCase = (caseStr.length() == 0); - if (!foundCase - && (lastCase || matchTag(value, caseStr))) { - foundCase = true; - // Execute this body. - writeAttribute(aval, type1); - } - if (lastCase) { - break; - } - } - continue; - case 'B': - case 'H': - case 'I': // int = oneof "BHI" - value = (int) aval.getAttrLong(nextAttrName); - intKind = type.charAt(i); - next = i + 1; - break; - case 'K': - sigChar = type.charAt(i + 1); - if (sigChar == 'Q') { - assert (currentMember.getName() == "Field"); - assert (aval.getName() == "ConstantValue"); - String sig = currentMember.getAttr("type"); - sigChar = sig.charAt(0); - switch (sigChar) { - case 'Z': - case 'B': - case 'C': - case 'S': - sigChar = 'I'; - break; - } - } - switch (sigChar) { - case 'I': - tag = CONSTANT_Integer; - break; - case 'J': - tag = CONSTANT_Long; - break; - case 'F': - tag = CONSTANT_Float; - break; - case 'D': - tag = CONSTANT_Double; - break; - case 'L': - tag = CONSTANT_String; - break; - default: - assert (false); - tag = 0; - } - assert (type.charAt(i + 2) == 'H'); // only H works for now - next = i + 3; - assert (afterElemHead || nextAttrName != null); - //System.out.println("get attr "+nextAttrName+" in "+aval); - if (nextAttrName != null) { - attrValue = aval.getAttr(nextAttrName); - assert (attrValue != null); - } else { - assert (aval.isText()) : aval; - attrValue = aval.getText().toString(); - } - value = getCPIndex(tag, attrValue); - intKind = 'H'; //type.charAt(i+2); - break; - case 'R': - sigChar = type.charAt(i + 1); - switch (sigChar) { - case 'C': - tag = CONSTANT_Class; - break; - case 'S': - tag = CONSTANT_Utf8; - break; - case 'D': - tag = CONSTANT_Class; - break; - case 'F': - tag = CONSTANT_Fieldref; - break; - case 'M': - tag = CONSTANT_Methodref; - break; - case 'I': - tag = CONSTANT_InterfaceMethodref; - break; - case 'U': - tag = CONSTANT_Utf8; - break; - //case 'Q': tag = CONSTANT_Class; break; - default: - assert (false); - tag = 0; - } - assert (type.charAt(i + 2) == 'H'); // only H works for now - next = i + 3; - assert (afterElemHead || nextAttrName != null); - //System.out.println("get attr "+nextAttrName+" in "+aval); - if (nextAttrName != null) { - attrValue = aval.getAttr(nextAttrName); - } else if (aval.hasText()) { - attrValue = aval.getText().toString(); - } else { - attrValue = null; - } - value = getCPIndex(tag, attrValue); - intKind = 'H'; //type.charAt(i+2); - break; - case 'P': // bci = 'P' int - case 'S': // signed_int = 'S' int - next = i + 2; - value = (int) aval.getAttrLong(nextAttrName); - intKind = type.charAt(i + 1); - break; - case 'F': - next = i + 2; - value = parseFlags(aval.getAttr(nextAttrName)); - intKind = type.charAt(i + 1); - break; - default: - throw new RuntimeException("bad attr format '" + type.charAt(i) + "': " + type); - } - // write the value - putInt(value, intKind); - nextAttrName = null; - afterElemHead = false; - } - assert (nextAttrName == null); - } - - private void putInt(int x, char ch) throws IOException { - switch (ch) { - case 'B': - u1(x); - break; - case 'H': - u2(x); - break; - case 'I': - u4(x); - break; - } - assert ("BHI".indexOf(ch) >= 0); - } - - private void writeCode(Element code) throws IOException { - //System.out.println("writeCode "+code); - //Element m = new Element(currentMember); m.remove(code); - //System.out.println(" in "+m); - int stack = (int) code.getAttrLong("stack"); - int local = (int) code.getAttrLong("local"); - Element bytes = code.findElement("Bytes"); - Element insns = code.findElement("Instructions"); - String bytecodes; - if (insns == null) { - bytecodes = bytes.getText().toString(); - } else { - bytecodes = InstructionSyntax.assemble(insns, this); - // Cache the assembled bytecodes: - bytes = new Element("Bytes", (String[]) null, bytecodes); - code.add(0, bytes); - } - u2(stack); - u2(local); - int length = bytecodes.length(); - u4(length); - for (int i = 0; i < length; i++) { - u1((byte) bytecodes.charAt(i)); - } - Element handlers = code.findAllElements("Handler"); - u2(handlers.size()); - for (Element handler : handlers.elements()) { - int start = (int) handler.getAttrLong("start"); - int end = (int) handler.getAttrLong("end"); - int catsh = (int) handler.getAttrLong("catch"); - u2(start); - u2(end); - u2(catsh); - cpRef(CONSTANT_Class, handler.getAttr("class")); - } - writeAttributesFor(code); - } - - protected void writeStackMap(Element attrs, boolean hasXOption) throws IOException { - Element bytes = currentCode.findElement("Bytes"); - assert (bytes != null && bytes.size() == 1); - int byteLength = ((String) bytes.get(0)).length(); - boolean uoffsetIsU4 = (byteLength >= (1 << 16)); - boolean ulocalvarIsU4 = currentCode.getAttrLong("local") >= (1 << 16); - boolean ustackIsU4 = currentCode.getAttrLong("stack") >= (1 << 16); - if (uoffsetIsU4) { - u4(attrs.size()); - } else { - u2(attrs.size()); - } - for (Element frame : attrs.elements()) { - int bci = (int) frame.getAttrLong("bci"); - if (uoffsetIsU4) { - u4(bci); - } else { - u2(bci); - } - if (hasXOption) { - u1((int) frame.getAttrLong("flags")); - } - // Scan local and stack types in this frame: - final int LOCALS = 0, STACK = 1; - for (int j = LOCALS; j <= STACK; j++) { - Element types = frame.findElement(j == LOCALS ? "Local" : "Stack"); - int typeSize = (types == null) ? 0 : types.size(); - if (j == LOCALS) { - if (ulocalvarIsU4) { - u4(typeSize); - } else { - u2(typeSize); - } - } else { // STACK - if (ustackIsU4) { - u4(typeSize); - } else { - u2(typeSize); - } - } - if (types == null) { - continue; - } - for (Element type : types.elements()) { - int tag = itemTagValue(type.getName()); - u1(tag); - switch (tag) { - case ITEM_Object: - cpRef(CONSTANT_Class, type.getAttr("class")); - break; - case ITEM_Uninitialized: - case ITEM_ReturnAddress: { - int offset = (int) type.getAttrLong("bci"); - if (uoffsetIsU4) { - u4(offset); - } else { - u2(offset); - } - } - break; - } - } - } - } - } - - public void writeCP() throws IOException { - int cpLen = cpoolSize; - u2(cpLen); - ByteArrayOutputStream buf = getAttrBuf(); - for (Element c : cpool.elements()) { - if (!c.isText()) { - System.out.println("## !isText " + c); - } - int id = (int) c.getAttrLong("id"); - int tag = cpTagValue(c.getName()); - String name = c.getText().toString(); - int pos; - u1(tag); - switch (tag) { - case CONSTANT_Utf8: { - int done = 0; - buf.reset(); - int nameLen = name.length(); - while (done < nameLen) { - int next = name.indexOf((char) 0, done); - if (next < 0) { - next = nameLen; - } - if (done < next) { - buf.write(name.substring(done, next).getBytes(UTF8_ENCODING)); - } - if (next < nameLen) { - buf.write(0300); - buf.write(0200); - next++; - } - done = next; - } - u2(buf.size()); - buf.writeTo(out); - } - break; - case CONSTANT_Integer: - u4(Integer.parseInt(name)); - break; - case CONSTANT_Float: - u4(Float.floatToIntBits(Float.parseFloat(name))); - break; - case CONSTANT_Long: - u8(Long.parseLong(name)); - //i += 1; // no need: extra cp slot is implicit - break; - case CONSTANT_Double: - u8(Double.doubleToLongBits(Double.parseDouble(name))); - //i += 1; // no need: extra cp slot is implicit - break; - case CONSTANT_Class: - case CONSTANT_String: - u2(getCPIndex(CONSTANT_Utf8, name)); - break; - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - pos = name.indexOf(' '); - u2(getCPIndex(CONSTANT_Class, name.substring(0, pos))); - u2(getCPIndex(CONSTANT_NameAndType, name.substring(pos + 1))); - break; - case CONSTANT_NameAndType: - pos = name.indexOf(' '); - u2(getCPIndex(CONSTANT_Utf8, name.substring(0, pos))); - u2(getCPIndex(CONSTANT_Utf8, name.substring(pos + 1))); - break; - } - } - putAttrBuf(buf); - } - - public void cpRef(int tag, String name) throws IOException { - u2(getCPIndex(tag, name)); - } - - public void u8(long x) throws IOException { - u4((int) (x >>> 32)); - u4((int) (x >>> 0)); - } - - public void u4(int x) throws IOException { - u2(x >>> 16); - u2(x >>> 0); - } - - public void u2(int x) throws IOException { - u1(x >>> 8); - u1(x >>> 0); - } - - public void u1(int x) throws IOException { - out.write(x & 0xFF); - } -} - diff --git a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/InstructionAssembler.java b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/InstructionAssembler.java deleted file mode 100644 index cbe34e6b960..00000000000 --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/InstructionAssembler.java +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright (c) 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*- - -import xmlkit.XMLKit.Element; -import java.util.HashMap; -/* - * @author jrose - */ -abstract class InstructionAssembler extends InstructionSyntax { - - InstructionAssembler() { - } - - public static String assemble(Element instructions, String pcAttrName, - ClassSyntax.GetCPIndex getCPI) { - int insCount = instructions.size(); - Element[] insElems = new Element[insCount]; - int[] elemToIndexMap; - int[] insLocs; - byte[] ops = new byte[insCount]; - int[] operands = new int[insCount]; - boolean[] isWide = new boolean[insCount]; - int[] branches; - int[] branchInsLocs; - HashMap labels = new HashMap(); - - final int WIDE = 0xc4; - final int GOTO = 0xa7; - final int GOTO_W = 0xc8; - final int GOTO_LEN = 3; - final int GOTO_W_LEN = 5; - assert ("wide".equals(bcNames[WIDE])); - assert ("goto".equals(bcNames[GOTO])); - assert ("goto_w".equals(bcNames[GOTO_W])); - assert (bcFormats[GOTO].length() == GOTO_LEN); - assert (bcFormats[GOTO_W].length() == GOTO_W_LEN); - - // Unpack instructions into temp. arrays, and find branches and labels. - { - elemToIndexMap = (pcAttrName != null) ? new int[insCount] : null; - int[] buffer = operands; - int id = 0; - int branchCount = 0; - for (int i = 0; i < insCount; i++) { - Element ins = (Element) instructions.get(i); - if (elemToIndexMap != null) { - elemToIndexMap[i] = (ins.getAttr(pcAttrName) != null ? id : -1); - } - String lab = ins.getAttr("pc"); - if (lab != null) { - labels.put(lab, String.valueOf(id)); - } - int op = opCode(ins.getName()); - if (op < 0) { - assert (ins.getAttr(pcAttrName) != null - || ins.getName().equals("label")); - continue; // delete PC holder element - } - if (op == WIDE) { //0xc4 - isWide[id] = true; // force wide format - continue; - } - if (bcFormats[op].indexOf('o') >= 0) { - buffer[branchCount++] = id; - } - if (bcFormats[op] == bcWideFormats[op]) { - isWide[id] = false; - } - insElems[id] = ins; - ops[id] = (byte) op; - id++; - } - insCount = id; // maybe we deleted some wide prefixes, etc. - branches = new int[branchCount + 1]; - System.arraycopy(buffer, 0, branches, 0, branchCount); - branches[branchCount] = -1; // sentinel - } - - // Compute instruction sizes. These sizes are final, - // except for branch instructions, which may need lengthening. - // Some instructions (ldc, bipush, iload, iinc) are automagically widened. - insLocs = new int[insCount + 1]; - int loc = 0; - for (int bn = 0, id = 0; id < insCount; id++) { - insLocs[id] = loc; - Element ins = insElems[id]; - int op = ops[id] & 0xFF; - String format = opFormat(op, isWide[id]); - // Make sure operands fit within the given format. - for (int j = 1, jlimit = format.length(); j < jlimit; j++) { - char fc = format.charAt(j); - int x = 0; - switch (fc) { - case 'l': - x = (int) ins.getAttrLong("loc"); - assert (x >= 0); - if (x > 0xFF && !isWide[id]) { - isWide[id] = true; - format = opFormat(op, isWide[id]); - } - assert (x <= 0xFFFF); - break; - case 'k': - char fc2 = format.charAt(Math.min(j + 1, format.length() - 1)); - x = getCPIndex(ins, fc2, getCPI); - if (x > 0xFF && j == jlimit - 1) { - assert (op == 0x12); //ldc - ops[id] = (byte) (op = 0x13); //ldc_w - format = opFormat(op); - } - assert (x <= 0xFFFF); - j++; // skip type-of-constant marker - break; - case 'x': - x = (int) ins.getAttrLong("num"); - assert (x >= 0 && x <= ((j == jlimit - 1) ? 0xFF : 0xFFFF)); - break; - case 's': - x = (int) ins.getAttrLong("num"); - if (x != (byte) x && j == jlimit - 1) { - switch (op) { - case 0x10: //bipush - ops[id] = (byte) (op = 0x11); //sipush - break; - case 0x84: //iinc - isWide[id] = true; - format = opFormat(op, isWide[id]); - break; - default: - assert (false); // cannot lengthen - } - } - // unsign the value now, to make later steps clearer - if (j == jlimit - 1) { - assert (x == (byte) x); - x = x & 0xFF; - } else { - assert (x == (short) x); - x = x & 0xFFFF; - } - break; - case 'o': - assert (branches[bn] == id); - bn++; - // make local copies of the branches, and fix up labels - insElems[id] = ins = new Element(ins); - String newLab = labels.get(ins.getAttr("lab")); - assert (newLab != null); - ins.setAttr("lab", newLab); - int prevCas = 0; - int k = 0; - for (Element cas : ins.elements()) { - assert (cas.getName().equals("Case")); - ins.set(k++, cas = new Element(cas)); - newLab = labels.get(cas.getAttr("lab")); - assert (newLab != null); - cas.setAttr("lab", newLab); - int thisCas = (int) cas.getAttrLong("num"); - assert (op == 0xab - || op == 0xaa && (k == 0 || thisCas == prevCas + 1)); - prevCas = thisCas; - } - break; - case 't': - // switch table is represented as Switch.Case sub-elements - break; - default: - assert (false); - } - operands[id] = x; // record operand (last if there are 2) - // skip redundant chars - while (j + 1 < jlimit && format.charAt(j + 1) == fc) { - ++j; - } - } - - switch (op) { - case 0xaa: //tableswitch - loc = switchBase(loc); - loc += 4 * (3 + ins.size()); - break; - case 0xab: //lookupswitch - loc = switchBase(loc); - loc += 4 * (2 + 2 * ins.size()); - break; - default: - if (isWide[id]) { - loc++; // 'wide' opcode prefix - } - loc += format.length(); - break; - } - } - insLocs[insCount] = loc; - - // compute branch offsets, and see if any branches need expansion - for (int maxTries = 9, tries = 0;; ++tries) { - boolean overflowing = false; - boolean[] branchExpansions = null; - for (int bn = 0; bn < branches.length - 1; bn++) { - int id = branches[bn]; - Element ins = insElems[id]; - int insSize = insLocs[id + 1] - insLocs[id]; - int origin = insLocs[id]; - int target = insLocs[(int) ins.getAttrLong("lab")]; - int offset = target - origin; - operands[id] = offset; - //System.out.println("branch id="+id+" len="+insSize+" to="+target+" offset="+offset); - assert (insSize == GOTO_LEN || insSize == GOTO_W_LEN || ins.getName().indexOf("switch") > 0); - boolean thisOverflow = (insSize == GOTO_LEN && (offset != (short) offset)); - if (thisOverflow && !overflowing) { - overflowing = true; - branchExpansions = new boolean[branches.length]; - } - if (thisOverflow || tries == maxTries - 1) { - // lengthen the branch - assert (!(thisOverflow && isWide[id])); - isWide[id] = true; - branchExpansions[bn] = true; - } - } - if (!overflowing) { - break; // done, usually on first try - } - assert (tries <= maxTries); - - // Walk over all instructions, expanding branches and updating locations. - int fixup = 0; - for (int bn = 0, id = 0; id < insCount; id++) { - insLocs[id] += fixup; - if (branches[bn] == id) { - int op = ops[id] & 0xFF; - int wop; - boolean invert; - if (branchExpansions[bn]) { - switch (op) { - case GOTO: //0xa7 - wop = GOTO_W; //0xc8 - invert = false; - break; - case 0xa8: //jsr - wop = 0xc9; //jsr_w - invert = false; - break; - default: - wop = invertBranchOp(op); - invert = true; - break; - } - assert (op != wop); - ops[id] = (byte) wop; - isWide[id] = invert; - if (invert) { - fixup += GOTO_W_LEN; //branch around a wide goto - } else { - fixup += (GOTO_W_LEN - GOTO_LEN); - } - // done expanding: ops and isWide reflect the decision - } - bn++; - } - } - insLocs[insCount] += fixup; - } - // we know the layout now - - // notify the caller of offsets, if requested - if (elemToIndexMap != null) { - for (int i = 0; i < elemToIndexMap.length; i++) { - int id = elemToIndexMap[i]; - if (id >= 0) { - Element ins = (Element) instructions.get(i); - ins.setAttr(pcAttrName, "" + insLocs[id]); - } - } - elemToIndexMap = null; // release the pointer - } - - // output the bytes - StringBuffer sbuf = new StringBuffer(insLocs[insCount]); - for (int bn = 0, id = 0; id < insCount; id++) { - //System.out.println("output id="+id+" loc="+insLocs[id]+" len="+(insLocs[id+1]-insLocs[id])+" #sbuf="+sbuf.length()); - assert (sbuf.length() == insLocs[id]); - Element ins; - int pc = insLocs[id]; - int nextpc = insLocs[id + 1]; - int op = ops[id] & 0xFF; - int opnd = operands[id]; - String format; - if (branches[bn] == id) { - bn++; - sbuf.append((char) op); - if (isWide[id]) { - // emit

FrameStateTest
Bug ID: 4157271

+

This test checks that when setState(Frame.ICONIFIED) is called before + setVisible(true) the Frame is shown in the proper iconified state. + The problem was that it did not honor the initial iconic state, but + instead was shown in the NORMAL state.

+

See the dialog box (usually in upper left corner) for instructions

+ + + + diff --git a/jdk/test/java/awt/Frame/FrameStateTest/FrameStateTest.java b/jdk/test/java/awt/Frame/FrameStateTest/FrameStateTest.java new file mode 100644 index 00000000000..33ea9b304ff --- /dev/null +++ b/jdk/test/java/awt/Frame/FrameStateTest/FrameStateTest.java @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + test + @bug 4157271 + @summary Checks that when a Frame is created it honors the state it + was set to. The bug was that if setState(Frame.ICONIFIED) was + called before setVisible(true) the Frame would be shown in NORMAL + state instead of ICONIFIED. + @author JTG East Team: area=awt.Frame + @run applet/manual=yesno FrameStateTest.html +*/ + +/** + * FrameStateTest.java + * + * summary: Checks that when setState(Frame.ICONIFIED) is called before + * setVisible(true) the Frame is shown in the proper iconified state. + * The problem was that it did not honor the initial iconic state, but + * instead was shown in the NORMAL state. + */ + +import java.awt.event.*; +import java.awt.*; +import java.lang.*; +import java.applet.Applet; + + +public class FrameStateTest extends Applet implements ActionListener, ItemListener{ + + Button btnCreate = new Button("Create Frame"); + Button btnDispose = new Button("Dispose Frame"); + CheckboxGroup cbgState = new CheckboxGroup(); + CheckboxGroup cbgResize = new CheckboxGroup(); + Checkbox cbIconState = new Checkbox("Frame state ICONIFIED",cbgState,false); + Checkbox cbNormState = new Checkbox("Frame state NORMAL",cbgState,true); + Checkbox cbNonResize = new Checkbox("Frame Nonresizable",cbgResize,false); + Checkbox cbResize = new Checkbox("Frame Resizable",cbgResize,true); + int iState = 0; + boolean bResize = true; + CreateFrame icontst; + + public void init() { + this.setLayout (new BorderLayout ()); + + String[] instructions = + { + "Steps to try to reproduce this problem:", + "When this test is run an Applet Viewer window will display. In the", + "Applet Viewer window select the different options for the Frame (i.e.", + "{Normal, Non-resizalbe}, {Normal, Resizable}, {Iconified, Resizable},", + "{Iconified, Non-resizalbe}). After chosing the Frame's state click the", + "Create Frame button. After the Frame (Frame State Test (Window2)) comes", + "up make sure the proper behavior occurred (Frame shown in proper state).", + "Click the Dispose button to close the Frame. Do the above steps for all", + "the different Frame state combinations available. If you observe the", + "proper behavior the test has passed, Press the Pass button. Otherwise", + "the test has failed, Press the Fail button.", + "Note: In Frame State Test (Window2) you can also chose the different", + "buttons to see different Frame behavior. An example of a problem that", + "has been seen, With the Frame nonresizable you can not iconify the Frame." + }; + Sysout.createDialogWithInstructions( instructions ); + + btnDispose.setEnabled(false); + add(btnCreate, BorderLayout.NORTH); + add(btnDispose, BorderLayout.SOUTH); + + Panel p = new Panel(new GridLayout(0,1)); + p.add(cbIconState); + p.add(cbResize); + add(p, BorderLayout.WEST); + + p = new Panel(new GridLayout(0,1)); + p.add(cbNormState); + p.add(cbNonResize); + add(p, BorderLayout.EAST); + + // Add Listeners + btnDispose.addActionListener(this); + btnCreate.addActionListener(this); + cbNormState.addItemListener(this); + cbResize.addItemListener(this); + cbIconState.addItemListener(this); + cbNonResize.addItemListener(this); + + resize(600, 200); + + }//End init() + + public void actionPerformed(ActionEvent evt) { + + + if (evt.getSource() == btnCreate) { + btnCreate.setEnabled(false); + btnDispose.setEnabled(true); + icontst = new CreateFrame(iState, bResize); + icontst.show(); + } else if (evt.getSource() == btnDispose) { + btnCreate.setEnabled(true); + btnDispose.setEnabled(false); + icontst.dispose(); + } + } + + public void itemStateChanged(ItemEvent evt) { + + if (cbNormState.getState()) iState = 0; + if (cbIconState.getState()) iState = 1; + if (cbResize.getState()) bResize = true; + if (cbNonResize.getState()) bResize = false; + + } + +}// class FrameStateTest + + +class CreateFrame extends Frame implements ActionListener , WindowListener { + + static int e=0; + static int u=0; + static int p=0; + static int i=0; + static int v=0; + + Button b1, b2, b3, b4, b5, b6, b7; + boolean resizable = true; + boolean iconic = false; + String name = "Frame State Test"; + + CreateFrame (int iFrameState, boolean bFrameResizable) { + + setTitle("Frame State Test (Window 2)"); + + if (iFrameState == 1) { + iconic = true; + } + + if (!(bFrameResizable)) { + resizable = false; + } + + System.out.println("CREATING FRAME - Initially "+ + ((iconic) ? "ICONIFIED" : "NORMAL (NON-ICONIFIED)") + " and " + + ((resizable) ? "RESIZABLE" : "NON-RESIZABLE") ); + + Sysout.println("CREATING FRAME - Initially "+ + ((iconic) ? "ICONIFIED" : "NORMAL (NON-ICONIFIED)") + " and " + + ((resizable) ? "RESIZABLE" : "NON-RESIZABLE") ); + + setLayout(new FlowLayout() ); + b1 = new Button("resizable"); + add(b1); + b2 = new Button("resize"); + add(b2); + b3 = new Button("iconify"); + add(b3); + b4 = new Button("iconify and restore"); + add(b4); + b5 = new Button("hide and show"); + add(b5); + b6 = new Button("hide, iconify and show"); + add(b6); + b7 = new Button("hide, iconify, show, and restore"); + add(b7); + b1.addActionListener(this); + b2.addActionListener(this); + b3.addActionListener(this); + b4.addActionListener(this); + b5.addActionListener(this); + b6.addActionListener(this); + b7.addActionListener(this); + addWindowListener(this); + + setBounds(100,2,200, 200); + setState(iconic ? Frame.ICONIFIED: Frame.NORMAL); + setResizable(resizable); + pack(); + setVisible(true); + + } + + public void actionPerformed ( ActionEvent e ) + { + if ( e.getSource() == b2 ) { + Rectangle r = this.getBounds(); + r.width += 10; + System.out.println(" - button pressed - setting bounds on Frame to: "+r); + setBounds(r); + validate(); + } else if ( e.getSource() == b1 ) { + resizable = !resizable; + System.out.println(" - button pressed - setting Resizable to: "+resizable); + ((Frame)(b1.getParent())).setResizable(resizable); + } else if ( e.getSource() == b3 ) { + System.out.println(" - button pressed - setting Iconic: "); + dolog(); + ((Frame)(b1.getParent())).setState(Frame.ICONIFIED); + dolog(); + } else if ( e.getSource() == b4 ) { + System.out.println(" - button pressed - setting Iconic: "); + dolog(); + ((Frame)(b1.getParent())).setState(Frame.ICONIFIED); + dolog(); + try { + Thread.sleep(1000); + } catch (Exception ex) {}; + System.out.println(" - now restoring: "); + ((Frame)(b1.getParent())).setState(Frame.NORMAL); + dolog(); + } else if ( e.getSource() == b5 ) { + System.out.println(" - button pressed - hiding : "); + dolog(); + ((Frame)(b1.getParent())).setVisible(false); + dolog(); + try { + Thread.sleep(1000); + } catch (Exception ex) {}; + System.out.println(" - now reshowing: "); + ((Frame)(b1.getParent())).setVisible(true); + dolog(); + } else if ( e.getSource() == b6 ) { + System.out.println(" - button pressed - hiding : "); + dolog(); + ((Frame)(b1.getParent())).setVisible(false); + dolog(); + try { + Thread.sleep(1000); + } catch (Exception ex) {}; + System.out.println(" - setting Iconic: "); + dolog(); + ((Frame)(b1.getParent())).setState(Frame.ICONIFIED); + try { + Thread.sleep(1000); + } catch (Exception ex) {}; + System.out.println(" - now reshowing: "); + ((Frame)(b1.getParent())).setVisible(true); + dolog(); + } else if ( e.getSource() == b7 ) { + System.out.println(" - button pressed - hiding : "); + dolog(); + ((Frame)(b1.getParent())).setVisible(false); + dolog(); + try { + Thread.sleep(1000); + } catch (Exception ex) {}; + System.out.println(" - setting Iconic: "); + dolog(); + ((Frame)(b1.getParent())).setState(Frame.ICONIFIED); + try { + Thread.sleep(1000); + } catch (Exception ex) {}; + System.out.println(" - now reshowing: "); + ((Frame)(b1.getParent())).setVisible(true); + dolog(); + try { + Thread.sleep(1000); + } catch (Exception ex) {}; + System.out.println(" - now restoring: "); + ((Frame)(b1.getParent())).setState(Frame.NORMAL); + dolog(); + } + } + + public void windowActivated(WindowEvent e) { + System.out.println(name + " Activated"); + dolog(); + } + public void windowClosed(WindowEvent e) { + System.out.println(name + " Closed"); + dolog(); + } + public void windowClosing(WindowEvent e) { + ((Window)(e.getSource())).dispose(); + System.out.println(name + " Closing"); + dolog(); + } + public void windowDeactivated(WindowEvent e) { + System.out.println(name + " Deactivated"); + dolog(); + } + public void windowDeiconified(WindowEvent e) { + System.out.println(name + " Deiconified"); + dolog(); + } + public void windowIconified(WindowEvent e) { + System.out.println(name + " Iconified"); + dolog(); + } + public void windowOpened(WindowEvent e) { + System.out.println(name + " Opened"); + dolog(); + } + + public void dolog() { + System.out.println(" getState returns: "+getState()); + } +} + +// }// class FrameStateTest + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + int scrollNone = TextArea.SCROLLBARS_NONE; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 10, maxStringLength, scrollBoth ); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + + }// TestDialog class From 2942df6c93022f75b060bb6ff030bdb4ff05affa Mon Sep 17 00:00:00 2001 From: Nicolas Carranza Date: Tue, 24 Apr 2012 19:12:47 +0400 Subject: [PATCH 21/51] 7163898: add isLoggable() check to doLog() Add the check and return immediately if it's false Reviewed-by: anthony, mchung, sla --- jdk/src/share/classes/sun/util/logging/PlatformLogger.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java index df88de5bdd4..30700a06b0b 100644 --- a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java +++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java @@ -516,6 +516,9 @@ public class PlatformLogger { } void doLog(int level, String msg, Object... params) { + if (!isLoggable(level)) { + return; + } // only pass String objects to the j.u.l.Logger which may // be created by untrusted code int len = (params != null) ? params.length : 0; From 14842a2b9755aa56f25ea6dd16ecbf1728c4b3b3 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 24 Apr 2012 20:39:40 +0400 Subject: [PATCH 22/51] 7131021: [macosx] Consider using system properties to pass arguments from the launcher to AWT/SplashScreen Document the environment variables and add tests Reviewed-by: ksrini --- jdk/src/macosx/bin/java_md_macosx.c | 46 ++++++++ .../tools/launcher/EnvironmentVariables.java | 79 +++++++++++++ jdk/test/tools/launcher/TestHelper.java | 14 ++- jdk/test/tools/launcher/TestSpecialArgs.java | 104 ++++++++++++++++++ 4 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 jdk/test/tools/launcher/EnvironmentVariables.java create mode 100644 jdk/test/tools/launcher/TestSpecialArgs.java diff --git a/jdk/src/macosx/bin/java_md_macosx.c b/jdk/src/macosx/bin/java_md_macosx.c index 14ae5318e33..4fba1ede4b5 100644 --- a/jdk/src/macosx/bin/java_md_macosx.c +++ b/jdk/src/macosx/bin/java_md_macosx.c @@ -906,11 +906,41 @@ SetXDockArgForAWT(const char *arg) { char envVar[80]; if (strstr(arg, "-Xdock:name=") == arg) { + /* + * The APP_NAME_ environment variable is used to pass + * an application name as specified with the -Xdock:name command + * line option from Java launcher code to the AWT code in order + * to assign this name to the app's dock tile on the Mac. + * The _ part is added to avoid collisions with child processes. + * + * WARNING: This environment variable is an implementation detail and + * isn't meant for use outside of the core platform. The mechanism for + * passing this information from Java launcher to other modules may + * change drastically between update release, and it may even be + * removed or replaced with another mechanism. + * + * NOTE: It is used by SWT, and JavaFX. + */ snprintf(envVar, sizeof(envVar), "APP_NAME_%d", getpid()); setenv(envVar, (arg + 12), 1); } if (strstr(arg, "-Xdock:icon=") == arg) { + /* + * The APP_ICON_ environment variable is used to pass + * an application icon as specified with the -Xdock:icon command + * line option from Java launcher code to the AWT code in order + * to assign this icon to the app's dock tile on the Mac. + * The _ part is added to avoid collisions with child processes. + * + * WARNING: This environment variable is an implementation detail and + * isn't meant for use outside of the core platform. The mechanism for + * passing this information from Java launcher to other modules may + * change drastically between update release, and it may even be + * removed or replaced with another mechanism. + * + * NOTE: It is used by SWT, and JavaFX. + */ snprintf(envVar, sizeof(envVar), "APP_ICON_%d", getpid()); setenv(envVar, (arg + 12), 1); } @@ -931,6 +961,22 @@ SetMainClassForAWT(JNIEnv *env, jclass mainClass) { NULL_CHECK(mainClassName = (*env)->GetStringUTFChars(env, mainClassString, NULL)); char envVar[80]; + /* + * The JAVA_MAIN_CLASS_ environment variable is used to pass + * the name of a Java class whose main() method is invoked by + * the Java launcher code to start the application, to the AWT code + * in order to assign the name to the Apple menu bar when the app + * is active on the Mac. + * The _ part is added to avoid collisions with child processes. + * + * WARNING: This environment variable is an implementation detail and + * isn't meant for use outside of the core platform. The mechanism for + * passing this information from Java launcher to other modules may + * change drastically between update release, and it may even be + * removed or replaced with another mechanism. + * + * NOTE: It is used by SWT, and JavaFX. + */ snprintf(envVar, sizeof(envVar), "JAVA_MAIN_CLASS_%d", getpid()); setenv(envVar, mainClassName, 1); diff --git a/jdk/test/tools/launcher/EnvironmentVariables.java b/jdk/test/tools/launcher/EnvironmentVariables.java new file mode 100644 index 00000000000..06ae701a6c2 --- /dev/null +++ b/jdk/test/tools/launcher/EnvironmentVariables.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012, 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. + */ + +/* + * see TestSpecialArgs.java + * bug 7131021 + * summary Checks for environment variables set by the launcher + * author anthony.petrov@oracle.com: area=launcher + */ + +public class EnvironmentVariables { + public static void main(String[] args) { + if (args.length != 2) { + throw new RuntimeException("ERROR: two command line arguments expected"); + } + + String name = args[0]; + String expect = args[1]; + String key = null; + + if (!name.endsWith("*")) { + key = name; + } else { + name = name.split("\\*")[0]; + + for (String s : System.getenv().keySet()) { + if (s.startsWith(name)) { + if (key == null) { + key = s; + } else { + System.err.println("WARNING: more variables match: " + s); + } + } + } + + if (key == null) { + throw new RuntimeException("ERROR: unable to find a match for: " + name); + } + } + + System.err.println("Will check the variable named: '" + key + + "' expecting the value: '" + expect + "'"); + + if (!System.getenv().containsKey(key)) { + throw new RuntimeException("ERROR: the variable '" + key + + "' is not present in the environment"); + } + + if (!expect.equals(System.getenv().get(key))) { + throw new RuntimeException("ERROR: expected: '" + expect + + "', got: '" + System.getenv().get(key) + "'"); + } + for (String x : args) { + System.err.print(x + " "); + } + System.err.println("-----> Passed!"); + } +} + diff --git a/jdk/test/tools/launcher/TestHelper.java b/jdk/test/tools/launcher/TestHelper.java index 445efcec3a6..1fdfb431e42 100644 --- a/jdk/test/tools/launcher/TestHelper.java +++ b/jdk/test/tools/launcher/TestHelper.java @@ -21,6 +21,7 @@ * questions. */ +import java.util.Set; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; @@ -316,19 +317,28 @@ public class TestHelper { } static TestResult doExec(String...cmds) { - return doExec(null, cmds); + return doExec(null, null, cmds); } + static TestResult doExec(Map envToSet, String...cmds) { + return doExec(envToSet, null, cmds); + } /* * A method which executes a java cmd and returns the results in a container */ - static TestResult doExec(Map envToSet, String...cmds) { + static TestResult doExec(Map envToSet, + Set envToRemove, String...cmds) { String cmdStr = ""; for (String x : cmds) { cmdStr = cmdStr.concat(x + " "); } ProcessBuilder pb = new ProcessBuilder(cmds); Map env = pb.environment(); + if (envToRemove != null) { + for (String key : envToRemove) { + env.remove(key); + } + } if (envToSet != null) { env.putAll(envToSet); } diff --git a/jdk/test/tools/launcher/TestSpecialArgs.java b/jdk/test/tools/launcher/TestSpecialArgs.java new file mode 100644 index 00000000000..344869bfbae --- /dev/null +++ b/jdk/test/tools/launcher/TestSpecialArgs.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7124089 7131021 + * @summary Checks for MacOSX specific flags are accepted or rejected, and + * MacOSX platforms specific environment is consistent. + * @compile -XDignore.symbol.file TestSpecialArgs.java EnvironmentVariables.java + * @run main TestSpecialArgs + */ +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class TestSpecialArgs extends TestHelper { + + public static void main(String... args) { + final Map envMap = new HashMap<>(); + envMap.put("_JAVA_LAUNCHER_DEBUG", "true"); + + TestResult tr = doExec(envMap, javaCmd, "-XstartOnFirstThread", "-version"); + if (isMacOSX) { + if (!tr.contains("In same thread")) { + System.out.println(tr); + throw new RuntimeException("Error: not running in the same thread ?"); + } + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Error: arg was rejected ????"); + } + } else { + if (tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Error: argument was accepted ????"); + } + } + + tr = doExec(javaCmd, "-Xdock:/tmp/not-available", "-version"); + if (isMacOSX) { + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Error: arg was rejected ????"); + } + } else { + if (tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Error: argument was accepted ????"); + } + } + // MacOSX specific tests ensue...... + if (!isMacOSX) + return; + Set envToRemove = new HashSet<>(); + Map map = System.getenv(); + for (String s : map.keySet()) { + if (s.startsWith("JAVA_MAIN_CLASS_") + || s.startsWith("APP_NAME_") + || s.startsWith("APP_ICON_")) { + envToRemove.add(s); + } + } + runTest(envToRemove, javaCmd, "-cp", TEST_CLASSES_DIR.getAbsolutePath(), + "EnvironmentVariables", "JAVA_MAIN_CLASS_*", + "EnvironmentVariables"); + + runTest(envToRemove, javaCmd, "-cp", TEST_CLASSES_DIR.getAbsolutePath(), + "-Xdock:name=TestAppName", "EnvironmentVariables", + "APP_NAME_*", "TestAppName"); + + runTest(envToRemove, javaCmd, "-cp", TEST_CLASSES_DIR.getAbsolutePath(), + "-Xdock:icon=TestAppIcon", "EnvironmentVariables", + "APP_ICON_*", "TestAppIcon"); + } + + static void runTest(Set envToRemove, String... args) { + TestResult tr = doExec(null, envToRemove, args); + if (!tr.isOK()) { + System.err.println(tr.toString()); + throw new RuntimeException("Test Fails"); + } + } +} From cb9507190eea09030d265fcb939d3146e83823d6 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Tue, 24 Apr 2012 10:37:01 -0700 Subject: [PATCH 23/51] 7151434: java -jar -XX crashes java launcher Reviewed-by: mchung, darcy --- jdk/src/share/bin/java.c | 7 ++++ jdk/test/tools/launcher/Arrrghs.java | 9 ++++- jdk/test/tools/launcher/TestHelper.java | 53 +++++++++++++++---------- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c index 313325817e0..3e7ff04c446 100644 --- a/jdk/src/share/bin/java.c +++ b/jdk/src/share/bin/java.c @@ -695,6 +695,13 @@ SetClassPath(const char *s) char *def; const char *orig = s; static const char format[] = "-Djava.class.path=%s"; + /* + * usually we should not get a null pointer, but there are cases where + * we might just get one, in which case we simply ignore it, and let the + * caller deal with it + */ + if (s == NULL) + return; s = JLI_WildcardExpandClasspath(s); def = JLI_MemAlloc(sizeof(format) - 2 /* strlen("%s") */ diff --git a/jdk/test/tools/launcher/Arrrghs.java b/jdk/test/tools/launcher/Arrrghs.java index 6306e2c2f87..e551bdf3cf2 100644 --- a/jdk/test/tools/launcher/Arrrghs.java +++ b/jdk/test/tools/launcher/Arrrghs.java @@ -24,7 +24,7 @@ /** * @test * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938 - * 6894719 6968053 + * 6894719 6968053 7151314 * @summary Argument parsing validation. * @compile -XDignore.symbol.file Arrrghs.java * @run main Arrrghs @@ -237,6 +237,13 @@ public class Arrrghs extends TestHelper { tr.checkNegative(); tr.isNotZeroOutput(); System.out.println(tr); + + // 7151314, test for non-negative exit value for an incorrectly formed + // command line, '% java -jar -W', note the bogus -W + tr = doExec(javaCmd, "-jar", "-W"); + tr.checkNegative(); + tr.contains("Unrecognized option: -W"); + System.out.println(tr); } /* diff --git a/jdk/test/tools/launcher/TestHelper.java b/jdk/test/tools/launcher/TestHelper.java index e0e50c92466..8fd7ffe0800 100644 --- a/jdk/test/tools/launcher/TestHelper.java +++ b/jdk/test/tools/launcher/TestHelper.java @@ -21,6 +21,8 @@ * questions. */ +import java.io.StringWriter; +import java.io.PrintWriter; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; @@ -87,6 +89,7 @@ public class TestHelper { static final String EXE_FILE_EXT = ".exe"; static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG"; static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC"; + static final String TEST_PREFIX = "###TestError###: "; static int testExitValue = 0; @@ -376,7 +379,8 @@ public class TestHelper { * of use methods to check the test results. */ static class TestResult { - StringBuilder status; + PrintWriter status; + StringWriter sw; int exitValue; List testOutput; Map env; @@ -384,27 +388,33 @@ public class TestHelper { public TestResult(String str, int rv, List oList, Map env, Throwable t) { - status = new StringBuilder("Executed command: " + str + "\n"); + sw = new StringWriter(); + status = new PrintWriter(sw); + status.println("Executed command: " + str + "\n"); exitValue = rv; testOutput = oList; this.env = env; this.t = t; } - void appendStatus(String x) { - status = status.append(" " + x + "\n"); + void appendError(String x) { + status.println(TEST_PREFIX + x); + } + + void indentStatus(String x) { + status.println(" " + x); } void checkNegative() { if (exitValue == 0) { - appendStatus("Error: test must not return 0 exit value"); + appendError("test must not return 0 exit value"); testExitValue++; } } void checkPositive() { if (exitValue != 0) { - appendStatus("Error: test did not return 0 exit value"); + appendError("test did not return 0 exit value"); testExitValue++; } } @@ -415,7 +425,7 @@ public class TestHelper { boolean isZeroOutput() { if (!testOutput.isEmpty()) { - appendStatus("Error: No message from cmd please"); + appendError("No message from cmd please"); testExitValue++; return false; } @@ -424,7 +434,7 @@ public class TestHelper { boolean isNotZeroOutput() { if (testOutput.isEmpty()) { - appendStatus("Error: Missing message"); + appendError("Missing message"); testExitValue++; return false; } @@ -433,22 +443,25 @@ public class TestHelper { @Override public String toString() { - status.append("++++Begin Test Info++++\n"); - status.append("++++Test Environment++++\n"); + status.println("++++Begin Test Info++++"); + status.println("++++Test Environment++++"); for (String x : env.keySet()) { - status.append(x).append("=").append(env.get(x)).append("\n"); + indentStatus(x + "=" + env.get(x)); } - status.append("++++Test Output++++\n"); + status.println("++++Test Output++++"); for (String x : testOutput) { - appendStatus(x); + indentStatus(x); } - status.append("++++Test Stack Trace++++\n"); - status.append(t.toString()); + status.println("++++Test Stack Trace++++"); + status.println(t.toString()); for (StackTraceElement e : t.getStackTrace()) { - status.append(e.toString()); + indentStatus(e.toString()); } - status.append("++++End of Test Info++++\n"); - return status.toString(); + status.println("++++End of Test Info++++"); + status.flush(); + String out = sw.toString(); + status.close(); + return out; } boolean contains(String str) { @@ -457,7 +470,7 @@ public class TestHelper { return true; } } - appendStatus("Error: string <" + str + "> not found"); + appendError("string <" + str + "> not found"); testExitValue++; return false; } @@ -468,7 +481,7 @@ public class TestHelper { return true; } } - appendStatus("Error: string <" + stringToMatch + "> not found"); + appendError("string <" + stringToMatch + "> not found"); testExitValue++; return false; } From 59a75697e30b5b22459e41ea6a9e2b0c5521cb7a Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Tue, 24 Apr 2012 13:29:04 -0700 Subject: [PATCH 24/51] 7157659: [macosx] Landscape Printing orientation doesn't work Reviewed-by: bae, prr --- jdk/src/macosx/native/sun/awt/PrinterView.m | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/jdk/src/macosx/native/sun/awt/PrinterView.m b/jdk/src/macosx/native/sun/awt/PrinterView.m index 84ddd0b4983..b7134090c73 100644 --- a/jdk/src/macosx/native/sun/awt/PrinterView.m +++ b/jdk/src/macosx/native/sun/awt/PrinterView.m @@ -27,6 +27,7 @@ #import "java_awt_print_Pageable.h" #import "java_awt_print_Printable.h" +#import "java_awt_print_PageFormat.h" #import @@ -35,6 +36,7 @@ static JNF_CLASS_CACHE(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob"); +static JNF_CLASS_CACHE(sjc_PageFormat, "java/awt/print/PageFormat"); @implementation PrinterView @@ -152,6 +154,7 @@ static JNF_CLASS_CACHE(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob"); static JNF_MEMBER_CACHE(jm_getPageformatPrintablePeekgraphics, sjc_CPrinterJob, "getPageformatPrintablePeekgraphics", "(I)[Ljava/lang/Object;"); static JNF_MEMBER_CACHE(jm_printAndGetPageFormatArea, sjc_CPrinterJob, "printAndGetPageFormatArea", "(Ljava/awt/print/Printable;Ljava/awt/Graphics;Ljava/awt/print/PageFormat;I)Ljava/awt/geom/Rectangle2D;"); + static JNF_MEMBER_CACHE(jm_getOrientation, sjc_PageFormat, "getOrientation", "()I"); // Assertions removed, and corresponding JNFDeleteGlobalRefs added, for radr://3962543 // Actual fix that will keep these assertions from being true is radr://3205462 , @@ -201,6 +204,26 @@ static JNF_CLASS_CACHE(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob"); // Actually print and get the PageFormatArea jobject pageFormatArea = JNFCallObjectMethod(env, fPrinterJob, jm_printAndGetPageFormatArea, fCurPainter, fCurPeekGraphics, fCurPageFormat, jPageNumber); // AWT_THREADING Safe (AWTRunLoopMode) if (pageFormatArea != NULL) { + NSPrintingOrientation currentOrientation = + [[[NSPrintOperation currentOperation] printInfo] orientation]; + // set page orientation + switch (JNFCallIntMethod(env, fCurPageFormat, jm_getOrientation)) { + case java_awt_print_PageFormat_PORTRAIT: + default: + if (currentOrientation != NSPortraitOrientation) { + [[[NSPrintOperation currentOperation] printInfo] + setOrientation:NSPortraitOrientation]; + } + break; + + case java_awt_print_PageFormat_LANDSCAPE: + case java_awt_print_PageFormat_REVERSE_LANDSCAPE: + if (currentOrientation != NSLandscapeOrientation) { + [[[NSPrintOperation currentOperation] printInfo] + setOrientation:NSLandscapeOrientation]; + } + break; + } result = JavaToNSRect(env, pageFormatArea); (*env)->DeleteLocalRef(env, pageFormatArea); } else { From 21d0c9ef0d13cd07ae88b633c711e549071f858a Mon Sep 17 00:00:00 2001 From: Kurchi Subhra Hazra Date: Tue, 24 Apr 2012 14:59:45 -0700 Subject: [PATCH 25/51] 7144274: [macosx] Default IPv6 multicast interface is not being set when calling MulticastSocket.joinGroup() Get default interface for Mac OS X when interface is not set Reviewed-by: chegar --- .../native/java/net/PlainDatagramSocketImpl.c | 7 ++++++- jdk/src/solaris/native/java/net/net_util_md.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c index cbdacdf6bcd..382ec4c83bc 100644 --- a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c +++ b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c @@ -84,6 +84,7 @@ static jfieldID pdsi_ttlID; #endif extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him); +extern int getDefaultScopeID(JNIEnv *env); /* * Returns a java.lang.Integer based on 'i' @@ -2418,7 +2419,11 @@ static void mcast_join_leave(JNIEnv *env, jobject this, } } #endif - +#ifdef MACOSX + if (family == AF_INET6 && index == 0) { + index = getDefaultScopeID(env); + } +#endif mname6.ipv6mr_interface = index; } else { jint idx = (*env)->GetIntField(env, niObj, ni_indexID); diff --git a/jdk/src/solaris/native/java/net/net_util_md.c b/jdk/src/solaris/native/java/net/net_util_md.c index f7e6d6a02ab..ccbe4b15a72 100644 --- a/jdk/src/solaris/native/java/net/net_util_md.c +++ b/jdk/src/solaris/native/java/net/net_util_md.c @@ -109,6 +109,24 @@ void setDefaultScopeID(JNIEnv *env, struct sockaddr *him) #endif } +int getDefaultScopeID(JNIEnv *env) { + static jclass ni_class = NULL; + static jfieldID ni_defaultIndexID; + if (ni_class == NULL) { + jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); + CHECK_NULL(c); + c = (*env)->NewGlobalRef(env, c); + CHECK_NULL(c); + ni_defaultIndexID = (*env)->GetStaticFieldID(env, c, + "defaultIndex", "I"); + ni_class = c; + } + int defaultIndex = 0; + defaultIndex = (*env)->GetStaticIntField(env, ni_class, + ni_defaultIndexID); + return defaultIndex; +} + #ifdef __solaris__ static int init_tcp_max_buf, init_udp_max_buf; static int tcp_max_buf; From b63f7f3a18b6be9210fb8e553b4fc564030ce726 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Wed, 25 Apr 2012 09:55:55 -0700 Subject: [PATCH 26/51] 7164144: Fix variable naming style in freeBlockDictionary.* and binaryTreeDictionary* Fix naming style to be consistent with the predominant hotspot style. Reviewed-by: ysr, brutisso --- .../compactibleFreeListSpace.cpp | 294 ++++++------- .../compactibleFreeListSpace.hpp | 4 +- .../concurrentMarkSweepGeneration.cpp | 54 +-- .../concurrentMarkSweep/freeChunk.hpp | 24 +- .../concurrentMarkSweep/promotionInfo.cpp | 2 +- .../concurrentMarkSweep/promotionInfo.hpp | 18 +- .../concurrentMarkSweep/vmStructs_cms.hpp | 2 +- .../shared/allocationStats.hpp | 90 ++-- .../share/vm/memory/binaryTreeDictionary.cpp | 390 +++++++++--------- .../share/vm/memory/binaryTreeDictionary.hpp | 136 +++--- .../share/vm/memory/freeBlockDictionary.cpp | 4 +- .../share/vm/memory/freeBlockDictionary.hpp | 38 +- hotspot/src/share/vm/memory/freeList.cpp | 76 ++-- hotspot/src/share/vm/memory/freeList.hpp | 108 ++--- 14 files changed, 620 insertions(+), 620 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 8263a42cb14..121829113c7 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -119,7 +119,7 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, // moved to its new location before the klass is moved. // Set the _refillSize for the linear allocation blocks if (!use_adaptive_freelists) { - FreeChunk* fc = _dictionary->getChunk(mr.word_size()); + FreeChunk* fc = _dictionary->get_chunk(mr.word_size()); // The small linAB initially has all the space and will allocate // a chunk of any size. HeapWord* addr = (HeapWord*) fc; @@ -275,12 +275,12 @@ void CompactibleFreeListSpace::reset(MemRegion mr) { assert(mr.word_size() >= MinChunkSize, "Chunk size is too small"); _bt.single_block(mr.start(), mr.word_size()); FreeChunk* fc = (FreeChunk*) mr.start(); - fc->setSize(mr.word_size()); + fc->set_size(mr.word_size()); if (mr.word_size() >= IndexSetSize ) { returnChunkToDictionary(fc); } else { _bt.verify_not_unallocated((HeapWord*)fc, fc->size()); - _indexedFreeList[mr.word_size()].returnChunkAtHead(fc); + _indexedFreeList[mr.word_size()].return_chunk_at_head(fc); } } _promoInfo.reset(); @@ -298,7 +298,7 @@ void CompactibleFreeListSpace::reset_after_compaction() { } else { // Place as much of mr in the linAB as we can get, // provided it was big enough to go into the dictionary. - FreeChunk* fc = dictionary()->findLargestDict(); + FreeChunk* fc = dictionary()->find_largest_dict(); if (fc != NULL) { assert(fc->size() == mr.word_size(), "Why was the chunk broken up?"); @@ -325,14 +325,14 @@ FreeChunk* CompactibleFreeListSpace::find_chunk_at_end() { #ifndef PRODUCT void CompactibleFreeListSpace::initializeIndexedFreeListArrayReturnedBytes() { for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { - _indexedFreeList[i].allocation_stats()->set_returnedBytes(0); + _indexedFreeList[i].allocation_stats()->set_returned_bytes(0); } } size_t CompactibleFreeListSpace::sumIndexedFreeListArrayReturnedBytes() { size_t sum = 0; for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { - sum += _indexedFreeList[i].allocation_stats()->returnedBytes(); + sum += _indexedFreeList[i].allocation_stats()->returned_bytes(); } return sum; } @@ -356,7 +356,7 @@ size_t CompactibleFreeListSpace::totalCountInIndexedFreeLists() const { size_t CompactibleFreeListSpace::totalCount() { size_t num = totalCountInIndexedFreeLists(); - num += dictionary()->totalCount(); + num += dictionary()->total_count(); if (_smallLinearAllocBlock._word_size != 0) { num++; } @@ -366,7 +366,7 @@ size_t CompactibleFreeListSpace::totalCount() { bool CompactibleFreeListSpace::is_free_block(const HeapWord* p) const { FreeChunk* fc = (FreeChunk*) p; - return fc->isFree(); + return fc->is_free(); } size_t CompactibleFreeListSpace::used() const { @@ -393,7 +393,7 @@ size_t CompactibleFreeListSpace::free() const { // that supports jvmstat, and you are apt to see the values // flicker in such cases. assert(_dictionary != NULL, "No _dictionary?"); - return (_dictionary->totalChunkSize(DEBUG_ONLY(freelistLock())) + + return (_dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())) + totalSizeInIndexedFreeLists() + _smallLinearAllocBlock._word_size) * HeapWordSize; } @@ -401,7 +401,7 @@ size_t CompactibleFreeListSpace::free() const { size_t CompactibleFreeListSpace::max_alloc_in_words() const { assert(_dictionary != NULL, "No _dictionary?"); assert_locked(); - size_t res = _dictionary->maxChunkSize(); + size_t res = _dictionary->max_chunk_size(); res = MAX2(res, MIN2(_smallLinearAllocBlock._word_size, (size_t) SmallForLinearAlloc - 1)); // XXX the following could potentially be pretty slow; @@ -469,7 +469,7 @@ const { void CompactibleFreeListSpace::print_dictionary_free_lists(outputStream* st) const { - _dictionary->reportStatistics(); + _dictionary->report_statistics(); st->print_cr("Layout of Freelists in Tree"); st->print_cr("---------------------------"); _dictionary->print_free_lists(st); @@ -547,12 +547,12 @@ void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c, void CompactibleFreeListSpace::reportFreeListStatistics() const { assert_lock_strong(&_freelistLock); assert(PrintFLSStatistics != 0, "Reporting error"); - _dictionary->reportStatistics(); + _dictionary->report_statistics(); if (PrintFLSStatistics > 1) { reportIndexedFreeListStatistics(); - size_t totalSize = totalSizeInIndexedFreeLists() + - _dictionary->totalChunkSize(DEBUG_ONLY(freelistLock())); - gclog_or_tty->print(" free=%ld frag=%1.4f\n", totalSize, flsFrag()); + size_t total_size = totalSizeInIndexedFreeLists() + + _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())); + gclog_or_tty->print(" free=%ld frag=%1.4f\n", total_size, flsFrag()); } } @@ -560,13 +560,13 @@ void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const { assert_lock_strong(&_freelistLock); gclog_or_tty->print("Statistics for IndexedFreeLists:\n" "--------------------------------\n"); - size_t totalSize = totalSizeInIndexedFreeLists(); - size_t freeBlocks = numFreeBlocksInIndexedFreeLists(); - gclog_or_tty->print("Total Free Space: %d\n", totalSize); + size_t total_size = totalSizeInIndexedFreeLists(); + size_t free_blocks = numFreeBlocksInIndexedFreeLists(); + gclog_or_tty->print("Total Free Space: %d\n", total_size); gclog_or_tty->print("Max Chunk Size: %d\n", maxChunkSizeInIndexedFreeLists()); - gclog_or_tty->print("Number of Blocks: %d\n", freeBlocks); - if (freeBlocks != 0) { - gclog_or_tty->print("Av. Block Size: %d\n", totalSize/freeBlocks); + gclog_or_tty->print("Number of Blocks: %d\n", free_blocks); + if (free_blocks != 0) { + gclog_or_tty->print("Av. Block Size: %d\n", total_size/free_blocks); } } @@ -913,7 +913,7 @@ CompactibleFreeListSpace::object_iterate_careful(ObjectClosureCareful* cl) { for (addr = bottom(), last = end(); addr < last; addr += size) { FreeChunk* fc = (FreeChunk*)addr; - if (fc->isFree()) { + if (fc->is_free()) { // Since we hold the free list lock, which protects direct // allocation in this generation by mutators, a free object // will remain free throughout this iteration code. @@ -955,7 +955,7 @@ CompactibleFreeListSpace::object_iterate_careful_m(MemRegion mr, for (addr = block_start_careful(mr.start()), end = mr.end(); addr < end; addr += size) { FreeChunk* fc = (FreeChunk*)addr; - if (fc->isFree()) { + if (fc->is_free()) { // Since we hold the free list lock, which protects direct // allocation in this generation by mutators, a free object // will remain free throughout this iteration code. @@ -1071,7 +1071,7 @@ size_t CompactibleFreeListSpace::block_size_nopar(const HeapWord* p) const { NOT_PRODUCT(verify_objects_initialized()); assert(MemRegion(bottom(), end()).contains(p), "p not in space"); FreeChunk* fc = (FreeChunk*)p; - if (fc->isFree()) { + if (fc->is_free()) { return fc->size(); } else { // Ignore mark word because this may be a recently promoted @@ -1162,7 +1162,7 @@ bool CompactibleFreeListSpace::block_is_obj_nopar(const HeapWord* p) const { FreeChunk* fc = (FreeChunk*)p; assert(is_in_reserved(p), "Should be in space"); assert(_bt.block_start(p) == p, "Should be a block boundary"); - if (!fc->isFree()) { + if (!fc->is_free()) { // Ignore mark word because it may have been used to // chain together promoted objects (the last one // would have a null value). @@ -1224,7 +1224,7 @@ HeapWord* CompactibleFreeListSpace::allocate(size_t size) { FreeChunk* fc = (FreeChunk*)res; fc->markNotFree(); - assert(!fc->isFree(), "shouldn't be marked free"); + assert(!fc->is_free(), "shouldn't be marked free"); assert(oop(fc)->klass_or_null() == NULL, "should look uninitialized"); // Verify that the block offset table shows this to // be a single block, but not one which is unallocated. @@ -1336,7 +1336,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) { FreeList* fl = &_indexedFreeList[i]; if (fl->head()) { ret = getFromListGreater(fl, numWords); - assert(ret == NULL || ret->isFree(), "Should be returning a free chunk"); + assert(ret == NULL || ret->is_free(), "Should be returning a free chunk"); return ret; } } @@ -1347,7 +1347,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) { /* Try to get a chunk that satisfies request, while avoiding fragmentation that can't be handled. */ { - ret = dictionary()->getChunk(currSize); + ret = dictionary()->get_chunk(currSize); if (ret != NULL) { assert(ret->size() - numWords >= MinChunkSize, "Chunk is too small"); @@ -1355,10 +1355,10 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) { /* Carve returned chunk. */ (void) splitChunkAndReturnRemainder(ret, numWords); /* Label this as no longer a free chunk. */ - assert(ret->isFree(), "This chunk should be free"); - ret->linkPrev(NULL); + assert(ret->is_free(), "This chunk should be free"); + ret->link_prev(NULL); } - assert(ret == NULL || ret->isFree(), "Should be returning a free chunk"); + assert(ret == NULL || ret->is_free(), "Should be returning a free chunk"); return ret; } ShouldNotReachHere(); @@ -1366,7 +1366,7 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) { bool CompactibleFreeListSpace::verifyChunkInIndexedFreeLists(FreeChunk* fc) const { assert(fc->size() < IndexSetSize, "Size of chunk is too large"); - return _indexedFreeList[fc->size()].verifyChunkInFreeLists(fc); + return _indexedFreeList[fc->size()].verify_chunk_in_free_list(fc); } bool CompactibleFreeListSpace::verify_chunk_is_linear_alloc_block(FreeChunk* fc) const { @@ -1380,13 +1380,13 @@ bool CompactibleFreeListSpace::verify_chunk_is_linear_alloc_block(FreeChunk* fc) // Check if the purported free chunk is present either as a linear // allocation block, the size-indexed table of (smaller) free blocks, // or the larger free blocks kept in the binary tree dictionary. -bool CompactibleFreeListSpace::verifyChunkInFreeLists(FreeChunk* fc) const { +bool CompactibleFreeListSpace::verify_chunk_in_free_list(FreeChunk* fc) const { if (verify_chunk_is_linear_alloc_block(fc)) { return true; } else if (fc->size() < IndexSetSize) { return verifyChunkInIndexedFreeLists(fc); } else { - return dictionary()->verifyChunkInFreeLists(fc); + return dictionary()->verify_chunk_in_free_list(fc); } } @@ -1414,7 +1414,7 @@ FreeChunk* CompactibleFreeListSpace::allocateScratch(size_t size) { } if (fc != NULL) { fc->dontCoalesce(); - assert(fc->isFree(), "Should be free, but not coalescable"); + assert(fc->is_free(), "Should be free, but not coalescable"); // Verify that the block offset table shows this to // be a single block, but not one which is unallocated. _bt.verify_single_block((HeapWord*)fc, fc->size()); @@ -1494,7 +1494,7 @@ CompactibleFreeListSpace::getChunkFromLinearAllocBlock(LinearAllocBlock *blk, } // Return the chunk that isn't big enough, and then refill below. addChunkToFreeLists(blk->_ptr, sz); - splitBirth(sz); + split_birth(sz); // Don't keep statistics on adding back chunk from a LinAB. } else { // A refilled block would not satisfy the request. @@ -1506,14 +1506,14 @@ CompactibleFreeListSpace::getChunkFromLinearAllocBlock(LinearAllocBlock *blk, assert(blk->_ptr == NULL || blk->_word_size >= size + MinChunkSize, "block was replenished"); if (res != NULL) { - splitBirth(size); + split_birth(size); repairLinearAllocBlock(blk); } else if (blk->_ptr != NULL) { res = blk->_ptr; size_t blk_size = blk->_word_size; blk->_word_size -= size; blk->_ptr += size; - splitBirth(size); + split_birth(size); repairLinearAllocBlock(blk); // Update BOT last so that other (parallel) GC threads see a consistent // view of the BOT and free blocks. @@ -1542,7 +1542,7 @@ HeapWord* CompactibleFreeListSpace::getChunkFromLinearAllocBlockRemainder( size_t blk_size = blk->_word_size; blk->_word_size -= size; blk->_ptr += size; - splitBirth(size); + split_birth(size); repairLinearAllocBlock(blk); // Update BOT last so that other (parallel) GC threads see a consistent // view of the BOT and free blocks. @@ -1559,7 +1559,7 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeList(size_t size) { assert_locked(); assert(size < SmallForDictionary, "just checking"); FreeChunk* res; - res = _indexedFreeList[size].getChunkAtHead(); + res = _indexedFreeList[size].get_chunk_at_head(); if (res == NULL) { res = getChunkFromIndexedFreeListHelper(size); } @@ -1593,7 +1593,7 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size, // Do not replenish from an underpopulated size. if (_indexedFreeList[replenish_size].surplus() > 0 && _indexedFreeList[replenish_size].head() != NULL) { - newFc = _indexedFreeList[replenish_size].getChunkAtHead(); + newFc = _indexedFreeList[replenish_size].get_chunk_at_head(); } else if (bestFitFirst()) { newFc = bestFitSmall(replenish_size); } @@ -1626,13 +1626,13 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size, i < (num_blk - 1); curFc = nextFc, nextFc = (FreeChunk*)((HeapWord*)nextFc + size), i++) { - curFc->setSize(size); + curFc->set_size(size); // Don't record this as a return in order to try and // determine the "returns" from a GC. _bt.verify_not_unallocated((HeapWord*) fc, size); - _indexedFreeList[size].returnChunkAtTail(curFc, false); + _indexedFreeList[size].return_chunk_at_tail(curFc, false); _bt.mark_block((HeapWord*)curFc, size); - splitBirth(size); + split_birth(size); // Don't record the initial population of the indexed list // as a split birth. } @@ -1640,9 +1640,9 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size, // check that the arithmetic was OK above assert((HeapWord*)nextFc == (HeapWord*)newFc + num_blk*size, "inconsistency in carving newFc"); - curFc->setSize(size); + curFc->set_size(size); _bt.mark_block((HeapWord*)curFc, size); - splitBirth(size); + split_birth(size); fc = curFc; } else { // Return entire block to caller @@ -1655,14 +1655,14 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size, // replenish the indexed free list. fc = getChunkFromDictionaryExact(size); } - // assert(fc == NULL || fc->isFree(), "Should be returning a free chunk"); + // assert(fc == NULL || fc->is_free(), "Should be returning a free chunk"); return fc; } FreeChunk* CompactibleFreeListSpace::getChunkFromDictionary(size_t size) { assert_locked(); - FreeChunk* fc = _dictionary->getChunk(size); + FreeChunk* fc = _dictionary->get_chunk(size); if (fc == NULL) { return NULL; } @@ -1679,7 +1679,7 @@ CompactibleFreeListSpace::getChunkFromDictionary(size_t size) { FreeChunk* CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) { assert_locked(); - FreeChunk* fc = _dictionary->getChunk(size); + FreeChunk* fc = _dictionary->get_chunk(size); if (fc == NULL) { return fc; } @@ -1688,11 +1688,11 @@ CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) { _bt.verify_single_block((HeapWord*)fc, size); return fc; } - assert(fc->size() > size, "getChunk() guarantee"); + assert(fc->size() > size, "get_chunk() guarantee"); if (fc->size() < size + MinChunkSize) { // Return the chunk to the dictionary and go get a bigger one. returnChunkToDictionary(fc); - fc = _dictionary->getChunk(size + MinChunkSize); + fc = _dictionary->get_chunk(size + MinChunkSize); if (fc == NULL) { return NULL; } @@ -1713,7 +1713,7 @@ CompactibleFreeListSpace::returnChunkToDictionary(FreeChunk* chunk) { _bt.verify_single_block((HeapWord*)chunk, size); // adjust _unallocated_block downward, as necessary _bt.freed((HeapWord*)chunk, size); - _dictionary->returnChunk(chunk); + _dictionary->return_chunk(chunk); #ifndef PRODUCT if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { TreeChunk::as_TreeChunk(chunk)->list()->verify_stats(); @@ -1728,9 +1728,9 @@ CompactibleFreeListSpace::returnChunkToFreeList(FreeChunk* fc) { _bt.verify_single_block((HeapWord*) fc, size); _bt.verify_not_unallocated((HeapWord*) fc, size); if (_adaptive_freelists) { - _indexedFreeList[size].returnChunkAtTail(fc); + _indexedFreeList[size].return_chunk_at_tail(fc); } else { - _indexedFreeList[size].returnChunkAtHead(fc); + _indexedFreeList[size].return_chunk_at_head(fc); } #ifndef PRODUCT if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { @@ -1758,7 +1758,7 @@ CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats( FreeChunk* ec; { MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag); - ec = dictionary()->findLargestDict(); // get largest block + ec = dictionary()->find_largest_dict(); // get largest block if (ec != NULL && ec->end() == chunk) { // It's a coterminal block - we can coalesce. size_t old_size = ec->size(); @@ -1769,7 +1769,7 @@ CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats( ec = (FreeChunk*)chunk; } } - ec->setSize(size); + ec->set_size(size); debug_only(ec->mangleFreed(size)); if (size < SmallForDictionary) { lock = _indexedFreeListParLocks[size]; @@ -1792,7 +1792,7 @@ CompactibleFreeListSpace::addChunkToFreeLists(HeapWord* chunk, _bt.verify_single_block(chunk, size); FreeChunk* fc = (FreeChunk*) chunk; - fc->setSize(size); + fc->set_size(size); debug_only(fc->mangleFreed(size)); if (size < SmallForDictionary) { returnChunkToFreeList(fc); @@ -1835,7 +1835,7 @@ CompactibleFreeListSpace::removeChunkFromDictionary(FreeChunk* fc) { assert_locked(); assert(fc != NULL, "null chunk"); _bt.verify_single_block((HeapWord*)fc, size); - _dictionary->removeChunk(fc); + _dictionary->remove_chunk(fc); // adjust _unallocated_block upward, as necessary _bt.allocated((HeapWord*)fc, size); } @@ -1850,7 +1850,7 @@ CompactibleFreeListSpace::removeChunkFromIndexedFreeList(FreeChunk* fc) { verifyIndexedFreeList(size); } ) - _indexedFreeList[size].removeChunk(fc); + _indexedFreeList[size].remove_chunk(fc); NOT_PRODUCT( if (FLSVerifyIndexTable) { verifyIndexedFreeList(size); @@ -1874,7 +1874,7 @@ FreeChunk* CompactibleFreeListSpace::bestFitSmall(size_t numWords) { // and split out a free chunk which is returned. _indexedFreeList[start].set_hint(hint); FreeChunk* res = getFromListGreater(fl, numWords); - assert(res == NULL || res->isFree(), + assert(res == NULL || res->is_free(), "Should be returning a free chunk"); return res; } @@ -1896,13 +1896,13 @@ FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl, assert(oldNumWords >= numWords + MinChunkSize, "Size of chunks in the list is too small"); - fl->removeChunk(curr); + fl->remove_chunk(curr); // recorded indirectly by splitChunkAndReturnRemainder - // smallSplit(oldNumWords, numWords); FreeChunk* new_chunk = splitChunkAndReturnRemainder(curr, numWords); // Does anything have to be done for the remainder in terms of // fixing the card table? - assert(new_chunk == NULL || new_chunk->isFree(), + assert(new_chunk == NULL || new_chunk->is_free(), "Should be returning a free chunk"); return new_chunk; } @@ -1920,13 +1920,13 @@ CompactibleFreeListSpace::splitChunkAndReturnRemainder(FreeChunk* chunk, assert(rem_size >= MinChunkSize, "Free chunk smaller than minimum"); FreeChunk* ffc = (FreeChunk*)((HeapWord*)chunk + new_size); assert(is_aligned(ffc), "alignment problem"); - ffc->setSize(rem_size); - ffc->linkNext(NULL); - ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads. + ffc->set_size(rem_size); + ffc->link_next(NULL); + ffc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads. // Above must occur before BOT is updated below. // adjust block offset table OrderAccess::storestore(); - assert(chunk->isFree() && ffc->isFree(), "Error"); + assert(chunk->is_free() && ffc->is_free(), "Error"); _bt.split_block((HeapWord*)chunk, chunk->size(), new_size); if (rem_size < SmallForDictionary) { bool is_par = (SharedHeap::heap()->n_par_threads() > 0); @@ -1941,7 +1941,7 @@ CompactibleFreeListSpace::splitChunkAndReturnRemainder(FreeChunk* chunk, returnChunkToDictionary(ffc); split(size ,rem_size); } - chunk->setSize(new_size); + chunk->set_size(new_size); return chunk; } @@ -2048,10 +2048,10 @@ void CompactibleFreeListSpace::repairLinearAllocBlock(LinearAllocBlock* blk) { assert(blk->_word_size != 0 && blk->_word_size >= MinChunkSize, "Minimum block size requirement"); FreeChunk* fc = (FreeChunk*)(blk->_ptr); - fc->setSize(blk->_word_size); - fc->linkPrev(NULL); // mark as free + fc->set_size(blk->_word_size); + fc->link_prev(NULL); // mark as free fc->dontCoalesce(); - assert(fc->isFree(), "just marked it free"); + assert(fc->is_free(), "just marked it free"); assert(fc->cantCoalesce(), "just marked it uncoalescable"); } } @@ -2151,7 +2151,7 @@ double CompactibleFreeListSpace::flsFrag() const { } double totFree = itabFree + - _dictionary->totalChunkSize(DEBUG_ONLY(freelistLock())); + _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())); if (totFree > 0) { frag = ((frag + _dictionary->sum_of_squared_block_sizes()) / (totFree * totFree)); @@ -2174,11 +2174,11 @@ void CompactibleFreeListSpace::beginSweepFLCensus( gclog_or_tty->print("size[%d] : ", i); } fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); - fl->set_coalDesired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); - fl->set_beforeSweep(fl->count()); - fl->set_bfrSurp(fl->surplus()); + fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); + fl->set_before_sweep(fl->count()); + fl->set_bfr_surp(fl->surplus()); } - _dictionary->beginSweepDictCensus(CMSLargeCoalSurplusPercent, + _dictionary->begin_sweep_dict_census(CMSLargeCoalSurplusPercent, inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); @@ -2212,17 +2212,17 @@ void CompactibleFreeListSpace::clearFLCensus() { size_t i; for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { FreeList *fl = &_indexedFreeList[i]; - fl->set_prevSweep(fl->count()); - fl->set_coalBirths(0); - fl->set_coalDeaths(0); - fl->set_splitBirths(0); - fl->set_splitDeaths(0); + fl->set_prev_sweep(fl->count()); + fl->set_coal_births(0); + fl->set_coal_deaths(0); + fl->set_split_births(0); + fl->set_split_deaths(0); } } void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { if (PrintFLSStatistics > 0) { - HeapWord* largestAddr = (HeapWord*) dictionary()->findLargestDict(); + HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict(); gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT, largestAddr); } @@ -2233,30 +2233,30 @@ void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { } clearFLCensus(); assert_locked(); - _dictionary->endSweepDictCensus(CMSLargeSplitSurplusPercent); + _dictionary->end_sweep_dict_census(CMSLargeSplitSurplusPercent); } bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { if (size < SmallForDictionary) { FreeList *fl = &_indexedFreeList[size]; - return (fl->coalDesired() < 0) || - ((int)fl->count() > fl->coalDesired()); + return (fl->coal_desired() < 0) || + ((int)fl->count() > fl->coal_desired()); } else { - return dictionary()->coalDictOverPopulated(size); + return dictionary()->coal_dict_over_populated(size); } } void CompactibleFreeListSpace::smallCoalBirth(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); FreeList *fl = &_indexedFreeList[size]; - fl->increment_coalBirths(); + fl->increment_coal_births(); fl->increment_surplus(); } void CompactibleFreeListSpace::smallCoalDeath(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); FreeList *fl = &_indexedFreeList[size]; - fl->increment_coalDeaths(); + fl->increment_coal_deaths(); fl->decrement_surplus(); } @@ -2264,7 +2264,7 @@ void CompactibleFreeListSpace::coalBirth(size_t size) { if (size < SmallForDictionary) { smallCoalBirth(size); } else { - dictionary()->dictCensusUpdate(size, + dictionary()->dict_census_udpate(size, false /* split */, true /* birth */); } @@ -2274,7 +2274,7 @@ void CompactibleFreeListSpace::coalDeath(size_t size) { if(size < SmallForDictionary) { smallCoalDeath(size); } else { - dictionary()->dictCensusUpdate(size, + dictionary()->dict_census_udpate(size, false /* split */, false /* birth */); } @@ -2283,22 +2283,22 @@ void CompactibleFreeListSpace::coalDeath(size_t size) { void CompactibleFreeListSpace::smallSplitBirth(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); FreeList *fl = &_indexedFreeList[size]; - fl->increment_splitBirths(); + fl->increment_split_births(); fl->increment_surplus(); } void CompactibleFreeListSpace::smallSplitDeath(size_t size) { assert(size < SmallForDictionary, "Size too large for indexed list"); FreeList *fl = &_indexedFreeList[size]; - fl->increment_splitDeaths(); + fl->increment_split_deaths(); fl->decrement_surplus(); } -void CompactibleFreeListSpace::splitBirth(size_t size) { +void CompactibleFreeListSpace::split_birth(size_t size) { if (size < SmallForDictionary) { smallSplitBirth(size); } else { - dictionary()->dictCensusUpdate(size, + dictionary()->dict_census_udpate(size, true /* split */, true /* birth */); } @@ -2308,7 +2308,7 @@ void CompactibleFreeListSpace::splitDeath(size_t size) { if (size < SmallForDictionary) { smallSplitDeath(size); } else { - dictionary()->dictCensusUpdate(size, + dictionary()->dict_census_udpate(size, true /* split */, false /* birth */); } @@ -2317,8 +2317,8 @@ void CompactibleFreeListSpace::splitDeath(size_t size) { void CompactibleFreeListSpace::split(size_t from, size_t to1) { size_t to2 = from - to1; splitDeath(from); - splitBirth(to1); - splitBirth(to2); + split_birth(to1); + split_birth(to2); } void CompactibleFreeListSpace::print() const { @@ -2364,7 +2364,7 @@ class VerifyAllBlksClosure: public BlkClosure { FreeChunk* fc = (FreeChunk*)addr; res = fc->size(); if (FLSVerifyLists && !fc->cantCoalesce()) { - guarantee(_sp->verifyChunkInFreeLists(fc), + guarantee(_sp->verify_chunk_in_free_list(fc), "Chunk should be on a free list"); } } @@ -2520,7 +2520,7 @@ void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const { "Slot should have been empty"); for (; fc != NULL; fc = fc->next(), n++) { guarantee(fc->size() == size, "Size inconsistency"); - guarantee(fc->isFree(), "!free?"); + guarantee(fc->is_free(), "!free?"); guarantee(fc->next() == NULL || fc->next()->prev() == fc, "Broken list"); guarantee((fc->next() == NULL) == (fc == tail), "Incorrect tail"); } @@ -2529,7 +2529,7 @@ void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const { #ifndef PRODUCT void CompactibleFreeListSpace::check_free_list_consistency() const { - assert(_dictionary->minSize() <= IndexSetSize, + assert(_dictionary->min_size() <= IndexSetSize, "Some sizes can't be allocated without recourse to" " linear allocation buffers"); assert(BinaryTreeDictionary::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk), @@ -2548,33 +2548,33 @@ void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { FreeList total; gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); FreeList::print_labels_on(gclog_or_tty, "size"); - size_t totalFree = 0; + size_t total_free = 0; for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { const FreeList *fl = &_indexedFreeList[i]; - totalFree += fl->count() * fl->size(); + total_free += fl->count() * fl->size(); if (i % (40*IndexSetStride) == 0) { FreeList::print_labels_on(gclog_or_tty, "size"); } fl->print_on(gclog_or_tty); - total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() ); + total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() ); total.set_surplus( total.surplus() + fl->surplus() ); total.set_desired( total.desired() + fl->desired() ); - total.set_prevSweep( total.prevSweep() + fl->prevSweep() ); - total.set_beforeSweep(total.beforeSweep() + fl->beforeSweep()); + total.set_prev_sweep( total.prev_sweep() + fl->prev_sweep() ); + total.set_before_sweep(total.before_sweep() + fl->before_sweep()); total.set_count( total.count() + fl->count() ); - total.set_coalBirths( total.coalBirths() + fl->coalBirths() ); - total.set_coalDeaths( total.coalDeaths() + fl->coalDeaths() ); - total.set_splitBirths(total.splitBirths() + fl->splitBirths()); - total.set_splitDeaths(total.splitDeaths() + fl->splitDeaths()); + total.set_coal_births( total.coal_births() + fl->coal_births() ); + total.set_coal_deaths( total.coal_deaths() + fl->coal_deaths() ); + total.set_split_births(total.split_births() + fl->split_births()); + total.set_split_deaths(total.split_deaths() + fl->split_deaths()); } total.print_on(gclog_or_tty, "TOTAL"); gclog_or_tty->print_cr("Total free in indexed lists " - SIZE_FORMAT " words", totalFree); + SIZE_FORMAT " words", total_free); gclog_or_tty->print("growth: %8.5f deficit: %8.5f\n", - (double)(total.splitBirths()+total.coalBirths()-total.splitDeaths()-total.coalDeaths())/ - (total.prevSweep() != 0 ? (double)total.prevSweep() : 1.0), + (double)(total.split_births()+total.coal_births()-total.split_deaths()-total.coal_deaths())/ + (total.prev_sweep() != 0 ? (double)total.prev_sweep() : 1.0), (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0)); - _dictionary->printDictCensus(); + _dictionary->print_dict_census(); } /////////////////////////////////////////////////////////////////////////// @@ -2643,11 +2643,11 @@ HeapWord* CFLS_LAB::alloc(size_t word_sz) { // If it didn't work, give up. if (fl->count() == 0) return NULL; } - res = fl->getChunkAtHead(); + res = fl->get_chunk_at_head(); assert(res != NULL, "Why was count non-zero?"); } res->markNotFree(); - assert(!res->isFree(), "shouldn't be marked free"); + assert(!res->is_free(), "shouldn't be marked free"); assert(oop(res)->klass_or_null() == NULL, "should look uninitialized"); // mangle a just allocated object with a distinct pattern. debug_only(res->mangleAllocated(word_sz)); @@ -2786,9 +2786,9 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n // we increment the split death count by the number of blocks // we just took from the cur_sz-size blocks list and which // we will be splitting below. - ssize_t deaths = gfl->splitDeaths() + + ssize_t deaths = gfl->split_deaths() + fl_for_cur_sz.count(); - gfl->set_splitDeaths(deaths); + gfl->set_split_deaths(deaths); } } } @@ -2799,21 +2799,21 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n } else { // Divide each block on fl_for_cur_sz up k ways. FreeChunk* fc; - while ((fc = fl_for_cur_sz.getChunkAtHead()) != NULL) { + while ((fc = fl_for_cur_sz.get_chunk_at_head()) != NULL) { // Must do this in reverse order, so that anybody attempting to // access the main chunk sees it as a single free block until we // change it. size_t fc_size = fc->size(); - assert(fc->isFree(), "Error"); + assert(fc->is_free(), "Error"); for (int i = k-1; i >= 0; i--) { FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz); assert((i != 0) || - ((fc == ffc) && ffc->isFree() && + ((fc == ffc) && ffc->is_free() && (ffc->size() == k*word_sz) && (fc_size == word_sz)), "Counting error"); - ffc->setSize(word_sz); - ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads. - ffc->linkNext(NULL); + ffc->set_size(word_sz); + ffc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads. + ffc->link_next(NULL); // Above must occur before BOT is updated below. OrderAccess::storestore(); // splitting from the right, fc_size == i * word_sz @@ -2824,7 +2824,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n _bt.verify_single_block((HeapWord*)fc, fc_size); _bt.verify_single_block((HeapWord*)ffc, word_sz); // Push this on "fl". - fl->returnChunkAtHead(ffc); + fl->return_chunk_at_head(ffc); } // TRAP assert(fl->tail()->next() == NULL, "List invariant."); @@ -2834,8 +2834,8 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n size_t num = fl->count(); MutexLockerEx x(_indexedFreeListParLocks[word_sz], Mutex::_no_safepoint_check_flag); - ssize_t births = _indexedFreeList[word_sz].splitBirths() + num; - _indexedFreeList[word_sz].set_splitBirths(births); + ssize_t births = _indexedFreeList[word_sz].split_births() + num; + _indexedFreeList[word_sz].set_split_births(births); return; } } @@ -2848,12 +2848,12 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n MutexLockerEx x(parDictionaryAllocLock(), Mutex::_no_safepoint_check_flag); while (n > 0) { - fc = dictionary()->getChunk(MAX2(n * word_sz, - _dictionary->minSize()), + fc = dictionary()->get_chunk(MAX2(n * word_sz, + _dictionary->min_size()), FreeBlockDictionary::atLeast); if (fc != NULL) { _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk - dictionary()->dictCensusUpdate(fc->size(), + dictionary()->dict_census_udpate(fc->size(), true /*split*/, false /*birth*/); break; @@ -2864,7 +2864,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n if (fc == NULL) return; // Otherwise, split up that block. assert((ssize_t)n >= 1, "Control point invariant"); - assert(fc->isFree(), "Error: should be a free block"); + assert(fc->is_free(), "Error: should be a free block"); _bt.verify_single_block((HeapWord*)fc, fc->size()); const size_t nn = fc->size() / word_sz; n = MIN2(nn, n); @@ -2895,18 +2895,18 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n if (rem > 0) { size_t prefix_size = n * word_sz; rem_fc = (FreeChunk*)((HeapWord*)fc + prefix_size); - rem_fc->setSize(rem); - rem_fc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads. - rem_fc->linkNext(NULL); + rem_fc->set_size(rem); + rem_fc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads. + rem_fc->link_next(NULL); // Above must occur before BOT is updated below. assert((ssize_t)n > 0 && prefix_size > 0 && rem_fc > fc, "Error"); OrderAccess::storestore(); _bt.split_block((HeapWord*)fc, fc->size(), prefix_size); - assert(fc->isFree(), "Error"); - fc->setSize(prefix_size); + assert(fc->is_free(), "Error"); + fc->set_size(prefix_size); if (rem >= IndexSetSize) { returnChunkToDictionary(rem_fc); - dictionary()->dictCensusUpdate(rem, true /*split*/, true /*birth*/); + dictionary()->dict_census_udpate(rem, true /*split*/, true /*birth*/); rem_fc = NULL; } // Otherwise, return it to the small list below. @@ -2916,7 +2916,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n MutexLockerEx x(_indexedFreeListParLocks[rem], Mutex::_no_safepoint_check_flag); _bt.verify_not_unallocated((HeapWord*)rem_fc, rem_fc->size()); - _indexedFreeList[rem].returnChunkAtHead(rem_fc); + _indexedFreeList[rem].return_chunk_at_head(rem_fc); smallSplitBirth(rem); } assert((ssize_t)n > 0 && fc != NULL, "Consistency"); @@ -2928,9 +2928,9 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n // All but first chunk in this loop for (ssize_t i = n-1; i > 0; i--) { FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz); - ffc->setSize(word_sz); - ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads. - ffc->linkNext(NULL); + ffc->set_size(word_sz); + ffc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads. + ffc->link_next(NULL); // Above must occur before BOT is updated below. OrderAccess::storestore(); // splitting from the right, fc_size == (n - i + 1) * wordsize @@ -2940,25 +2940,25 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n _bt.verify_single_block((HeapWord*)ffc, ffc->size()); _bt.verify_single_block((HeapWord*)fc, fc_size); // Push this on "fl". - fl->returnChunkAtHead(ffc); + fl->return_chunk_at_head(ffc); } // First chunk - assert(fc->isFree() && fc->size() == n*word_sz, "Error: should still be a free block"); + assert(fc->is_free() && fc->size() == n*word_sz, "Error: should still be a free block"); // The blocks above should show their new sizes before the first block below - fc->setSize(word_sz); - fc->linkPrev(NULL); // idempotent wrt free-ness, see assert above - fc->linkNext(NULL); + fc->set_size(word_sz); + fc->link_prev(NULL); // idempotent wrt free-ness, see assert above + fc->link_next(NULL); _bt.verify_not_unallocated((HeapWord*)fc, fc->size()); _bt.verify_single_block((HeapWord*)fc, fc->size()); - fl->returnChunkAtHead(fc); + fl->return_chunk_at_head(fc); assert((ssize_t)n > 0 && (ssize_t)n == fl->count(), "Incorrect number of blocks"); { // Update the stats for this block size. MutexLockerEx x(_indexedFreeListParLocks[word_sz], Mutex::_no_safepoint_check_flag); - const ssize_t births = _indexedFreeList[word_sz].splitBirths() + n; - _indexedFreeList[word_sz].set_splitBirths(births); + const ssize_t births = _indexedFreeList[word_sz].split_births() + n; + _indexedFreeList[word_sz].set_split_births(births); // ssize_t new_surplus = _indexedFreeList[word_sz].surplus() + n; // _indexedFreeList[word_sz].set_surplus(new_surplus); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp index 35eb1bfac3d..663b747fd77 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @@ -499,7 +499,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { // Verify that the given chunk is in the free lists: // i.e. either the binary tree dictionary, the indexed free lists // or the linear allocation block. - bool verifyChunkInFreeLists(FreeChunk* fc) const; + bool verify_chunk_in_free_list(FreeChunk* fc) const; // Verify that the given chunk is the linear allocation block bool verify_chunk_is_linear_alloc_block(FreeChunk* fc) const; // Do some basic checks on the the free lists. @@ -608,7 +608,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { void coalDeath(size_t size); void smallSplitBirth(size_t size); void smallSplitDeath(size_t size); - void splitBirth(size_t size); + void split_birth(size_t size); void splitDeath(size_t size); void split(size_t from, size_t to1); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index bedd9aa0971..5825a5772fc 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -1026,7 +1026,7 @@ HeapWord* ConcurrentMarkSweepGeneration::have_lock_and_allocate(size_t size, // its mark-bit or P-bits not yet set. Such objects need // to be safely navigable by block_start(). assert(oop(res)->klass_or_null() == NULL, "Object should be uninitialized here."); - assert(!((FreeChunk*)res)->isFree(), "Error, block will look free but show wrong size"); + assert(!((FreeChunk*)res)->is_free(), "Error, block will look free but show wrong size"); collector()->direct_allocated(res, adjustedSize); _direct_allocated_words += adjustedSize; // allocation counters @@ -1391,7 +1391,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num, oop obj = oop(obj_ptr); OrderAccess::storestore(); assert(obj->klass_or_null() == NULL, "Object should be uninitialized here."); - assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size"); + assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size"); // IMPORTANT: See note on object initialization for CMS above. // Otherwise, copy the object. Here we must be careful to insert the // klass pointer last, since this marks the block as an allocated object. @@ -1400,7 +1400,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num, // Restore the mark word copied above. obj->set_mark(m); assert(obj->klass_or_null() == NULL, "Object should be uninitialized here."); - assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size"); + assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size"); OrderAccess::storestore(); if (UseCompressedOops) { @@ -1421,7 +1421,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num, promoInfo->track((PromotedObject*)obj, old->klass()); } assert(obj->klass_or_null() == NULL, "Object should be uninitialized here."); - assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size"); + assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size"); assert(old->is_oop(), "Will use and dereference old klass ptr below"); // Finally, install the klass pointer (this should be volatile). @@ -2034,7 +2034,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) { pointer_delta(cms_space->end(), cms_space->compaction_top()) * HeapWordSize, "All the free space should be compacted into one chunk at top"); - assert(cms_space->dictionary()->totalChunkSize( + assert(cms_space->dictionary()->total_chunk_size( debug_only(cms_space->freelistLock())) == 0 || cms_space->totalSizeInIndexedFreeLists() == 0, "All the free space should be in a single chunk"); @@ -6131,7 +6131,7 @@ void ConcurrentMarkSweepGeneration::setNearLargestChunk() { double nearLargestPercent = FLSLargestBlockCoalesceProximity; HeapWord* minAddr = _cmsSpace->bottom(); HeapWord* largestAddr = - (HeapWord*) _cmsSpace->dictionary()->findLargestDict(); + (HeapWord*) _cmsSpace->dictionary()->find_largest_dict(); if (largestAddr == NULL) { // The dictionary appears to be empty. In this case // try to coalesce at the end of the heap. @@ -7906,7 +7906,7 @@ SweepClosure::SweepClosure(CMSCollector* collector, _last_fc = NULL; _sp->initializeIndexedFreeListArrayReturnedBytes(); - _sp->dictionary()->initializeDictReturnedBytes(); + _sp->dictionary()->initialize_dict_returned_bytes(); ) assert(_limit >= _sp->bottom() && _limit <= _sp->end(), "sweep _limit out of bounds"); @@ -7954,13 +7954,13 @@ SweepClosure::~SweepClosure() { if (PrintCMSStatistics && CMSVerifyReturnedBytes) { size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes(); - size_t dictReturnedBytes = _sp->dictionary()->sumDictReturnedBytes(); - size_t returnedBytes = indexListReturnedBytes + dictReturnedBytes; - gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returnedBytes); + size_t dict_returned_bytes = _sp->dictionary()->sum_dict_returned_bytes(); + size_t returned_bytes = indexListReturnedBytes + dict_returned_bytes; + gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returned_bytes); gclog_or_tty->print(" Indexed List Returned "SIZE_FORMAT" bytes", indexListReturnedBytes); gclog_or_tty->print_cr(" Dictionary Returned "SIZE_FORMAT" bytes", - dictReturnedBytes); + dict_returned_bytes); } } if (CMSTraceSweeper) { @@ -7985,9 +7985,9 @@ void SweepClosure::initialize_free_range(HeapWord* freeFinger, if (CMSTestInFreeList) { if (freeRangeInFreeLists) { FreeChunk* fc = (FreeChunk*) freeFinger; - assert(fc->isFree(), "A chunk on the free list should be free."); + assert(fc->is_free(), "A chunk on the free list should be free."); assert(fc->size() > 0, "Free range should have a size"); - assert(_sp->verifyChunkInFreeLists(fc), "Chunk is not in free lists"); + assert(_sp->verify_chunk_in_free_list(fc), "Chunk is not in free lists"); } } } @@ -8057,7 +8057,7 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) { assert(addr < _limit, "sweep invariant"); // check if we should yield do_yield_check(addr); - if (fc->isFree()) { + if (fc->is_free()) { // Chunk that is already free res = fc->size(); do_already_free_chunk(fc); @@ -8145,7 +8145,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) { // Chunks that cannot be coalesced are not in the // free lists. if (CMSTestInFreeList && !fc->cantCoalesce()) { - assert(_sp->verifyChunkInFreeLists(fc), + assert(_sp->verify_chunk_in_free_list(fc), "free chunk should be in free lists"); } // a chunk that is already free, should not have been @@ -8171,7 +8171,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) { FreeChunk* nextChunk = (FreeChunk*)(addr + size); assert((HeapWord*)nextChunk <= _sp->end(), "Chunk size out of bounds?"); if ((HeapWord*)nextChunk < _sp->end() && // There is another free chunk to the right ... - nextChunk->isFree() && // ... which is free... + nextChunk->is_free() && // ... which is free... nextChunk->cantCoalesce()) { // ... but can't be coalesced // nothing to do } else { @@ -8203,7 +8203,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) { assert(ffc->size() == pointer_delta(addr, freeFinger()), "Size of free range is inconsistent with chunk size."); if (CMSTestInFreeList) { - assert(_sp->verifyChunkInFreeLists(ffc), + assert(_sp->verify_chunk_in_free_list(ffc), "free range is not in free lists"); } _sp->removeFreeChunkFromFreeLists(ffc); @@ -8262,7 +8262,7 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) { assert(ffc->size() == pointer_delta(addr, freeFinger()), "Size of free range is inconsistent with chunk size."); if (CMSTestInFreeList) { - assert(_sp->verifyChunkInFreeLists(ffc), + assert(_sp->verify_chunk_in_free_list(ffc), "free range is not in free lists"); } _sp->removeFreeChunkFromFreeLists(ffc); @@ -8351,11 +8351,11 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, size_t chunkSize) { // do_post_free_or_garbage_chunk() should only be called in the case // of the adaptive free list allocator. - const bool fcInFreeLists = fc->isFree(); + const bool fcInFreeLists = fc->is_free(); assert(_sp->adaptive_freelists(), "Should only be used in this case."); assert((HeapWord*)fc <= _limit, "sweep invariant"); if (CMSTestInFreeList && fcInFreeLists) { - assert(_sp->verifyChunkInFreeLists(fc), "free chunk is not in free lists"); + assert(_sp->verify_chunk_in_free_list(fc), "free chunk is not in free lists"); } if (CMSTraceSweeper) { @@ -8410,7 +8410,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, assert(ffc->size() == pointer_delta(fc_addr, freeFinger()), "Size of free range is inconsistent with chunk size."); if (CMSTestInFreeList) { - assert(_sp->verifyChunkInFreeLists(ffc), + assert(_sp->verify_chunk_in_free_list(ffc), "Chunk is not in free lists"); } _sp->coalDeath(ffc->size()); @@ -8459,7 +8459,7 @@ void SweepClosure::lookahead_and_flush(FreeChunk* fc, size_t chunk_size) { " when examining fc = " PTR_FORMAT "(" SIZE_FORMAT ")", _limit, _sp->bottom(), _sp->end(), fc, chunk_size)); if (eob >= _limit) { - assert(eob == _limit || fc->isFree(), "Only a free chunk should allow us to cross over the limit"); + assert(eob == _limit || fc->is_free(), "Only a free chunk should allow us to cross over the limit"); if (CMSTraceSweeper) { gclog_or_tty->print_cr("_limit " PTR_FORMAT " reached or crossed by block " "[" PTR_FORMAT "," PTR_FORMAT ") in space " @@ -8482,8 +8482,8 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) { if (!freeRangeInFreeLists()) { if (CMSTestInFreeList) { FreeChunk* fc = (FreeChunk*) chunk; - fc->setSize(size); - assert(!_sp->verifyChunkInFreeLists(fc), + fc->set_size(size); + assert(!_sp->verify_chunk_in_free_list(fc), "chunk should not be in free lists yet"); } if (CMSTraceSweeper) { @@ -8557,8 +8557,8 @@ void SweepClosure::do_yield_work(HeapWord* addr) { // This is actually very useful in a product build if it can // be called from the debugger. Compile it into the product // as needed. -bool debug_verifyChunkInFreeLists(FreeChunk* fc) { - return debug_cms_space->verifyChunkInFreeLists(fc); +bool debug_verify_chunk_in_free_list(FreeChunk* fc) { + return debug_cms_space->verify_chunk_in_free_list(fc); } #endif @@ -9255,7 +9255,7 @@ void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) { size_t chunk_at_end_old_size = chunk_at_end->size(); assert(chunk_at_end_old_size >= word_size_change, "Shrink is too large"); - chunk_at_end->setSize(chunk_at_end_old_size - + chunk_at_end->set_size(chunk_at_end_old_size - word_size_change); _cmsSpace->freed((HeapWord*) chunk_at_end->end(), word_size_change); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp index 70a11b7313d..582fe9e82fe 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp @@ -75,20 +75,20 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC { // calls. We really want the read of _mark and _prev from this pointer // to be volatile but making the fields volatile causes all sorts of // compilation errors. - return ((volatile FreeChunk*)addr)->isFree(); + return ((volatile FreeChunk*)addr)->is_free(); } - bool isFree() const volatile { + bool is_free() const volatile { LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else) return (((intptr_t)_prev) & 0x1) == 0x1; } bool cantCoalesce() const { - assert(isFree(), "can't get coalesce bit on not free"); + assert(is_free(), "can't get coalesce bit on not free"); return (((intptr_t)_prev) & 0x2) == 0x2; } void dontCoalesce() { // the block should be free - assert(isFree(), "Should look like a free block"); + assert(is_free(), "Should look like a free block"); _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2); } FreeChunk* prev() const { @@ -103,23 +103,23 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC { LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else ) return _size; } - void setSize(size_t sz) { + void set_size(size_t sz) { LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::set_size_and_free(sz)); else ) _size = sz; } FreeChunk* next() const { return _next; } - void linkAfter(FreeChunk* ptr) { - linkNext(ptr); - if (ptr != NULL) ptr->linkPrev(this); + void link_after(FreeChunk* ptr) { + link_next(ptr); + if (ptr != NULL) ptr->link_prev(this); } - void linkNext(FreeChunk* ptr) { _next = ptr; } - void linkPrev(FreeChunk* ptr) { + void link_next(FreeChunk* ptr) { _next = ptr; } + void link_prev(FreeChunk* ptr) { LP64_ONLY(if (UseCompressedOops) _prev = ptr; else) _prev = (FreeChunk*)((intptr_t)ptr | 0x1); } - void clearNext() { _next = NULL; } + void clear_next() { _next = NULL; } void markNotFree() { // Set _prev (klass) to null before (if) clearing the mark word below _prev = NULL; @@ -129,7 +129,7 @@ class FreeChunk VALUE_OBJ_CLASS_SPEC { set_mark(markOopDesc::prototype()); } #endif - assert(!isFree(), "Error"); + assert(!is_free(), "Error"); } // Return the address past the end of this chunk diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp index 6fa109a53b3..ffb119c1649 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp @@ -121,7 +121,7 @@ void PromotionInfo::track(PromotedObject* trackOop) { void PromotionInfo::track(PromotedObject* trackOop, klassOop klassOfOop) { // make a copy of header as it may need to be spooled markOop mark = oop(trackOop)->mark(); - trackOop->clearNext(); + trackOop->clear_next(); if (mark->must_be_preserved_for_cms_scavenge(klassOfOop)) { // save non-prototypical header, and mark oop saveDisplacedHeader(mark); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp index 463c33bb889..27a455fcc3f 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp @@ -43,7 +43,7 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC { // whose position will depend on endian-ness of the platform. // This is so that there is no interference with the // cms_free_bit occupying bit position 7 (lsb == 0) - // when we are using compressed oops; see FreeChunk::isFree(). + // when we are using compressed oops; see FreeChunk::is_free(). // We cannot move the cms_free_bit down because currently // biased locking code assumes that age bits are contiguous // with the lock bits. Even if that assumption were relaxed, @@ -65,7 +65,7 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC { }; public: inline PromotedObject* next() const { - assert(!((FreeChunk*)this)->isFree(), "Error"); + assert(!((FreeChunk*)this)->is_free(), "Error"); PromotedObject* res; if (UseCompressedOops) { // The next pointer is a compressed oop stored in the top 32 bits @@ -85,27 +85,27 @@ class PromotedObject VALUE_OBJ_CLASS_SPEC { } else { _next |= (intptr_t)x; } - assert(!((FreeChunk*)this)->isFree(), "Error"); + assert(!((FreeChunk*)this)->is_free(), "Error"); } inline void setPromotedMark() { _next |= promoted_mask; - assert(!((FreeChunk*)this)->isFree(), "Error"); + assert(!((FreeChunk*)this)->is_free(), "Error"); } inline bool hasPromotedMark() const { - assert(!((FreeChunk*)this)->isFree(), "Error"); + assert(!((FreeChunk*)this)->is_free(), "Error"); return (_next & promoted_mask) == promoted_mask; } inline void setDisplacedMark() { _next |= displaced_mark; - assert(!((FreeChunk*)this)->isFree(), "Error"); + assert(!((FreeChunk*)this)->is_free(), "Error"); } inline bool hasDisplacedMark() const { - assert(!((FreeChunk*)this)->isFree(), "Error"); + assert(!((FreeChunk*)this)->is_free(), "Error"); return (_next & displaced_mark) != 0; } - inline void clearNext() { + inline void clear_next() { _next = 0; - assert(!((FreeChunk*)this)->isFree(), "Error"); + assert(!((FreeChunk*)this)->is_free(), "Error"); } debug_only(void *next_addr() { return (void *) &_next; }) }; diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp index dc5de36685e..c64e0eb5f1c 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp @@ -46,7 +46,7 @@ nonstatic_field(LinearAllocBlock, _word_size, size_t) \ nonstatic_field(FreeList, _size, size_t) \ nonstatic_field(FreeList, _count, ssize_t) \ - nonstatic_field(BinaryTreeDictionary,_totalSize, size_t) \ + nonstatic_field(BinaryTreeDictionary,_total_size, size_t) \ nonstatic_field(CompactibleFreeListSpace, _dictionary, FreeBlockDictionary*) \ nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList) \ nonstatic_field(CompactibleFreeListSpace, _smallLinearAllocBlock, LinearAllocBlock) diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp index 1c945388ab3..46f25371cc2 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp @@ -39,7 +39,7 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { // We measure the demand between the end of the previous sweep and // beginning of this sweep: // Count(end_last_sweep) - Count(start_this_sweep) - // + splitBirths(between) - splitDeaths(between) + // + split_births(between) - split_deaths(between) // The above number divided by the time since the end of the // previous sweep gives us a time rate of demand for blocks // of this size. We compute a padded average of this rate as @@ -51,34 +51,34 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { AdaptivePaddedAverage _demand_rate_estimate; ssize_t _desired; // Demand stimate computed as described above - ssize_t _coalDesired; // desired +/- small-percent for tuning coalescing + ssize_t _coal_desired; // desired +/- small-percent for tuning coalescing ssize_t _surplus; // count - (desired +/- small-percent), // used to tune splitting in best fit - ssize_t _bfrSurp; // surplus at start of current sweep - ssize_t _prevSweep; // count from end of previous sweep - ssize_t _beforeSweep; // count from before current sweep - ssize_t _coalBirths; // additional chunks from coalescing - ssize_t _coalDeaths; // loss from coalescing - ssize_t _splitBirths; // additional chunks from splitting - ssize_t _splitDeaths; // loss from splitting - size_t _returnedBytes; // number of bytes returned to list. + ssize_t _bfr_surp; // surplus at start of current sweep + ssize_t _prev_sweep; // count from end of previous sweep + ssize_t _before_sweep; // count from before current sweep + ssize_t _coal_births; // additional chunks from coalescing + ssize_t _coal_deaths; // loss from coalescing + ssize_t _split_births; // additional chunks from splitting + ssize_t _split_deaths; // loss from splitting + size_t _returned_bytes; // number of bytes returned to list. public: void initialize(bool split_birth = false) { AdaptivePaddedAverage* dummy = new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight, CMS_FLSPadding); _desired = 0; - _coalDesired = 0; + _coal_desired = 0; _surplus = 0; - _bfrSurp = 0; - _prevSweep = 0; - _beforeSweep = 0; - _coalBirths = 0; - _coalDeaths = 0; - _splitBirths = (split_birth ? 1 : 0); - _splitDeaths = 0; - _returnedBytes = 0; + _bfr_surp = 0; + _prev_sweep = 0; + _before_sweep = 0; + _coal_births = 0; + _coal_deaths = 0; + _split_births = (split_birth ? 1 : 0); + _split_deaths = 0; + _returned_bytes = 0; } AllocationStats() { @@ -99,12 +99,12 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { // vulnerable to noisy glitches. In such cases, we // ignore the current sample and use currently available // historical estimates. - assert(prevSweep() + splitBirths() + coalBirths() // "Total Production Stock" - >= splitDeaths() + coalDeaths() + (ssize_t)count, // "Current stock + depletion" + assert(prev_sweep() + split_births() + coal_births() // "Total Production Stock" + >= split_deaths() + coal_deaths() + (ssize_t)count, // "Current stock + depletion" "Conservation Principle"); if (inter_sweep_current > _threshold) { - ssize_t demand = prevSweep() - (ssize_t)count + splitBirths() + coalBirths() - - splitDeaths() - coalDeaths(); + ssize_t demand = prev_sweep() - (ssize_t)count + split_births() + coal_births() + - split_deaths() - coal_deaths(); assert(demand >= 0, err_msg("Demand (" SSIZE_FORMAT ") should be non-negative for " PTR_FORMAT " (size=" SIZE_FORMAT ")", @@ -130,40 +130,40 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { ssize_t desired() const { return _desired; } void set_desired(ssize_t v) { _desired = v; } - ssize_t coalDesired() const { return _coalDesired; } - void set_coalDesired(ssize_t v) { _coalDesired = v; } + ssize_t coal_desired() const { return _coal_desired; } + void set_coal_desired(ssize_t v) { _coal_desired = v; } ssize_t surplus() const { return _surplus; } void set_surplus(ssize_t v) { _surplus = v; } void increment_surplus() { _surplus++; } void decrement_surplus() { _surplus--; } - ssize_t bfrSurp() const { return _bfrSurp; } - void set_bfrSurp(ssize_t v) { _bfrSurp = v; } - ssize_t prevSweep() const { return _prevSweep; } - void set_prevSweep(ssize_t v) { _prevSweep = v; } - ssize_t beforeSweep() const { return _beforeSweep; } - void set_beforeSweep(ssize_t v) { _beforeSweep = v; } + ssize_t bfr_surp() const { return _bfr_surp; } + void set_bfr_surp(ssize_t v) { _bfr_surp = v; } + ssize_t prev_sweep() const { return _prev_sweep; } + void set_prev_sweep(ssize_t v) { _prev_sweep = v; } + ssize_t before_sweep() const { return _before_sweep; } + void set_before_sweep(ssize_t v) { _before_sweep = v; } - ssize_t coalBirths() const { return _coalBirths; } - void set_coalBirths(ssize_t v) { _coalBirths = v; } - void increment_coalBirths() { _coalBirths++; } + ssize_t coal_births() const { return _coal_births; } + void set_coal_births(ssize_t v) { _coal_births = v; } + void increment_coal_births() { _coal_births++; } - ssize_t coalDeaths() const { return _coalDeaths; } - void set_coalDeaths(ssize_t v) { _coalDeaths = v; } - void increment_coalDeaths() { _coalDeaths++; } + ssize_t coal_deaths() const { return _coal_deaths; } + void set_coal_deaths(ssize_t v) { _coal_deaths = v; } + void increment_coal_deaths() { _coal_deaths++; } - ssize_t splitBirths() const { return _splitBirths; } - void set_splitBirths(ssize_t v) { _splitBirths = v; } - void increment_splitBirths() { _splitBirths++; } + ssize_t split_births() const { return _split_births; } + void set_split_births(ssize_t v) { _split_births = v; } + void increment_split_births() { _split_births++; } - ssize_t splitDeaths() const { return _splitDeaths; } - void set_splitDeaths(ssize_t v) { _splitDeaths = v; } - void increment_splitDeaths() { _splitDeaths++; } + ssize_t split_deaths() const { return _split_deaths; } + void set_split_deaths(ssize_t v) { _split_deaths = v; } + void increment_split_deaths() { _split_deaths++; } NOT_PRODUCT( - size_t returnedBytes() const { return _returnedBytes; } - void set_returnedBytes(size_t v) { _returnedBytes = v; } + size_t returned_bytes() const { return _returned_bytes; } + void set_returned_bytes(size_t v) { _returned_bytes = v; } ) }; diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index 98bd273ad8e..3f4a8a16ac5 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -44,7 +44,7 @@ TreeChunk* TreeChunk::as_TreeChunk(Chunk* fc) { } template -void TreeChunk::verifyTreeChunkList() const { +void TreeChunk::verify_tree_chunk_list() const { TreeChunk* nextTC = (TreeChunk*)next(); if (prev() != NULL) { // interior list node shouldn'r have tree fields guarantee(embedded_list()->parent() == NULL && embedded_list()->left() == NULL && @@ -53,7 +53,7 @@ void TreeChunk::verifyTreeChunkList() const { if (nextTC != NULL) { guarantee(as_TreeChunk(nextTC->prev()) == this, "broken chain"); guarantee(nextTC->size() == size(), "wrong size"); - nextTC->verifyTreeChunkList(); + nextTC->verify_tree_chunk_list(); } } @@ -73,9 +73,9 @@ TreeList* TreeList::as_TreeList(TreeChunk* tc) { tl->link_tail(tc); tl->set_count(1); tl->init_statistics(true /* split_birth */); - tl->setParent(NULL); - tl->setLeft(NULL); - tl->setRight(NULL); + tl->set_parent(NULL); + tl->set_left(NULL); + tl->set_right(NULL); return tl; } @@ -92,15 +92,15 @@ TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) { SpaceMangler::is_mangled((HeapWord*) tc->next_addr())) || (tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL), "Space should be clear or mangled"); - tc->setSize(size); - tc->linkPrev(NULL); - tc->linkNext(NULL); + tc->set_size(size); + tc->link_prev(NULL); + tc->link_next(NULL); TreeList* tl = TreeList::as_TreeList(tc); return tl; } template -TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) { +TreeList* TreeList::remove_chunk_replace_if_needed(TreeChunk* tc) { TreeList* retTL = this; Chunk* list = head(); @@ -108,7 +108,7 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* t assert(tc != NULL, "Chunk being removed is NULL"); assert(parent() == NULL || this == parent()->left() || this == parent()->right(), "list is inconsistent"); - assert(tc->isFree(), "Header is not marked correctly"); + assert(tc->is_free(), "Header is not marked correctly"); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); @@ -148,24 +148,24 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* t // Fix the parent to point to the new TreeList. if (retTL->parent() != NULL) { if (this == retTL->parent()->left()) { - retTL->parent()->setLeft(retTL); + retTL->parent()->set_left(retTL); } else { assert(this == retTL->parent()->right(), "Parent is incorrect"); - retTL->parent()->setRight(retTL); + retTL->parent()->set_right(retTL); } } // Fix the children's parent pointers to point to the // new list. assert(right() == retTL->right(), "Should have been copied"); if (retTL->right() != NULL) { - retTL->right()->setParent(retTL); + retTL->right()->set_parent(retTL); } assert(left() == retTL->left(), "Should have been copied"); if (retTL->left() != NULL) { - retTL->left()->setParent(retTL); + retTL->left()->set_parent(retTL); } retTL->link_head(nextTC); - assert(nextTC->isFree(), "Should be a free chunk"); + assert(nextTC->is_free(), "Should be a free chunk"); } } else { if (nextTC == NULL) { @@ -173,7 +173,7 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* t link_tail(prevFC); } // Chunk is interior to the list - prevFC->linkAfter(nextTC); + prevFC->link_after(nextTC); } // Below this point the embeded TreeList being used for the @@ -183,8 +183,8 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* t assert(!retTL->head() || retTL->size() == retTL->head()->size(), "Wrong sized chunk in list"); debug_only( - tc->linkPrev(NULL); - tc->linkNext(NULL); + tc->link_prev(NULL); + tc->link_next(NULL); tc->set_list(NULL); bool prev_found = false; bool next_found = false; @@ -207,7 +207,7 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* t ) retTL->decrement_count(); - assert(tc->isFree(), "Should still be a free chunk"); + assert(tc->is_free(), "Should still be a free chunk"); assert(retTL->head() == NULL || retTL->head()->prev() == NULL, "list invariant"); assert(retTL->tail() == NULL || retTL->tail()->next() == NULL, @@ -216,22 +216,22 @@ TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* t } template -void TreeList::returnChunkAtTail(TreeChunk* chunk) { +void TreeList::return_chunk_at_tail(TreeChunk* chunk) { assert(chunk != NULL, "returning NULL chunk"); assert(chunk->list() == this, "list should be set for chunk"); assert(tail() != NULL, "The tree list is embedded in the first chunk"); // which means that the list can never be empty. - assert(!verifyChunkInFreeLists(chunk), "Double entry"); + assert(!verify_chunk_in_free_list(chunk), "Double entry"); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); Chunk* fc = tail(); - fc->linkAfter(chunk); + fc->link_after(chunk); link_tail(chunk); assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list"); FreeList::increment_count(); - debug_only(increment_returnedBytes_by(chunk->size()*sizeof(HeapWord));) + debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));) assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); } @@ -241,25 +241,25 @@ void TreeList::returnChunkAtTail(TreeChunk* chunk) { // because the TreeList is embedded in the first TreeChunk in the // list. See the definition of TreeChunk. template -void TreeList::returnChunkAtHead(TreeChunk* chunk) { +void TreeList::return_chunk_at_head(TreeChunk* chunk) { assert(chunk->list() == this, "list should be set for chunk"); assert(head() != NULL, "The tree list is embedded in the first chunk"); assert(chunk != NULL, "returning NULL chunk"); - assert(!verifyChunkInFreeLists(chunk), "Double entry"); + assert(!verify_chunk_in_free_list(chunk), "Double entry"); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); Chunk* fc = head()->next(); if (fc != NULL) { - chunk->linkAfter(fc); + chunk->link_after(fc); } else { assert(tail() == NULL, "List is inconsistent"); link_tail(chunk); } - head()->linkAfter(chunk); + head()->link_after(chunk); assert(!head() || size() == head()->size(), "Wrong sized chunk in list"); FreeList::increment_count(); - debug_only(increment_returnedBytes_by(chunk->size()*sizeof(HeapWord));) + debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));) assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); } @@ -314,7 +314,7 @@ TreeChunk* TreeList::largest_address() { template BinaryTreeDictionary::BinaryTreeDictionary(bool adaptive_freelists, bool splay) : _splay(splay), _adaptive_freelists(adaptive_freelists), - _totalSize(0), _totalFreeBlocks(0), _root(0) {} + _total_size(0), _total_free_blocks(0), _root(0) {} template BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, @@ -329,26 +329,26 @@ BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, assert(root()->right() == NULL, "reset check failed"); assert(root()->head()->next() == NULL, "reset check failed"); assert(root()->head()->prev() == NULL, "reset check failed"); - assert(totalSize() == root()->size(), "reset check failed"); - assert(totalFreeBlocks() == 1, "reset check failed"); + assert(total_size() == root()->size(), "reset check failed"); + assert(total_free_blocks() == 1, "reset check failed"); } template -void BinaryTreeDictionary::inc_totalSize(size_t inc) { - _totalSize = _totalSize + inc; +void BinaryTreeDictionary::inc_total_size(size_t inc) { + _total_size = _total_size + inc; } template -void BinaryTreeDictionary::dec_totalSize(size_t dec) { - _totalSize = _totalSize - dec; +void BinaryTreeDictionary::dec_total_size(size_t dec) { + _total_size = _total_size - dec; } template void BinaryTreeDictionary::reset(MemRegion mr) { assert(mr.word_size() >= BinaryTreeDictionary::min_tree_chunk_size, "minimum chunk size"); set_root(TreeList::as_TreeList(mr.start(), mr.word_size())); - set_totalSize(mr.word_size()); - set_totalFreeBlocks(1); + set_total_size(mr.word_size()); + set_total_free_blocks(1); } template @@ -360,8 +360,8 @@ void BinaryTreeDictionary::reset(HeapWord* addr, size_t byte_size) { template void BinaryTreeDictionary::reset() { set_root(NULL); - set_totalSize(0); - set_totalFreeBlocks(0); + set_total_size(0); + set_total_free_blocks(0); } // Get a free block of size at least size from tree, or NULL. @@ -374,13 +374,13 @@ void BinaryTreeDictionary::reset() { // node is replaced in place by its tree successor. template TreeChunk* -BinaryTreeDictionary::getChunkFromTree(size_t size, enum FreeBlockDictionary::Dither dither, bool splay) +BinaryTreeDictionary::get_chunk_from_tree(size_t size, enum FreeBlockDictionary::Dither dither, bool splay) { TreeList *curTL, *prevTL; TreeChunk* retTC = NULL; assert(size >= BinaryTreeDictionary::min_tree_chunk_size, "minimum chunk size"); if (FLSVerifyDictionary) { - verifyTree(); + verify_tree(); } // starting at the root, work downwards trying to find match. // Remember the last node of size too great or too small. @@ -421,7 +421,7 @@ BinaryTreeDictionary::getChunkFromTree(size_t size, enum FreeBlockDiction while (hintTL->hint() != 0) { assert(hintTL->hint() == 0 || hintTL->hint() > hintTL->size(), "hint points in the wrong direction"); - hintTL = findList(hintTL->hint()); + hintTL = find_list(hintTL->hint()); assert(curTL != hintTL, "Infinite loop"); if (hintTL == NULL || hintTL == curTL /* Should not happen but protect against it */ ) { @@ -448,15 +448,15 @@ BinaryTreeDictionary::getChunkFromTree(size_t size, enum FreeBlockDiction } // don't waste time splaying if chunk's singleton if (splay && curTL->head()->next() != NULL) { - semiSplayStep(curTL); + semi_splay_step(curTL); } retTC = curTL->first_available(); assert((retTC != NULL) && (curTL->count() > 0), "A list in the binary tree should not be NULL"); assert(retTC->size() >= size, "A chunk of the wrong size was found"); - removeChunkFromTree(retTC); - assert(retTC->isFree(), "Header is not marked correctly"); + remove_chunk_from_tree(retTC); + assert(retTC->is_free(), "Header is not marked correctly"); } if (FLSVerifyDictionary) { @@ -466,7 +466,7 @@ BinaryTreeDictionary::getChunkFromTree(size_t size, enum FreeBlockDiction } template -TreeList* BinaryTreeDictionary::findList(size_t size) const { +TreeList* BinaryTreeDictionary::find_list(size_t size) const { TreeList* curTL; for (curTL = root(); curTL != NULL;) { if (curTL->size() == size) { // exact match @@ -485,18 +485,18 @@ TreeList* BinaryTreeDictionary::findList(size_t size) const { template -bool BinaryTreeDictionary::verifyChunkInFreeLists(Chunk* tc) const { +bool BinaryTreeDictionary::verify_chunk_in_free_list(Chunk* tc) const { size_t size = tc->size(); - TreeList* tl = findList(size); + TreeList* tl = find_list(size); if (tl == NULL) { return false; } else { - return tl->verifyChunkInFreeLists(tc); + return tl->verify_chunk_in_free_list(tc); } } template -Chunk* BinaryTreeDictionary::findLargestDict() const { +Chunk* BinaryTreeDictionary::find_largest_dict() const { TreeList *curTL = root(); if (curTL != NULL) { while(curTL->right() != NULL) curTL = curTL->right(); @@ -512,9 +512,9 @@ Chunk* BinaryTreeDictionary::findLargestDict() const { // remove the node and repair the tree. template TreeChunk* -BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { +BinaryTreeDictionary::remove_chunk_from_tree(TreeChunk* tc) { assert(tc != NULL, "Should not call with a NULL chunk"); - assert(tc->isFree(), "Header is not marked correctly"); + assert(tc->is_free(), "Header is not marked correctly"); TreeList *newTL, *parentTL; TreeChunk* retTC; @@ -534,13 +534,13 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { assert(tl->parent() == NULL || tl == tl->parent()->left() || tl == tl->parent()->right(), "list is inconsistent"); - bool complicatedSplice = false; + bool complicated_splice = false; retTC = tc; // Removing this chunk can have the side effect of changing the node // (TreeList*) in the tree. If the node is the root, update it. - TreeList* replacementTL = tl->removeChunkReplaceIfNeeded(tc); - assert(tc->isFree(), "Chunk should still be free"); + TreeList* replacementTL = tl->remove_chunk_replace_if_needed(tc); + assert(tc->is_free(), "Chunk should still be free"); assert(replacementTL->parent() == NULL || replacementTL == replacementTL->parent()->left() || replacementTL == replacementTL->parent()->right(), @@ -570,15 +570,15 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { if (replacementTL->left() == NULL) { // left is NULL so pick right. right may also be NULL. newTL = replacementTL->right(); - debug_only(replacementTL->clearRight();) + debug_only(replacementTL->clear_right();) } else if (replacementTL->right() == NULL) { // right is NULL newTL = replacementTL->left(); debug_only(replacementTL->clearLeft();) } else { // we have both children, so, by patriarchal convention, // my replacement is least node in right sub-tree - complicatedSplice = true; - newTL = removeTreeMinimum(replacementTL->right()); + complicated_splice = true; + newTL = remove_tree_minimum(replacementTL->right()); assert(newTL != NULL && newTL->left() == NULL && newTL->right() == NULL, "sub-tree minimum exists"); } @@ -586,7 +586,7 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { // newTL may be NULL. // should verify; we just cleanly excised our replacement if (FLSVerifyDictionary) { - verifyTree(); + verify_tree(); } // first make newTL my parent's child if ((parentTL = replacementTL->parent()) == NULL) { @@ -594,35 +594,35 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { assert(tl == root(), "Incorrectly replacing root"); set_root(newTL); if (newTL != NULL) { - newTL->clearParent(); + newTL->clear_parent(); } } else if (parentTL->right() == replacementTL) { // replacementTL is a right child - parentTL->setRight(newTL); + parentTL->set_right(newTL); } else { // replacementTL is a left child assert(parentTL->left() == replacementTL, "should be left child"); - parentTL->setLeft(newTL); + parentTL->set_left(newTL); } - debug_only(replacementTL->clearParent();) - if (complicatedSplice) { // we need newTL to get replacementTL's + debug_only(replacementTL->clear_parent();) + if (complicated_splice) { // we need newTL to get replacementTL's // two children assert(newTL != NULL && newTL->left() == NULL && newTL->right() == NULL, "newTL should not have encumbrances from the past"); // we'd like to assert as below: // assert(replacementTL->left() != NULL && replacementTL->right() != NULL, - // "else !complicatedSplice"); + // "else !complicated_splice"); // ... however, the above assertion is too strong because we aren't // guaranteed that replacementTL->right() is still NULL. // Recall that we removed // the right sub-tree minimum from replacementTL. // That may well have been its right // child! So we'll just assert half of the above: - assert(replacementTL->left() != NULL, "else !complicatedSplice"); - newTL->setLeft(replacementTL->left()); - newTL->setRight(replacementTL->right()); + assert(replacementTL->left() != NULL, "else !complicated_splice"); + newTL->set_left(replacementTL->left()); + newTL->set_right(replacementTL->right()); debug_only( - replacementTL->clearRight(); + replacementTL->clear_right(); replacementTL->clearLeft(); ) } @@ -632,16 +632,16 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { "delete without encumbrances"); } - assert(totalSize() >= retTC->size(), "Incorrect total size"); - dec_totalSize(retTC->size()); // size book-keeping - assert(totalFreeBlocks() > 0, "Incorrect total count"); - set_totalFreeBlocks(totalFreeBlocks() - 1); + assert(total_size() >= retTC->size(), "Incorrect total size"); + dec_total_size(retTC->size()); // size book-keeping + assert(total_free_blocks() > 0, "Incorrect total count"); + set_total_free_blocks(total_free_blocks() - 1); assert(retTC != NULL, "null chunk?"); assert(retTC->prev() == NULL && retTC->next() == NULL, "should return without encumbrances"); if (FLSVerifyDictionary) { - verifyTree(); + verify_tree(); } assert(!removing_only_chunk || _root == NULL, "root should be NULL"); return TreeChunk::as_TreeChunk(retTC); @@ -651,7 +651,7 @@ BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) { // If lm has a right child, link it to the left node of // the parent of lm. template -TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* tl) { +TreeList* BinaryTreeDictionary::remove_tree_minimum(TreeList* tl) { assert(tl != NULL && tl->parent() != NULL, "really need a proper sub-tree"); // locate the subtree minimum by walking down left branches TreeList* curTL = tl; @@ -660,12 +660,12 @@ TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* if (curTL != root()) { // Should this test just be removed? TreeList* parentTL = curTL->parent(); if (parentTL->left() == curTL) { // curTL is a left child - parentTL->setLeft(curTL->right()); + parentTL->set_left(curTL->right()); } else { // If the list tl has no left child, then curTL may be // the right child of parentTL. assert(parentTL->right() == curTL, "should be a right child"); - parentTL->setRight(curTL->right()); + parentTL->set_right(curTL->right()); } } else { // The only use of this method would not pass the root of the @@ -675,12 +675,12 @@ TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* set_root(NULL); } debug_only( - curTL->clearParent(); // Test if this needs to be cleared - curTL->clearRight(); // recall, above, left child is already null + curTL->clear_parent(); // Test if this needs to be cleared + curTL->clear_right(); // recall, above, left child is already null ) // we just excised a (non-root) node, we should still verify all tree invariants if (FLSVerifyDictionary) { - verifyTree(); + verify_tree(); } return curTL; } @@ -694,7 +694,7 @@ TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* // [Measurements will be needed to (in)validate this expectation.] template -void BinaryTreeDictionary::semiSplayStep(TreeList* tc) { +void BinaryTreeDictionary::semi_splay_step(TreeList* tc) { // apply a semi-splay step at the given node: // . if root, norting needs to be done // . if child of root, splay once @@ -705,17 +705,17 @@ void BinaryTreeDictionary::semiSplayStep(TreeList* tc) { } template -void BinaryTreeDictionary::insertChunkInTree(Chunk* fc) { +void BinaryTreeDictionary::insert_chunk_in_tree(Chunk* fc) { TreeList *curTL, *prevTL; size_t size = fc->size(); assert(size >= BinaryTreeDictionary::min_tree_chunk_size, "too small to be a TreeList"); if (FLSVerifyDictionary) { - verifyTree(); + verify_tree(); } - fc->clearNext(); - fc->linkPrev(NULL); + fc->clear_next(); + fc->link_prev(NULL); // work down from the _root, looking for insertion point for (prevTL = curTL = root(); curTL != NULL;) { @@ -735,10 +735,10 @@ void BinaryTreeDictionary::insertChunkInTree(Chunk* fc) { tc->initialize(); if (curTL != NULL) { // exact match tc->set_list(curTL); - curTL->returnChunkAtTail(tc); + curTL->return_chunk_at_tail(tc); } else { // need a new node in tree - tc->clearNext(); - tc->linkPrev(NULL); + tc->clear_next(); + tc->link_prev(NULL); TreeList* newTL = TreeList::as_TreeList(tc); assert(((TreeChunk*)tc)->list() == newTL, "List was not initialized correctly"); @@ -748,28 +748,28 @@ void BinaryTreeDictionary::insertChunkInTree(Chunk* fc) { } else { // insert under prevTL ... if (prevTL->size() < size) { // am right child assert(prevTL->right() == NULL, "control point invariant"); - prevTL->setRight(newTL); + prevTL->set_right(newTL); } else { // am left child assert(prevTL->size() > size && prevTL->left() == NULL, "cpt pt inv"); - prevTL->setLeft(newTL); + prevTL->set_left(newTL); } } } assert(tc->list() != NULL, "Tree list should be set"); - inc_totalSize(size); - // Method 'totalSizeInTree' walks through the every block in the + inc_total_size(size); + // Method 'total_size_in_tree' walks through the every block in the // tree, so it can cause significant performance loss if there are // many blocks in the tree - assert(!FLSVerifyDictionary || totalSizeInTree(root()) == totalSize(), "_totalSize inconsistency"); - set_totalFreeBlocks(totalFreeBlocks() + 1); + assert(!FLSVerifyDictionary || total_size_in_tree(root()) == total_size(), "_total_size inconsistency"); + set_total_free_blocks(total_free_blocks() + 1); if (FLSVerifyDictionary) { - verifyTree(); + verify_tree(); } } template -size_t BinaryTreeDictionary::maxChunkSize() const { +size_t BinaryTreeDictionary::max_chunk_size() const { FreeBlockDictionary::verify_par_locked(); TreeList* tc = root(); if (tc == NULL) return 0; @@ -778,7 +778,7 @@ size_t BinaryTreeDictionary::maxChunkSize() const { } template -size_t BinaryTreeDictionary::totalListLength(TreeList* tl) const { +size_t BinaryTreeDictionary::total_list_length(TreeList* tl) const { size_t res; res = tl->count(); #ifdef ASSERT @@ -791,12 +791,12 @@ size_t BinaryTreeDictionary::totalListLength(TreeList* tl) const { } template -size_t BinaryTreeDictionary::totalSizeInTree(TreeList* tl) const { +size_t BinaryTreeDictionary::total_size_in_tree(TreeList* tl) const { if (tl == NULL) return 0; - return (tl->size() * totalListLength(tl)) + - totalSizeInTree(tl->left()) + - totalSizeInTree(tl->right()); + return (tl->size() * total_list_length(tl)) + + total_size_in_tree(tl->left()) + + total_size_in_tree(tl->right()); } template @@ -805,73 +805,73 @@ double BinaryTreeDictionary::sum_of_squared_block_sizes(TreeList* return 0.0; } double size = (double)(tl->size()); - double curr = size * size * totalListLength(tl); + double curr = size * size * total_list_length(tl); curr += sum_of_squared_block_sizes(tl->left()); curr += sum_of_squared_block_sizes(tl->right()); return curr; } template -size_t BinaryTreeDictionary::totalFreeBlocksInTree(TreeList* tl) const { +size_t BinaryTreeDictionary::total_free_blocks_in_tree(TreeList* tl) const { if (tl == NULL) return 0; - return totalListLength(tl) + - totalFreeBlocksInTree(tl->left()) + - totalFreeBlocksInTree(tl->right()); + return total_list_length(tl) + + total_free_blocks_in_tree(tl->left()) + + total_free_blocks_in_tree(tl->right()); } template -size_t BinaryTreeDictionary::numFreeBlocks() const { - assert(totalFreeBlocksInTree(root()) == totalFreeBlocks(), - "_totalFreeBlocks inconsistency"); - return totalFreeBlocks(); +size_t BinaryTreeDictionary::num_free_blocks() const { + assert(total_free_blocks_in_tree(root()) == total_free_blocks(), + "_total_free_blocks inconsistency"); + return total_free_blocks(); } template -size_t BinaryTreeDictionary::treeHeightHelper(TreeList* tl) const { +size_t BinaryTreeDictionary::tree_height_helper(TreeList* tl) const { if (tl == NULL) return 0; - return 1 + MAX2(treeHeightHelper(tl->left()), - treeHeightHelper(tl->right())); + return 1 + MAX2(tree_height_helper(tl->left()), + tree_height_helper(tl->right())); } template size_t BinaryTreeDictionary::treeHeight() const { - return treeHeightHelper(root()); + return tree_height_helper(root()); } template -size_t BinaryTreeDictionary::totalNodesHelper(TreeList* tl) const { +size_t BinaryTreeDictionary::total_nodes_helper(TreeList* tl) const { if (tl == NULL) { return 0; } - return 1 + totalNodesHelper(tl->left()) + - totalNodesHelper(tl->right()); + return 1 + total_nodes_helper(tl->left()) + + total_nodes_helper(tl->right()); } template -size_t BinaryTreeDictionary::totalNodesInTree(TreeList* tl) const { - return totalNodesHelper(root()); +size_t BinaryTreeDictionary::total_nodes_in_tree(TreeList* tl) const { + return total_nodes_helper(root()); } template -void BinaryTreeDictionary::dictCensusUpdate(size_t size, bool split, bool birth){ - TreeList* nd = findList(size); +void BinaryTreeDictionary::dict_census_udpate(size_t size, bool split, bool birth){ + TreeList* nd = find_list(size); if (nd) { if (split) { if (birth) { - nd->increment_splitBirths(); + nd->increment_split_births(); nd->increment_surplus(); } else { - nd->increment_splitDeaths(); + nd->increment_split_deaths(); nd->decrement_surplus(); } } else { if (birth) { - nd->increment_coalBirths(); + nd->increment_coal_births(); nd->increment_surplus(); } else { - nd->increment_coalDeaths(); + nd->increment_coal_deaths(); nd->decrement_surplus(); } } @@ -884,13 +884,13 @@ void BinaryTreeDictionary::dictCensusUpdate(size_t size, bool split, bool } template -bool BinaryTreeDictionary::coalDictOverPopulated(size_t size) { +bool BinaryTreeDictionary::coal_dict_over_populated(size_t size) { if (FLSAlwaysCoalesceLarge) return true; - TreeList* list_of_size = findList(size); + TreeList* list_of_size = find_list(size); // None of requested size implies overpopulated. - return list_of_size == NULL || list_of_size->coalDesired() <= 0 || - list_of_size->count() > list_of_size->coalDesired(); + return list_of_size == NULL || list_of_size->coal_desired() <= 0 || + list_of_size->count() > list_of_size->coal_desired(); } // Closures for walking the binary tree. @@ -952,9 +952,9 @@ class BeginSweepClosure : public AscendTreeCensusClosure { void do_list(FreeList* fl) { double coalSurplusPercent = _percentage; fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate); - fl->set_coalDesired((ssize_t)((double)fl->desired() * coalSurplusPercent)); - fl->set_beforeSweep(fl->count()); - fl->set_bfrSurp(fl->surplus()); + fl->set_coal_desired((ssize_t)((double)fl->desired() * coalSurplusPercent)); + fl->set_before_sweep(fl->count()); + fl->set_bfr_surp(fl->surplus()); } }; @@ -1031,7 +1031,7 @@ Chunk* BinaryTreeDictionary::find_chunk_ends_at(HeapWord* target) const { } template -void BinaryTreeDictionary::beginSweepDictCensus(double coalSurplusPercent, +void BinaryTreeDictionary::begin_sweep_dict_census(double coalSurplusPercent, float inter_sweep_current, float inter_sweep_estimate, float intra_sweep_estimate) { BeginSweepClosure bsc(coalSurplusPercent, inter_sweep_current, inter_sweep_estimate, @@ -1046,33 +1046,33 @@ template class InitializeDictReturnedBytesClosure : public AscendTreeCensusClosure { public: void do_list(FreeList* fl) { - fl->set_returnedBytes(0); + fl->set_returned_bytes(0); } }; template -void BinaryTreeDictionary::initializeDictReturnedBytes() { +void BinaryTreeDictionary::initialize_dict_returned_bytes() { InitializeDictReturnedBytesClosure idrb; idrb.do_tree(root()); } template class ReturnedBytesClosure : public AscendTreeCensusClosure { - size_t _dictReturnedBytes; + size_t _dict_returned_bytes; public: - ReturnedBytesClosure() { _dictReturnedBytes = 0; } + ReturnedBytesClosure() { _dict_returned_bytes = 0; } void do_list(FreeList* fl) { - _dictReturnedBytes += fl->returnedBytes(); + _dict_returned_bytes += fl->returned_bytes(); } - size_t dictReturnedBytes() { return _dictReturnedBytes; } + size_t dict_returned_bytes() { return _dict_returned_bytes; } }; template -size_t BinaryTreeDictionary::sumDictReturnedBytes() { +size_t BinaryTreeDictionary::sum_dict_returned_bytes() { ReturnedBytesClosure rbc; rbc.do_tree(root()); - return rbc.dictReturnedBytes(); + return rbc.dict_returned_bytes(); } // Count the number of entries in the tree. @@ -1087,7 +1087,7 @@ class treeCountClosure : public DescendTreeCensusClosure { }; template -size_t BinaryTreeDictionary::totalCount() { +size_t BinaryTreeDictionary::total_count() { treeCountClosure ctc(0); ctc.do_tree(root()); return ctc.count; @@ -1108,7 +1108,7 @@ class setTreeSurplusClosure : public AscendTreeCensusClosure { }; template -void BinaryTreeDictionary::setTreeSurplus(double splitSurplusPercent) { +void BinaryTreeDictionary::set_tree_surplus(double splitSurplusPercent) { setTreeSurplusClosure sts(splitSurplusPercent); sts.do_tree(root()); } @@ -1130,7 +1130,7 @@ class setTreeHintsClosure : public DescendTreeCensusClosure { }; template -void BinaryTreeDictionary::setTreeHints(void) { +void BinaryTreeDictionary::set_tree_hints(void) { setTreeHintsClosure sth(0); sth.do_tree(root()); } @@ -1139,45 +1139,45 @@ void BinaryTreeDictionary::setTreeHints(void) { template class clearTreeCensusClosure : public AscendTreeCensusClosure { void do_list(FreeList* fl) { - fl->set_prevSweep(fl->count()); - fl->set_coalBirths(0); - fl->set_coalDeaths(0); - fl->set_splitBirths(0); - fl->set_splitDeaths(0); + fl->set_prev_sweep(fl->count()); + fl->set_coal_births(0); + fl->set_coal_deaths(0); + fl->set_split_births(0); + fl->set_split_deaths(0); } }; template -void BinaryTreeDictionary::clearTreeCensus(void) { +void BinaryTreeDictionary::clear_tree_census(void) { clearTreeCensusClosure ctc; ctc.do_tree(root()); } // Do reporting and post sweep clean up. template -void BinaryTreeDictionary::endSweepDictCensus(double splitSurplusPercent) { +void BinaryTreeDictionary::end_sweep_dict_census(double splitSurplusPercent) { // Does walking the tree 3 times hurt? - setTreeSurplus(splitSurplusPercent); - setTreeHints(); + set_tree_surplus(splitSurplusPercent); + set_tree_hints(); if (PrintGC && Verbose) { - reportStatistics(); + report_statistics(); } - clearTreeCensus(); + clear_tree_census(); } // Print summary statistics template -void BinaryTreeDictionary::reportStatistics() const { +void BinaryTreeDictionary::report_statistics() const { FreeBlockDictionary::verify_par_locked(); gclog_or_tty->print("Statistics for BinaryTreeDictionary:\n" "------------------------------------\n"); - size_t totalSize = totalChunkSize(debug_only(NULL)); - size_t freeBlocks = numFreeBlocks(); - gclog_or_tty->print("Total Free Space: %d\n", totalSize); - gclog_or_tty->print("Max Chunk Size: %d\n", maxChunkSize()); - gclog_or_tty->print("Number of Blocks: %d\n", freeBlocks); - if (freeBlocks > 0) { - gclog_or_tty->print("Av. Block Size: %d\n", totalSize/freeBlocks); + size_t total_size = total_chunk_size(debug_only(NULL)); + size_t free_blocks = num_free_blocks(); + gclog_or_tty->print("Total Free Space: %d\n", total_size); + gclog_or_tty->print("Max Chunk Size: %d\n", max_chunk_size()); + gclog_or_tty->print("Number of Blocks: %d\n", free_blocks); + if (free_blocks > 0) { + gclog_or_tty->print("Av. Block Size: %d\n", total_size/free_blocks); } gclog_or_tty->print("Tree Height: %d\n", treeHeight()); } @@ -1188,38 +1188,38 @@ void BinaryTreeDictionary::reportStatistics() const { template class PrintTreeCensusClosure : public AscendTreeCensusClosure { int _print_line; - size_t _totalFree; + size_t _total_free; FreeList _total; public: PrintTreeCensusClosure() { _print_line = 0; - _totalFree = 0; + _total_free = 0; } FreeList* total() { return &_total; } - size_t totalFree() { return _totalFree; } + size_t total_free() { return _total_free; } void do_list(FreeList* fl) { if (++_print_line >= 40) { FreeList::print_labels_on(gclog_or_tty, "size"); _print_line = 0; } fl->print_on(gclog_or_tty); - _totalFree += fl->count() * fl->size() ; + _total_free += fl->count() * fl->size() ; total()->set_count( total()->count() + fl->count() ); - total()->set_bfrSurp( total()->bfrSurp() + fl->bfrSurp() ); - total()->set_surplus( total()->splitDeaths() + fl->surplus() ); + total()->set_bfr_surp( total()->bfr_surp() + fl->bfr_surp() ); + total()->set_surplus( total()->split_deaths() + fl->surplus() ); total()->set_desired( total()->desired() + fl->desired() ); - total()->set_prevSweep( total()->prevSweep() + fl->prevSweep() ); - total()->set_beforeSweep(total()->beforeSweep() + fl->beforeSweep()); - total()->set_coalBirths( total()->coalBirths() + fl->coalBirths() ); - total()->set_coalDeaths( total()->coalDeaths() + fl->coalDeaths() ); - total()->set_splitBirths(total()->splitBirths() + fl->splitBirths()); - total()->set_splitDeaths(total()->splitDeaths() + fl->splitDeaths()); + total()->set_prev_sweep( total()->prev_sweep() + fl->prev_sweep() ); + total()->set_before_sweep(total()->before_sweep() + fl->before_sweep()); + total()->set_coal_births( total()->coal_births() + fl->coal_births() ); + total()->set_coal_deaths( total()->coal_deaths() + fl->coal_deaths() ); + total()->set_split_births(total()->split_births() + fl->split_births()); + total()->set_split_deaths(total()->split_deaths() + fl->split_deaths()); } }; template -void BinaryTreeDictionary::printDictCensus(void) const { +void BinaryTreeDictionary::print_dict_census(void) const { gclog_or_tty->print("\nBinaryTree\n"); FreeList::print_labels_on(gclog_or_tty, "size"); @@ -1230,12 +1230,12 @@ void BinaryTreeDictionary::printDictCensus(void) const { FreeList::print_labels_on(gclog_or_tty, " "); total->print_on(gclog_or_tty, "TOTAL\t"); gclog_or_tty->print( - "totalFree(words): " SIZE_FORMAT_W(16) + "total_free(words): " SIZE_FORMAT_W(16) " growth: %8.5f deficit: %8.5f\n", - ptc.totalFree(), - (double)(total->splitBirths() + total->coalBirths() - - total->splitDeaths() - total->coalDeaths()) - /(total->prevSweep() != 0 ? (double)total->prevSweep() : 1.0), + ptc.total_free(), + (double)(total->split_births() + total->coal_births() + - total->split_deaths() - total->coal_deaths()) + /(total->prev_sweep() != 0 ? (double)total->prev_sweep() : 1.0), (double)(total->desired() - total->count()) /(total->desired() != 0 ? (double)total->desired() : 1.0)); } @@ -1279,19 +1279,19 @@ void BinaryTreeDictionary::print_free_lists(outputStream* st) const { // . parent and child point to each other // . each node's key correctly related to that of its child(ren) template -void BinaryTreeDictionary::verifyTree() const { - guarantee(root() == NULL || totalFreeBlocks() == 0 || - totalSize() != 0, "_totalSize should't be 0?"); +void BinaryTreeDictionary::verify_tree() const { + guarantee(root() == NULL || total_free_blocks() == 0 || + total_size() != 0, "_total_size should't be 0?"); guarantee(root() == NULL || root()->parent() == NULL, "_root shouldn't have parent"); - verifyTreeHelper(root()); + verify_tree_helper(root()); } template -size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) { +size_t BinaryTreeDictionary::verify_prev_free_ptrs(TreeList* tl) { size_t ct = 0; for (Chunk* curFC = tl->head(); curFC != NULL; curFC = curFC->next()) { ct++; - assert(curFC->prev() == NULL || curFC->prev()->isFree(), + assert(curFC->prev() == NULL || curFC->prev()->is_free(), "Chunk should be free"); } return ct; @@ -1301,7 +1301,7 @@ size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) { // caution on very deep trees; and watch out for stack overflow errors; // In general, to be used only for debugging. template -void BinaryTreeDictionary::verifyTreeHelper(TreeList* tl) const { +void BinaryTreeDictionary::verify_tree_helper(TreeList* tl) const { if (tl == NULL) return; guarantee(tl->size() != 0, "A list must has a size"); @@ -1313,26 +1313,26 @@ void BinaryTreeDictionary::verifyTreeHelper(TreeList* tl) const { "parent !> left"); guarantee(tl->right() == NULL || tl->right()->size() > tl->size(), "parent !< left"); - guarantee(tl->head() == NULL || tl->head()->isFree(), "!Free"); + guarantee(tl->head() == NULL || tl->head()->is_free(), "!Free"); guarantee(tl->head() == NULL || tl->head_as_TreeChunk()->list() == tl, "list inconsistency"); guarantee(tl->count() > 0 || (tl->head() == NULL && tl->tail() == NULL), "list count is inconsistent"); guarantee(tl->count() > 1 || tl->head() == tl->tail(), "list is incorrectly constructed"); - size_t count = verifyPrevFreePtrs(tl); + size_t count = verify_prev_free_ptrs(tl); guarantee(count == (size_t)tl->count(), "Node count is incorrect"); if (tl->head() != NULL) { - tl->head_as_TreeChunk()->verifyTreeChunkList(); + tl->head_as_TreeChunk()->verify_tree_chunk_list(); } - verifyTreeHelper(tl->left()); - verifyTreeHelper(tl->right()); + verify_tree_helper(tl->left()); + verify_tree_helper(tl->right()); } template void BinaryTreeDictionary::verify() const { - verifyTree(); - guarantee(totalSize() == totalSizeInTree(root()), "Total Size inconsistency"); + verify_tree(); + guarantee(total_size() == total_size_in_tree(root()), "Total Size inconsistency"); } #ifndef SERIALGC diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp index 8de138f085d..6d25852cb3e 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp @@ -70,22 +70,22 @@ class TreeList: public FreeList { // Accessors for links in tree. - void setLeft(TreeList* tl) { + void set_left(TreeList* tl) { _left = tl; if (tl != NULL) - tl->setParent(this); + tl->set_parent(this); } - void setRight(TreeList* tl) { + void set_right(TreeList* tl) { _right = tl; if (tl != NULL) - tl->setParent(this); + tl->set_parent(this); } - void setParent(TreeList* tl) { _parent = tl; } + void set_parent(TreeList* tl) { _parent = tl; } void clearLeft() { _left = NULL; } - void clearRight() { _right = NULL; } - void clearParent() { _parent = NULL; } - void initialize() { clearLeft(); clearRight(), clearParent(); } + void clear_right() { _right = NULL; } + void clear_parent() { _parent = NULL; } + void initialize() { clearLeft(); clear_right(), clear_parent(); } // For constructing a TreeList from a Tree chunk or // address and size. @@ -104,16 +104,16 @@ class TreeList: public FreeList { // use with caution! TreeChunk* largest_address(); - // removeChunkReplaceIfNeeded() removes the given "tc" from the TreeList. + // remove_chunk_replace_if_needed() removes the given "tc" from the TreeList. // If "tc" is the first chunk in the list, it is also the - // TreeList that is the node in the tree. removeChunkReplaceIfNeeded() + // TreeList that is the node in the tree. remove_chunk_replace_if_needed() // returns the possibly replaced TreeList* for the node in // the tree. It also updates the parent of the original // node to point to the new node. - TreeList* removeChunkReplaceIfNeeded(TreeChunk* tc); + TreeList* remove_chunk_replace_if_needed(TreeChunk* tc); // See FreeList. - void returnChunkAtHead(TreeChunk* tc); - void returnChunkAtTail(TreeChunk* tc); + void return_chunk_at_head(TreeChunk* tc); + void return_chunk_at_tail(TreeChunk* tc); }; // A TreeChunk is a subclass of a Chunk that additionally @@ -151,7 +151,7 @@ class TreeChunk : public Chunk { size_t size() const volatile { return Chunk::size(); } // debugging - void verifyTreeChunkList() const; + void verify_tree_chunk_list() const; }; @@ -159,19 +159,19 @@ template class BinaryTreeDictionary: public FreeBlockDictionary { friend class VMStructs; bool _splay; - size_t _totalSize; - size_t _totalFreeBlocks; + size_t _total_size; + size_t _total_free_blocks; TreeList* _root; bool _adaptive_freelists; // private accessors bool splay() const { return _splay; } void set_splay(bool v) { _splay = v; } - void set_totalSize(size_t v) { _totalSize = v; } - virtual void inc_totalSize(size_t v); - virtual void dec_totalSize(size_t v); - size_t totalFreeBlocks() const { return _totalFreeBlocks; } - void set_totalFreeBlocks(size_t v) { _totalFreeBlocks = v; } + void set_total_size(size_t v) { _total_size = v; } + virtual void inc_total_size(size_t v); + virtual void dec_total_size(size_t v); + size_t total_free_blocks() const { return _total_free_blocks; } + void set_total_free_blocks(size_t v) { _total_free_blocks = v; } TreeList* root() const { return _root; } void set_root(TreeList* v) { _root = v; } bool adaptive_freelists() { return _adaptive_freelists; } @@ -186,46 +186,46 @@ class BinaryTreeDictionary: public FreeBlockDictionary { // return it. If the chunk // is the last chunk of that size, remove the node for that size // from the tree. - TreeChunk* getChunkFromTree(size_t size, enum FreeBlockDictionary::Dither dither, bool splay); + TreeChunk* get_chunk_from_tree(size_t size, enum FreeBlockDictionary::Dither dither, bool splay); // Return a list of the specified size or NULL from the tree. // The list is not removed from the tree. - TreeList* findList (size_t size) const; + TreeList* find_list (size_t size) const; // Remove this chunk from the tree. If the removal results // in an empty list in the tree, remove the empty list. - TreeChunk* removeChunkFromTree(TreeChunk* tc); + TreeChunk* remove_chunk_from_tree(TreeChunk* tc); // Remove the node in the trees starting at tl that has the // minimum value and return it. Repair the tree as needed. - TreeList* removeTreeMinimum(TreeList* tl); - void semiSplayStep(TreeList* tl); + TreeList* remove_tree_minimum(TreeList* tl); + void semi_splay_step(TreeList* tl); // Add this free chunk to the tree. - void insertChunkInTree(Chunk* freeChunk); + void insert_chunk_in_tree(Chunk* freeChunk); public: static const size_t min_tree_chunk_size = sizeof(TreeChunk)/HeapWordSize; - void verifyTree() const; + void verify_tree() const; // verify that the given chunk is in the tree. - bool verifyChunkInFreeLists(Chunk* tc) const; + bool verify_chunk_in_free_list(Chunk* tc) const; private: - void verifyTreeHelper(TreeList* tl) const; - static size_t verifyPrevFreePtrs(TreeList* tl); + void verify_tree_helper(TreeList* tl) const; + static size_t verify_prev_free_ptrs(TreeList* tl); // Returns the total number of chunks in the list. - size_t totalListLength(TreeList* tl) const; + size_t total_list_length(TreeList* tl) const; // Returns the total number of words in the chunks in the tree // starting at "tl". - size_t totalSizeInTree(TreeList* tl) const; + size_t total_size_in_tree(TreeList* tl) const; // Returns the sum of the square of the size of each block // in the tree starting at "tl". double sum_of_squared_block_sizes(TreeList* const tl) const; // Returns the total number of free blocks in the tree starting // at "tl". - size_t totalFreeBlocksInTree(TreeList* tl) const; - size_t numFreeBlocks() const; + size_t total_free_blocks_in_tree(TreeList* tl) const; + size_t num_free_blocks() const; size_t treeHeight() const; - size_t treeHeightHelper(TreeList* tl) const; - size_t totalNodesInTree(TreeList* tl) const; - size_t totalNodesHelper(TreeList* tl) const; + size_t tree_height_helper(TreeList* tl) const; + size_t total_nodes_in_tree(TreeList* tl) const; + size_t total_nodes_helper(TreeList* tl) const; public: // Constructor @@ -233,7 +233,7 @@ class BinaryTreeDictionary: public FreeBlockDictionary { BinaryTreeDictionary(MemRegion mr, bool adaptive_freelists, bool splay = false); // Public accessors - size_t totalSize() const { return _totalSize; } + size_t total_size() const { return _total_size; } // Reset the dictionary to the initial conditions with // a single free chunk. @@ -245,37 +245,37 @@ class BinaryTreeDictionary: public FreeBlockDictionary { // Return a chunk of size "size" or greater from // the tree. // want a better dynamic splay strategy for the future. - Chunk* getChunk(size_t size, enum FreeBlockDictionary::Dither dither) { + Chunk* get_chunk(size_t size, enum FreeBlockDictionary::Dither dither) { FreeBlockDictionary::verify_par_locked(); - Chunk* res = getChunkFromTree(size, dither, splay()); - assert(res == NULL || res->isFree(), + Chunk* res = get_chunk_from_tree(size, dither, splay()); + assert(res == NULL || res->is_free(), "Should be returning a free chunk"); return res; } - void returnChunk(Chunk* chunk) { + void return_chunk(Chunk* chunk) { FreeBlockDictionary::verify_par_locked(); - insertChunkInTree(chunk); + insert_chunk_in_tree(chunk); } - void removeChunk(Chunk* chunk) { + void remove_chunk(Chunk* chunk) { FreeBlockDictionary::verify_par_locked(); - removeChunkFromTree((TreeChunk*)chunk); - assert(chunk->isFree(), "Should still be a free chunk"); + remove_chunk_from_tree((TreeChunk*)chunk); + assert(chunk->is_free(), "Should still be a free chunk"); } - size_t maxChunkSize() const; - size_t totalChunkSize(debug_only(const Mutex* lock)) const { + size_t max_chunk_size() const; + size_t total_chunk_size(debug_only(const Mutex* lock)) const { debug_only( if (lock != NULL && lock->owned_by_self()) { - assert(totalSizeInTree(root()) == totalSize(), - "_totalSize inconsistency"); + assert(total_size_in_tree(root()) == total_size(), + "_total_size inconsistency"); } ) - return totalSize(); + return total_size(); } - size_t minSize() const { + size_t min_size() const { return min_tree_chunk_size; } @@ -288,40 +288,40 @@ class BinaryTreeDictionary: public FreeBlockDictionary { // Find the list with size "size" in the binary tree and update // the statistics in the list according to "split" (chunk was // split or coalesce) and "birth" (chunk was added or removed). - void dictCensusUpdate(size_t size, bool split, bool birth); + void dict_census_udpate(size_t size, bool split, bool birth); // Return true if the dictionary is overpopulated (more chunks of // this size than desired) for size "size". - bool coalDictOverPopulated(size_t size); + bool coal_dict_over_populated(size_t size); // Methods called at the beginning of a sweep to prepare the // statistics for the sweep. - void beginSweepDictCensus(double coalSurplusPercent, + void begin_sweep_dict_census(double coalSurplusPercent, float inter_sweep_current, float inter_sweep_estimate, float intra_sweep_estimate); // Methods called after the end of a sweep to modify the // statistics for the sweep. - void endSweepDictCensus(double splitSurplusPercent); + void end_sweep_dict_census(double splitSurplusPercent); // Return the largest free chunk in the tree. - Chunk* findLargestDict() const; + Chunk* find_largest_dict() const; // Accessors for statistics - void setTreeSurplus(double splitSurplusPercent); - void setTreeHints(void); + void set_tree_surplus(double splitSurplusPercent); + void set_tree_hints(void); // Reset statistics for all the lists in the tree. - void clearTreeCensus(void); + void clear_tree_census(void); // Print the statistcis for all the lists in the tree. Also may // print out summaries. - void printDictCensus(void) const; + void print_dict_census(void) const; void print_free_lists(outputStream* st) const; - // For debugging. Returns the sum of the _returnedBytes for + // For debugging. Returns the sum of the _returned_bytes for // all lists in the tree. - size_t sumDictReturnedBytes() PRODUCT_RETURN0; - // Sets the _returnedBytes for all the lists in the tree to zero. - void initializeDictReturnedBytes() PRODUCT_RETURN; + size_t sum_dict_returned_bytes() PRODUCT_RETURN0; + // Sets the _returned_bytes for all the lists in the tree to zero. + void initialize_dict_returned_bytes() PRODUCT_RETURN; // For debugging. Return the total number of chunks in the dictionary. - size_t totalCount() PRODUCT_RETURN0; + size_t total_count() PRODUCT_RETURN0; - void reportStatistics() const; + void report_statistics() const; void verify() const; }; diff --git a/hotspot/src/share/vm/memory/freeBlockDictionary.cpp b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp index 03314ebbe44..3c6c8116784 100644 --- a/hotspot/src/share/vm/memory/freeBlockDictionary.cpp +++ b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp @@ -52,8 +52,8 @@ template void FreeBlockDictionary::set_par_lock(Mutex* lock template void FreeBlockDictionary::verify_par_locked() const { #ifdef ASSERT if (ParallelGCThreads > 0) { - Thread* myThread = Thread::current(); - if (myThread->is_GC_task_thread()) { + Thread* my_thread = Thread::current(); + if (my_thread->is_GC_task_thread()) { assert(par_lock() != NULL, "Should be using locking?"); assert_lock_strong(par_lock()); } diff --git a/hotspot/src/share/vm/memory/freeBlockDictionary.hpp b/hotspot/src/share/vm/memory/freeBlockDictionary.hpp index 43148837373..9e3e20a7794 100644 --- a/hotspot/src/share/vm/memory/freeBlockDictionary.hpp +++ b/hotspot/src/share/vm/memory/freeBlockDictionary.hpp @@ -51,45 +51,45 @@ class FreeBlockDictionary: public CHeapObj { NOT_PRODUCT(Mutex* _lock;) public: - virtual void removeChunk(Chunk* fc) = 0; - virtual Chunk* getChunk(size_t size, Dither dither = atLeast) = 0; - virtual void returnChunk(Chunk* chunk) = 0; - virtual size_t totalChunkSize(debug_only(const Mutex* lock)) const = 0; - virtual size_t maxChunkSize() const = 0; - virtual size_t minSize() const = 0; + virtual void remove_chunk(Chunk* fc) = 0; + virtual Chunk* get_chunk(size_t size, Dither dither = atLeast) = 0; + virtual void return_chunk(Chunk* chunk) = 0; + virtual size_t total_chunk_size(debug_only(const Mutex* lock)) const = 0; + virtual size_t max_chunk_size() const = 0; + virtual size_t min_size() const = 0; // Reset the dictionary to the initial conditions for a single // block. virtual void reset(HeapWord* addr, size_t size) = 0; virtual void reset() = 0; - virtual void dictCensusUpdate(size_t size, bool split, bool birth) = 0; - virtual bool coalDictOverPopulated(size_t size) = 0; - virtual void beginSweepDictCensus(double coalSurplusPercent, + virtual void dict_census_udpate(size_t size, bool split, bool birth) = 0; + virtual bool coal_dict_over_populated(size_t size) = 0; + virtual void begin_sweep_dict_census(double coalSurplusPercent, float inter_sweep_current, float inter_sweep_estimate, float intra__sweep_current) = 0; - virtual void endSweepDictCensus(double splitSurplusPercent) = 0; - virtual Chunk* findLargestDict() const = 0; + virtual void end_sweep_dict_census(double splitSurplusPercent) = 0; + virtual Chunk* find_largest_dict() const = 0; // verify that the given chunk is in the dictionary. - virtual bool verifyChunkInFreeLists(Chunk* tc) const = 0; + virtual bool verify_chunk_in_free_list(Chunk* tc) const = 0; // Sigma_{all_free_blocks} (block_size^2) virtual double sum_of_squared_block_sizes() const = 0; virtual Chunk* find_chunk_ends_at(HeapWord* target) const = 0; - virtual void inc_totalSize(size_t v) = 0; - virtual void dec_totalSize(size_t v) = 0; + virtual void inc_total_size(size_t v) = 0; + virtual void dec_total_size(size_t v) = 0; NOT_PRODUCT ( - virtual size_t sumDictReturnedBytes() = 0; - virtual void initializeDictReturnedBytes() = 0; - virtual size_t totalCount() = 0; + virtual size_t sum_dict_returned_bytes() = 0; + virtual void initialize_dict_returned_bytes() = 0; + virtual size_t total_count() = 0; ) - virtual void reportStatistics() const { + virtual void report_statistics() const { gclog_or_tty->print("No statistics available"); } - virtual void printDictCensus() const = 0; + virtual void print_dict_census() const = 0; virtual void print_free_lists(outputStream* st) const = 0; virtual void verify() const = 0; diff --git a/hotspot/src/share/vm/memory/freeList.cpp b/hotspot/src/share/vm/memory/freeList.cpp index 0ffd8f52f06..1c6018082de 100644 --- a/hotspot/src/share/vm/memory/freeList.cpp +++ b/hotspot/src/share/vm/memory/freeList.cpp @@ -65,7 +65,7 @@ FreeList::FreeList(Chunk* fc) : _hint = 0; init_statistics(); #ifndef PRODUCT - _allocation_stats.set_returnedBytes(size() * HeapWordSize); + _allocation_stats.set_returned_bytes(size() * HeapWordSize); #endif } @@ -83,7 +83,7 @@ void FreeList::init_statistics(bool split_birth) { } template -Chunk* FreeList::getChunkAtHead() { +Chunk* FreeList::get_chunk_at_head() { assert_proper_lock_protection(); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); @@ -93,7 +93,7 @@ Chunk* FreeList::getChunkAtHead() { if (nextFC != NULL) { // The chunk fc being removed has a "next". Set the "next" to the // "prev" of fc. - nextFC->linkPrev(NULL); + nextFC->link_prev(NULL); } else { // removed tail of list link_tail(NULL); } @@ -126,10 +126,10 @@ void FreeList::getFirstNChunksFromList(size_t n, FreeList* fl) { if (new_head == NULL) { set_tail(NULL); } else { - new_head->linkPrev(NULL); + new_head->link_prev(NULL); } // Now we can fix up the tail. - tl->linkNext(NULL); + tl->link_next(NULL); // And return the result. fl->set_tail(tl); fl->set_count(k); @@ -138,7 +138,7 @@ void FreeList::getFirstNChunksFromList(size_t n, FreeList* fl) { // Remove this chunk from the list template -void FreeList::removeChunk(Chunk*fc) { +void FreeList::remove_chunk(Chunk*fc) { assert_proper_lock_protection(); assert(head() != NULL, "Remove from empty list"); assert(fc != NULL, "Remove a NULL chunk"); @@ -151,7 +151,7 @@ void FreeList::removeChunk(Chunk*fc) { if (nextFC != NULL) { // The chunk fc being removed has a "next". Set the "next" to the // "prev" of fc. - nextFC->linkPrev(prevFC); + nextFC->link_prev(prevFC); } else { // removed tail of list link_tail(prevFC); } @@ -160,7 +160,7 @@ void FreeList::removeChunk(Chunk*fc) { assert(nextFC == NULL || nextFC->prev() == NULL, "Prev of head should be NULL"); } else { - prevFC->linkNext(nextFC); + prevFC->link_next(nextFC); assert(tail() != prevFC || prevFC->next() == NULL, "Next of tail should be NULL"); } @@ -169,10 +169,10 @@ void FreeList::removeChunk(Chunk*fc) { "H/T/C Inconsistency"); // clear next and prev fields of fc, debug only NOT_PRODUCT( - fc->linkPrev(NULL); - fc->linkNext(NULL); + fc->link_prev(NULL); + fc->link_next(NULL); ) - assert(fc->isFree(), "Should still be a free chunk"); + assert(fc->is_free(), "Should still be a free chunk"); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); assert(head() == NULL || head()->size() == size(), "wrong item on list"); @@ -181,7 +181,7 @@ void FreeList::removeChunk(Chunk*fc) { // Add this chunk at the head of the list. template -void FreeList::returnChunkAtHead(Chunk* chunk, bool record_return) { +void FreeList::return_chunk_at_head(Chunk* chunk, bool record_return) { assert_proper_lock_protection(); assert(chunk != NULL, "insert a NULL chunk"); assert(size() == chunk->size(), "Wrong size"); @@ -190,7 +190,7 @@ void FreeList::returnChunkAtHead(Chunk* chunk, bool record_return) { Chunk* oldHead = head(); assert(chunk != oldHead, "double insertion"); - chunk->linkAfter(oldHead); + chunk->link_after(oldHead); link_head(chunk); if (oldHead == NULL) { // only chunk in list assert(tail() == NULL, "inconsistent FreeList"); @@ -199,7 +199,7 @@ void FreeList::returnChunkAtHead(Chunk* chunk, bool record_return) { increment_count(); // of # of chunks in list DEBUG_ONLY( if (record_return) { - increment_returnedBytes_by(size()*HeapWordSize); + increment_returned_bytes_by(size()*HeapWordSize); } ) assert(head() == NULL || head()->prev() == NULL, "list invariant"); @@ -209,14 +209,14 @@ void FreeList::returnChunkAtHead(Chunk* chunk, bool record_return) { } template -void FreeList::returnChunkAtHead(Chunk* chunk) { +void FreeList::return_chunk_at_head(Chunk* chunk) { assert_proper_lock_protection(); - returnChunkAtHead(chunk, true); + return_chunk_at_head(chunk, true); } // Add this chunk at the tail of the list. template -void FreeList::returnChunkAtTail(Chunk* chunk, bool record_return) { +void FreeList::return_chunk_at_tail(Chunk* chunk, bool record_return) { assert_proper_lock_protection(); assert(head() == NULL || head()->prev() == NULL, "list invariant"); assert(tail() == NULL || tail()->next() == NULL, "list invariant"); @@ -226,7 +226,7 @@ void FreeList::returnChunkAtTail(Chunk* chunk, bool record_return) { Chunk* oldTail = tail(); assert(chunk != oldTail, "double insertion"); if (oldTail != NULL) { - oldTail->linkAfter(chunk); + oldTail->link_after(chunk); } else { // only chunk in list assert(head() == NULL, "inconsistent FreeList"); link_head(chunk); @@ -235,7 +235,7 @@ void FreeList::returnChunkAtTail(Chunk* chunk, bool record_return) { increment_count(); // of # of chunks in list DEBUG_ONLY( if (record_return) { - increment_returnedBytes_by(size()*HeapWordSize); + increment_returned_bytes_by(size()*HeapWordSize); } ) assert(head() == NULL || head()->prev() == NULL, "list invariant"); @@ -245,8 +245,8 @@ void FreeList::returnChunkAtTail(Chunk* chunk, bool record_return) { } template -void FreeList::returnChunkAtTail(Chunk* chunk) { - returnChunkAtTail(chunk, true); +void FreeList::return_chunk_at_tail(Chunk* chunk) { + return_chunk_at_tail(chunk, true); } template @@ -262,8 +262,8 @@ void FreeList::prepend(FreeList* fl) { Chunk* fl_tail = fl->tail(); Chunk* this_head = head(); assert(fl_tail->next() == NULL, "Well-formedness of fl"); - fl_tail->linkNext(this_head); - this_head->linkPrev(fl_tail); + fl_tail->link_next(this_head); + this_head->link_prev(fl_tail); set_head(fl->head()); set_count(count() + fl->count()); } @@ -273,10 +273,10 @@ void FreeList::prepend(FreeList* fl) { } } -// verifyChunkInFreeLists() is used to verify that an item is in this free list. +// verify_chunk_in_free_list() is used to verify that an item is in this free list. // It is used as a debugging aid. template -bool FreeList::verifyChunkInFreeLists(Chunk* fc) const { +bool FreeList::verify_chunk_in_free_list(Chunk* fc) const { // This is an internal consistency check, not part of the check that the // chunk is in the free lists. guarantee(fc->size() == size(), "Wrong list is being searched"); @@ -302,21 +302,21 @@ void FreeList::verify_stats() const { // dictionary for example, this might be the first block and // in that case there would be no place that we could record // the stats (which are kept in the block itself). - assert((_allocation_stats.prevSweep() + _allocation_stats.splitBirths() - + _allocation_stats.coalBirths() + 1) // Total Production Stock + 1 - >= (_allocation_stats.splitDeaths() + _allocation_stats.coalDeaths() + assert((_allocation_stats.prev_sweep() + _allocation_stats.split_births() + + _allocation_stats.coal_births() + 1) // Total Production Stock + 1 + >= (_allocation_stats.split_deaths() + _allocation_stats.coal_deaths() + (ssize_t)count()), // Total Current Stock + depletion err_msg("FreeList " PTR_FORMAT " of size " SIZE_FORMAT " violates Conservation Principle: " - "prevSweep(" SIZE_FORMAT ")" - " + splitBirths(" SIZE_FORMAT ")" - " + coalBirths(" SIZE_FORMAT ") + 1 >= " - " splitDeaths(" SIZE_FORMAT ")" - " coalDeaths(" SIZE_FORMAT ")" + "prev_sweep(" SIZE_FORMAT ")" + " + split_births(" SIZE_FORMAT ")" + " + coal_births(" SIZE_FORMAT ") + 1 >= " + " split_deaths(" SIZE_FORMAT ")" + " coal_deaths(" SIZE_FORMAT ")" " + count(" SSIZE_FORMAT ")", - this, _size, _allocation_stats.prevSweep(), _allocation_stats.splitBirths(), - _allocation_stats.splitBirths(), _allocation_stats.splitDeaths(), - _allocation_stats.coalDeaths(), count())); + this, _size, _allocation_stats.prev_sweep(), _allocation_stats.split_births(), + _allocation_stats.split_births(), _allocation_stats.split_deaths(), + _allocation_stats.coal_deaths(), count())); } template @@ -360,8 +360,8 @@ void FreeList::print_on(outputStream* st, const char* c) const { st->print("\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\n", - bfrSurp(), surplus(), desired(), prevSweep(), beforeSweep(), - count(), coalBirths(), coalDeaths(), splitBirths(), splitDeaths()); + bfr_surp(), surplus(), desired(), prev_sweep(), before_sweep(), + count(), coal_births(), coal_deaths(), split_births(), split_deaths()); } #ifndef SERIALGC diff --git a/hotspot/src/share/vm/memory/freeList.hpp b/hotspot/src/share/vm/memory/freeList.hpp index 77e42053bf5..d306578c9cb 100644 --- a/hotspot/src/share/vm/memory/freeList.hpp +++ b/hotspot/src/share/vm/memory/freeList.hpp @@ -119,7 +119,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC { // If this method is not used (just set the head instead), // this check can be avoided. if (v != NULL) { - v->linkPrev(NULL); + v->link_prev(NULL); } } @@ -138,7 +138,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC { assert_proper_lock_protection(); set_tail(v); if (v != NULL) { - v->clearNext(); + v->clear_next(); } } @@ -185,12 +185,12 @@ class FreeList VALUE_OBJ_CLASS_SPEC { inter_sweep_estimate, intra_sweep_estimate); } - ssize_t coalDesired() const { - return _allocation_stats.coalDesired(); + ssize_t coal_desired() const { + return _allocation_stats.coal_desired(); } - void set_coalDesired(ssize_t v) { + void set_coal_desired(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_coalDesired(v); + _allocation_stats.set_coal_desired(v); } ssize_t surplus() const { @@ -209,106 +209,106 @@ class FreeList VALUE_OBJ_CLASS_SPEC { _allocation_stats.decrement_surplus(); } - ssize_t bfrSurp() const { - return _allocation_stats.bfrSurp(); + ssize_t bfr_surp() const { + return _allocation_stats.bfr_surp(); } - void set_bfrSurp(ssize_t v) { + void set_bfr_surp(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_bfrSurp(v); + _allocation_stats.set_bfr_surp(v); } - ssize_t prevSweep() const { - return _allocation_stats.prevSweep(); + ssize_t prev_sweep() const { + return _allocation_stats.prev_sweep(); } - void set_prevSweep(ssize_t v) { + void set_prev_sweep(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_prevSweep(v); + _allocation_stats.set_prev_sweep(v); } - ssize_t beforeSweep() const { - return _allocation_stats.beforeSweep(); + ssize_t before_sweep() const { + return _allocation_stats.before_sweep(); } - void set_beforeSweep(ssize_t v) { + void set_before_sweep(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_beforeSweep(v); + _allocation_stats.set_before_sweep(v); } - ssize_t coalBirths() const { - return _allocation_stats.coalBirths(); + ssize_t coal_births() const { + return _allocation_stats.coal_births(); } - void set_coalBirths(ssize_t v) { + void set_coal_births(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_coalBirths(v); + _allocation_stats.set_coal_births(v); } - void increment_coalBirths() { + void increment_coal_births() { assert_proper_lock_protection(); - _allocation_stats.increment_coalBirths(); + _allocation_stats.increment_coal_births(); } - ssize_t coalDeaths() const { - return _allocation_stats.coalDeaths(); + ssize_t coal_deaths() const { + return _allocation_stats.coal_deaths(); } - void set_coalDeaths(ssize_t v) { + void set_coal_deaths(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_coalDeaths(v); + _allocation_stats.set_coal_deaths(v); } - void increment_coalDeaths() { + void increment_coal_deaths() { assert_proper_lock_protection(); - _allocation_stats.increment_coalDeaths(); + _allocation_stats.increment_coal_deaths(); } - ssize_t splitBirths() const { - return _allocation_stats.splitBirths(); + ssize_t split_births() const { + return _allocation_stats.split_births(); } - void set_splitBirths(ssize_t v) { + void set_split_births(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_splitBirths(v); + _allocation_stats.set_split_births(v); } - void increment_splitBirths() { + void increment_split_births() { assert_proper_lock_protection(); - _allocation_stats.increment_splitBirths(); + _allocation_stats.increment_split_births(); } - ssize_t splitDeaths() const { - return _allocation_stats.splitDeaths(); + ssize_t split_deaths() const { + return _allocation_stats.split_deaths(); } - void set_splitDeaths(ssize_t v) { + void set_split_deaths(ssize_t v) { assert_proper_lock_protection(); - _allocation_stats.set_splitDeaths(v); + _allocation_stats.set_split_deaths(v); } - void increment_splitDeaths() { + void increment_split_deaths() { assert_proper_lock_protection(); - _allocation_stats.increment_splitDeaths(); + _allocation_stats.increment_split_deaths(); } NOT_PRODUCT( - // For debugging. The "_returnedBytes" in all the lists are summed + // For debugging. The "_returned_bytes" in all the lists are summed // and compared with the total number of bytes swept during a // collection. - size_t returnedBytes() const { return _allocation_stats.returnedBytes(); } - void set_returnedBytes(size_t v) { _allocation_stats.set_returnedBytes(v); } - void increment_returnedBytes_by(size_t v) { - _allocation_stats.set_returnedBytes(_allocation_stats.returnedBytes() + v); + size_t returned_bytes() const { return _allocation_stats.returned_bytes(); } + void set_returned_bytes(size_t v) { _allocation_stats.set_returned_bytes(v); } + void increment_returned_bytes_by(size_t v) { + _allocation_stats.set_returned_bytes(_allocation_stats.returned_bytes() + v); } ) // Unlink head of list and return it. Returns NULL if // the list is empty. - Chunk* getChunkAtHead(); + Chunk* get_chunk_at_head(); // Remove the first "n" or "count", whichever is smaller, chunks from the // list, setting "fl", which is required to be empty, to point to them. void getFirstNChunksFromList(size_t n, FreeList* fl); // Unlink this chunk from it's free list - void removeChunk(Chunk* fc); + void remove_chunk(Chunk* fc); // Add this chunk to this free list. - void returnChunkAtHead(Chunk* fc); - void returnChunkAtTail(Chunk* fc); + void return_chunk_at_head(Chunk* fc); + void return_chunk_at_tail(Chunk* fc); // Similar to returnChunk* but also records some diagnostic // information. - void returnChunkAtHead(Chunk* fc, bool record_return); - void returnChunkAtTail(Chunk* fc, bool record_return); + void return_chunk_at_head(Chunk* fc, bool record_return); + void return_chunk_at_tail(Chunk* fc, bool record_return); // Prepend "fl" (whose size is required to be the same as that of "this") // to the front of "this" list. @@ -316,7 +316,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC { // Verify that the chunk is in the list. // found. Return NULL if "fc" is not found. - bool verifyChunkInFreeLists(Chunk* fc) const; + bool verify_chunk_in_free_list(Chunk* fc) const; // Stats verification void verify_stats() const PRODUCT_RETURN; From 377a04fe57d5f10fdb18dfee9d26dfdd9a38a2a2 Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Wed, 25 Apr 2012 10:23:12 -0700 Subject: [PATCH 27/51] 7143490: G1: Remove HeapRegion::_top_at_conc_mark_count Removed the HeapRegion::_top_at_conc_mark_count field. It is no longer needed as a result of the changes for 6888336 and 7127706. Refactored the closures that finalize and verify the liveness counting data so that common functionality was placed into a base class. Reviewed-by: brutisso, tonyp --- .../gc_implementation/g1/concurrentMark.cpp | 207 +++++------------- .../gc_implementation/g1/g1CollectedHeap.cpp | 11 +- .../g1/g1CollectorPolicy.cpp | 14 +- .../vm/gc_implementation/g1/heapRegion.cpp | 5 - .../vm/gc_implementation/g1/heapRegion.hpp | 18 -- .../g1/heapRegion.inline.hpp | 1 - 6 files changed, 64 insertions(+), 192 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index ba29b3120db..fd228964f7d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -1183,35 +1183,31 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { g1p->record_concurrent_mark_remark_end(); } -// Used to calculate the # live objects per region -// for verification purposes -class CalcLiveObjectsClosure: public HeapRegionClosure { - - CMBitMapRO* _bm; +// Base class of the closures that finalize and verify the +// liveness counting data. +class CMCountDataClosureBase: public HeapRegionClosure { +protected: ConcurrentMark* _cm; BitMap* _region_bm; BitMap* _card_bm; - size_t _region_marked_bytes; + void set_card_bitmap_range(BitMap::idx_t start_idx, BitMap::idx_t last_idx) { + assert(start_idx <= last_idx, "sanity"); - intptr_t _bottom_card_num; - - void mark_card_num_range(intptr_t start_card_num, intptr_t last_card_num) { - assert(start_card_num <= last_card_num, "sanity"); - BitMap::idx_t start_idx = start_card_num - _bottom_card_num; - BitMap::idx_t last_idx = last_card_num - _bottom_card_num; - - for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) { - _card_bm->par_at_put(i, 1); + // Set the inclusive bit range [start_idx, last_idx]. + // For small ranges (up to 8 cards) use a simple loop; otherwise + // use par_at_put_range. + if ((last_idx - start_idx) < 8) { + for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) { + _card_bm->par_set_bit(i); + } + } else { + assert(last_idx < _card_bm->size(), "sanity"); + // Note BitMap::par_at_put_range() is exclusive. + _card_bm->par_at_put_range(start_idx, last_idx+1, true); } } -public: - CalcLiveObjectsClosure(CMBitMapRO *bm, ConcurrentMark *cm, - BitMap* region_bm, BitMap* card_bm) : - _bm(bm), _cm(cm), _region_bm(region_bm), _card_bm(card_bm), - _region_marked_bytes(0), _bottom_card_num(cm->heap_bottom_card_num()) { } - // It takes a region that's not empty (i.e., it has at least one // live object in it and sets its corresponding bit on the region // bitmap to 1. If the region is "starts humongous" it will also set @@ -1234,6 +1230,24 @@ public: } } +public: + CMCountDataClosureBase(ConcurrentMark *cm, + BitMap* region_bm, BitMap* card_bm): + _cm(cm), _region_bm(region_bm), _card_bm(card_bm) { } +}; + +// Closure that calculates the # live objects per region. Used +// for verification purposes during the cleanup pause. +class CalcLiveObjectsClosure: public CMCountDataClosureBase { + CMBitMapRO* _bm; + size_t _region_marked_bytes; + +public: + CalcLiveObjectsClosure(CMBitMapRO *bm, ConcurrentMark *cm, + BitMap* region_bm, BitMap* card_bm) : + CMCountDataClosureBase(cm, region_bm, card_bm), + _bm(bm), _region_marked_bytes(0) { } + bool doHeapRegion(HeapRegion* hr) { if (hr->continuesHumongous()) { @@ -1260,65 +1274,31 @@ public: size_t marked_bytes = 0; - // Below, the term "card num" means the result of shifting an address - // by the card shift -- address 0 corresponds to card number 0. One - // must subtract the card num of the bottom of the heap to obtain a - // card table index. - - // The first card num of the sequence of live cards currently being - // constructed. -1 ==> no sequence. - intptr_t start_card_num = -1; - - // The last card num of the sequence of live cards currently being - // constructed. -1 ==> no sequence. - intptr_t last_card_num = -1; - while (start < nextTop) { oop obj = oop(start); int obj_sz = obj->size(); - - // The card num of the start of the current object. - intptr_t obj_card_num = - intptr_t(uintptr_t(start) >> CardTableModRefBS::card_shift); HeapWord* obj_last = start + obj_sz - 1; - intptr_t obj_last_card_num = - intptr_t(uintptr_t(obj_last) >> CardTableModRefBS::card_shift); - if (obj_card_num != last_card_num) { - if (start_card_num == -1) { - assert(last_card_num == -1, "Both or neither."); - start_card_num = obj_card_num; - } else { - assert(last_card_num != -1, "Both or neither."); - assert(obj_card_num >= last_card_num, "Inv"); - if ((obj_card_num - last_card_num) > 1) { - // Mark the last run, and start a new one. - mark_card_num_range(start_card_num, last_card_num); - start_card_num = obj_card_num; - } - } - } - // In any case, we set the last card num. - last_card_num = obj_last_card_num; + BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start); + BitMap::idx_t last_idx = _cm->card_bitmap_index_for(obj_last); + // Set the bits in the card BM for this object (inclusive). + set_card_bitmap_range(start_idx, last_idx); + + // Add the size of this object to the number of marked bytes. marked_bytes += (size_t)obj_sz * HeapWordSize; // Find the next marked object after this one. - start = _bm->getNextMarkedWordAddress(start + 1, nextTop); - } - - // Handle the last range, if any. - if (start_card_num != -1) { - mark_card_num_range(start_card_num, last_card_num); + start = _bm->getNextMarkedWordAddress(obj_last + 1, nextTop); } // Mark the allocated-since-marking portion... HeapWord* top = hr->top(); if (nextTop < top) { - start_card_num = intptr_t(uintptr_t(nextTop) >> CardTableModRefBS::card_shift); - last_card_num = intptr_t(uintptr_t(top) >> CardTableModRefBS::card_shift); + BitMap::idx_t start_idx = _cm->card_bitmap_index_for(nextTop); + BitMap::idx_t last_idx = _cm->card_bitmap_index_for(top - 1); - mark_card_num_range(start_card_num, last_card_num); + set_card_bitmap_range(start_idx, last_idx); // This definitely means the region has live objects. set_bit_for_region(hr); @@ -1394,17 +1374,6 @@ public: MutexLockerEx x((_verbose ? ParGCRareEvent_lock : NULL), Mutex::_no_safepoint_check_flag); - // Verify that _top_at_conc_count == ntams - if (hr->top_at_conc_mark_count() != hr->next_top_at_mark_start()) { - if (_verbose) { - gclog_or_tty->print_cr("Region %u: top at conc count incorrect: " - "expected " PTR_FORMAT ", actual: " PTR_FORMAT, - hr->hrs_index(), hr->next_top_at_mark_start(), - hr->top_at_conc_mark_count()); - } - failures += 1; - } - // Verify the marked bytes for this region. size_t exp_marked_bytes = _calc_cl.region_marked_bytes(); size_t act_marked_bytes = hr->next_marked_bytes(); @@ -1470,7 +1439,7 @@ public: _failures += failures; // We could stop iteration over the heap when we - // find the first voilating region by returning true. + // find the first violating region by returning true. return false; } }; @@ -1543,62 +1512,19 @@ public: int failures() const { return _failures; } }; -// Final update of count data (during cleanup). -// Adds [top_at_count, NTAMS) to the marked bytes for each -// region. Sets the bits in the card bitmap corresponding -// to the interval [top_at_count, top], and sets the -// liveness bit for each region containing live data -// in the region bitmap. - -class FinalCountDataUpdateClosure: public HeapRegionClosure { - ConcurrentMark* _cm; - BitMap* _region_bm; - BitMap* _card_bm; - - void set_card_bitmap_range(BitMap::idx_t start_idx, BitMap::idx_t last_idx) { - assert(start_idx <= last_idx, "sanity"); - - // Set the inclusive bit range [start_idx, last_idx]. - // For small ranges (up to 8 cards) use a simple loop; otherwise - // use par_at_put_range. - if ((last_idx - start_idx) <= 8) { - for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) { - _card_bm->par_set_bit(i); - } - } else { - assert(last_idx < _card_bm->size(), "sanity"); - // Note BitMap::par_at_put_range() is exclusive. - _card_bm->par_at_put_range(start_idx, last_idx+1, true); - } - } - - // It takes a region that's not empty (i.e., it has at least one - // live object in it and sets its corresponding bit on the region - // bitmap to 1. If the region is "starts humongous" it will also set - // to 1 the bits on the region bitmap that correspond to its - // associated "continues humongous" regions. - void set_bit_for_region(HeapRegion* hr) { - assert(!hr->continuesHumongous(), "should have filtered those out"); - - BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index(); - if (!hr->startsHumongous()) { - // Normal (non-humongous) case: just set the bit. - _region_bm->par_set_bit(index); - } else { - // Starts humongous case: calculate how many regions are part of - // this humongous region and then set the bit range. - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - HeapRegion *last_hr = g1h->heap_region_containing_raw(hr->end() - 1); - BitMap::idx_t end_index = (BitMap::idx_t) last_hr->hrs_index() + 1; - _region_bm->par_at_put_range(index, end_index, true); - } - } +// Closure that finalizes the liveness counting data. +// Used during the cleanup pause. +// Sets the bits corresponding to the interval [NTAMS, top] +// (which contains the implicitly live objects) in the +// card liveness bitmap. Also sets the bit for each region, +// containing live data, in the region liveness bitmap. +class FinalCountDataUpdateClosure: public CMCountDataClosureBase { public: FinalCountDataUpdateClosure(ConcurrentMark* cm, BitMap* region_bm, BitMap* card_bm) : - _cm(cm), _region_bm(region_bm), _card_bm(card_bm) { } + CMCountDataClosureBase(cm, region_bm, card_bm) { } bool doHeapRegion(HeapRegion* hr) { @@ -1613,26 +1539,10 @@ class FinalCountDataUpdateClosure: public HeapRegionClosure { return false; } - HeapWord* start = hr->top_at_conc_mark_count(); HeapWord* ntams = hr->next_top_at_mark_start(); HeapWord* top = hr->top(); - assert(hr->bottom() <= start && start <= hr->end() && - hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions."); - - if (start < ntams) { - // Region was changed between remark and cleanup pauses - // We need to add (ntams - start) to the marked bytes - // for this region, and set bits for the range - // [ card_idx(start), card_idx(ntams) ) in the card bitmap. - size_t live_bytes = (ntams - start) * HeapWordSize; - hr->add_to_marked_bytes(live_bytes); - - // Record the new top at conc count - hr->set_top_at_conc_mark_count(ntams); - - // The setting of the bits in the card bitmap takes place below - } + assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions."); // Mark the allocated-since-marking portion... if (ntams < top) { @@ -1640,8 +1550,8 @@ class FinalCountDataUpdateClosure: public HeapRegionClosure { set_bit_for_region(hr); } - // Now set the bits for [start, top] - BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start); + // Now set the bits for [ntams, top] + BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams); BitMap::idx_t last_idx = _cm->card_bitmap_index_for(top); set_card_bitmap_range(start_idx, last_idx); @@ -3072,9 +2982,6 @@ class AggregateCountDataHRClosure: public HeapRegionClosure { // Update the marked bytes for this region. hr->add_to_marked_bytes(marked_bytes); - // Now set the top at count to NTAMS. - hr->set_top_at_conc_mark_count(limit); - // Next heap region return false; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 2711a52d01b..3c5e6848591 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -368,16 +368,11 @@ void YoungList::print() { if (curr == NULL) gclog_or_tty->print_cr(" empty"); while (curr != NULL) { - gclog_or_tty->print_cr(" [%08x-%08x], t: %08x, P: %08x, N: %08x, C: %08x, " - "age: %4d, y: %d, surv: %d", - curr->bottom(), curr->end(), - curr->top(), + gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d", + HR_FORMAT_PARAMS(curr), curr->prev_top_at_mark_start(), curr->next_top_at_mark_start(), - curr->top_at_conc_mark_count(), - curr->age_in_surv_rate_group_cond(), - curr->is_young(), - curr->is_survivor()); + curr->age_in_surv_rate_group_cond()); curr = curr->get_next_young_region(); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index d656f260ba1..52bec21e771 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -2459,16 +2459,10 @@ void G1CollectorPolicy::print_collection_set(HeapRegion* list_head, outputStream while (csr != NULL) { HeapRegion* next = csr->next_in_collection_set(); assert(csr->in_collection_set(), "bad CS"); - st->print_cr(" [%08x-%08x], t: %08x, P: %08x, N: %08x, C: %08x, " - "age: %4d, y: %d, surv: %d", - csr->bottom(), csr->end(), - csr->top(), - csr->prev_top_at_mark_start(), - csr->next_top_at_mark_start(), - csr->top_at_conc_mark_count(), - csr->age_in_surv_rate_group_cond(), - csr->is_young(), - csr->is_survivor()); + st->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d", + HR_FORMAT_PARAMS(csr), + csr->prev_top_at_mark_start(), csr->next_top_at_mark_start(), + csr->age_in_surv_rate_group_cond()); csr = next; } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 09b80cce581..33dac688f84 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -510,9 +510,6 @@ HeapRegion::HeapRegion(uint hrs_index, _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); - // In case the region is allocated during a pause, note the top. - // We haven't done any counting on a brand new region. - _top_at_conc_mark_count = bottom(); } class NextCompactionHeapRegionClosure: public HeapRegionClosure { @@ -585,14 +582,12 @@ void HeapRegion::note_self_forwarding_removal_start(bool during_initial_mark, // we find to be self-forwarded on the next bitmap. So all // objects need to be below NTAMS. _next_top_at_mark_start = top(); - set_top_at_conc_mark_count(bottom()); _next_marked_bytes = 0; } else if (during_conc_mark) { // During concurrent mark, all objects in the CSet (including // the ones we find to be self-forwarded) are implicitly live. // So all objects need to be above NTAMS. _next_top_at_mark_start = bottom(); - set_top_at_conc_mark_count(bottom()); _next_marked_bytes = 0; } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index cd6e164e136..a3b4e44b7e9 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -306,9 +306,6 @@ class HeapRegion: public G1OffsetTableContigSpace { // If a collection pause is in progress, this is the top at the start // of that pause. - // We've counted the marked bytes of objects below here. - HeapWord* _top_at_conc_mark_count; - void init_top_at_mark_start() { assert(_prev_marked_bytes == 0 && _next_marked_bytes == 0, @@ -316,7 +313,6 @@ class HeapRegion: public G1OffsetTableContigSpace { HeapWord* bot = bottom(); _prev_top_at_mark_start = bot; _next_top_at_mark_start = bot; - _top_at_conc_mark_count = bot; } void set_young_type(YoungType new_type) { @@ -625,19 +621,6 @@ class HeapRegion: public G1OffsetTableContigSpace { // last mark phase ended. bool is_marked() { return _prev_top_at_mark_start != bottom(); } - void init_top_at_conc_mark_count() { - _top_at_conc_mark_count = bottom(); - } - - void set_top_at_conc_mark_count(HeapWord *cur) { - assert(bottom() <= cur && cur <= end(), "Sanity."); - _top_at_conc_mark_count = cur; - } - - HeapWord* top_at_conc_mark_count() { - return _top_at_conc_mark_count; - } - void reset_during_compaction() { guarantee( isHumongous() && startsHumongous(), "should only be called for humongous regions"); @@ -733,7 +716,6 @@ class HeapRegion: public G1OffsetTableContigSpace { _evacuation_failed = b; if (b) { - init_top_at_conc_mark_count(); _next_marked_bytes = 0; } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp index 1498b94a4e9..d88bc07ad07 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp @@ -56,7 +56,6 @@ G1OffsetTableContigSpace::block_start_const(const void* p) const { } inline void HeapRegion::note_start_of_marking() { - init_top_at_conc_mark_count(); _next_marked_bytes = 0; _next_top_at_mark_start = top(); } From 93bfefecfef8aa08df98f700d74c95a70aa58c08 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 25 Apr 2012 12:36:37 +0200 Subject: [PATCH 28/51] 7163848: G1: Log GC Cause for a GC Reviewed-by: johnc, jwilhelm, jmasa --- .../gc_implementation/g1/g1CollectedHeap.cpp | 24 +++++++++---------- .../g1/g1CollectorPolicy.cpp | 5 ++-- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 3c5e6848591..270e52e32b4 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -1248,12 +1248,13 @@ bool G1CollectedHeap::do_collection(bool explicit_gc, IsGCActiveMark x; // Timing - bool system_gc = (gc_cause() == GCCause::_java_lang_system_gc); - assert(!system_gc || explicit_gc, "invariant"); + assert(gc_cause() != GCCause::_java_lang_system_gc || explicit_gc, "invariant"); gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps); TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); - TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC", - G1Log::fine(), true, gclog_or_tty); + + char verbose_str[128]; + sprintf(verbose_str, "Full GC (%s)", GCCause::to_string(gc_cause())); + TraceTime t(verbose_str, G1Log::fine(), true, gclog_or_tty); TraceCollectorStats tcs(g1mm()->full_collection_counters()); TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); @@ -3588,25 +3589,22 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { // Inner scope for scope based logging, timers, and stats collection { - char verbose_str[128]; - sprintf(verbose_str, "GC pause "); - if (g1_policy()->gcs_are_young()) { - strcat(verbose_str, "(young)"); - } else { - strcat(verbose_str, "(mixed)"); - } if (g1_policy()->during_initial_mark_pause()) { - strcat(verbose_str, " (initial-mark)"); // We are about to start a marking cycle, so we increment the // full collection counter. increment_total_full_collections(); } - // if the log level is "finer" is on, we'll print long statistics information // in the collector policy code, so let's not print this as the output // is messy if we do. gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps); TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); + + char verbose_str[128]; + sprintf(verbose_str, "GC pause (%s) (%s)%s", + GCCause::to_string(gc_cause()), + g1_policy()->gcs_are_young() ? "young" : "mixed", + g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : ""); TraceTime t(verbose_str, G1Log::fine() && !G1Log::finer(), true, gclog_or_tty); TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index 52bec21e771..a4060618131 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -886,8 +886,9 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec, size_t start_used) { if (G1Log::finer()) { gclog_or_tty->stamp(PrintGCTimeStamps); - gclog_or_tty->print("[GC pause"); - gclog_or_tty->print(" (%s)", gcs_are_young() ? "young" : "mixed"); + gclog_or_tty->print("[GC pause (%s) (%s)", + GCCause::to_string(_g1->gc_cause()), + gcs_are_young() ? "young" : "mixed"); } // We only need to do this here as the policy will only be applied From 7f8dfa7abbff91de257a21b74af56d1e0e7f1c22 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Wed, 25 Apr 2012 16:48:12 +0400 Subject: [PATCH 29/51] 7163482: [macosx] Regtest closed/javax/swing/JTree/4908142/bug4908142.java intermittent failure Reviewed-by: rupashka --- .../javax/swing/JTree/4908142/bug4908142.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 jdk/test/javax/swing/JTree/4908142/bug4908142.java diff --git a/jdk/test/javax/swing/JTree/4908142/bug4908142.java b/jdk/test/javax/swing/JTree/4908142/bug4908142.java new file mode 100644 index 00000000000..58cb1ea86f5 --- /dev/null +++ b/jdk/test/javax/swing/JTree/4908142/bug4908142.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009, 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. + */ + + +/* + * @test + * @bug 4908142 + * @summary JList doesn't handle search function appropriately + * @author Andrey Pikalev + * @library ../../regtesthelpers + * @build Util + * @run main bug4908142 + */ +import javax.swing.*; +import javax.swing.tree.*; +import java.awt.*; +import java.awt.event.*; +import java.util.concurrent.Callable; +import sun.awt.SunToolkit; + +public class bug4908142 { + + private static JTree tree; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + tree.requestFocus(); + tree.setSelectionRow(0); + } + }); + + toolkit.realSync(); + + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyPress(KeyEvent.VK_D); + robot.keyRelease(KeyEvent.VK_D); + toolkit.realSync(); + + + String sel = Util.invokeOnEDT(new Callable() { + + @Override + public String call() throws Exception { + return tree.getLastSelectedPathComponent().toString(); + } + }); + + if (!"aad".equals(sel)) { + throw new Error("The selected index should be \"aad\", but not " + sel); + } + } + + private static void createAndShowGUI() { + JFrame fr = new JFrame("Test"); + fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + String[] data = {"aaa", "aab", "aac", "aad", "ade", "bba"}; + final DefaultMutableTreeNode root = new DefaultMutableTreeNode(data[0]); + for (int i = 1; i < data.length; i++) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(data[i]); + root.add(node); + } + + tree = new JTree(root); + + JScrollPane sp = new JScrollPane(tree); + fr.getContentPane().add(sp); + fr.setSize(200, 200); + fr.setVisible(true); + } +} From 653ffb1218c0dd710e6b88e5b927da6b2ce14b8b Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Wed, 25 Apr 2012 18:15:57 +0400 Subject: [PATCH 30/51] 7154480: [macosx] Not all popup menu items are visible Reviewed-by: art --- .../classes/sun/lwawt/macosx/LWCToolkit.java | 10 +++++++- .../share/classes/javax/swing/JPopupMenu.java | 23 ++++++++---------- jdk/src/share/classes/sun/awt/SunToolkit.java | 24 ++++++++++++++++++- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index b4c5f453d8d..05c4ceeaec8 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -656,6 +656,14 @@ public class LWCToolkit extends LWToolkit { return ((mods & (InputEvent.META_MASK | InputEvent.CTRL_MASK)) == 0); } + /** + * Returns whether popup is allowed to be shown above the task bar. + */ + @Override + public boolean canPopupOverlapTaskBar() { + return false; + } + // Extends PeerEvent because we want to pass long an ObjC mediator object and because we want these events to be posted early // Typically, rather than relying on the notifier to call notifyAll(), we use the mediator to stop the runloop public static class CPeerEvent extends PeerEvent { diff --git a/jdk/src/share/classes/javax/swing/JPopupMenu.java b/jdk/src/share/classes/javax/swing/JPopupMenu.java index 01763f666a9..7564b9f2075 100644 --- a/jdk/src/share/classes/javax/swing/JPopupMenu.java +++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ import javax.swing.plaf.PopupMenuUI; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.event.*; + +import sun.awt.SunToolkit; import sun.security.util.SecurityConstants; import java.applet.Applet; @@ -347,6 +349,7 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { long popupBottomY = (long)popupLocation.y + (long)popupSize.height; int scrWidth = scrBounds.width; int scrHeight = scrBounds.height; + if (!canPopupOverlapTaskBar()) { // Insets include the task bar. Take them into account. Insets scrInsets = toolkit.getScreenInsets(gc); @@ -407,25 +410,19 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { } /** - * Checks that there are enough security permissions - * to make popup "always on top", which allows to show it above the task bar. + * Returns whether popup is allowed to be shown above the task bar. */ static boolean canPopupOverlapTaskBar() { boolean result = true; - try { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission( - SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); - } - } catch (SecurityException se) { - // There is no permission to show popups over the task bar - result = false; + + Toolkit tk = Toolkit.getDefaultToolkit(); + if (tk instanceof SunToolkit) { + result = ((SunToolkit)tk).canPopupOverlapTaskBar(); } + return result; } - /** * Factory method which creates the JMenuItem for * Actions added to the JPopupMenu. diff --git a/jdk/src/share/classes/sun/awt/SunToolkit.java b/jdk/src/share/classes/sun/awt/SunToolkit.java index 19cfdf41711..b63403961a6 100644 --- a/jdk/src/share/classes/sun/awt/SunToolkit.java +++ b/jdk/src/share/classes/sun/awt/SunToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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 @@ -42,6 +42,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; + +import sun.security.util.SecurityConstants; import sun.util.logging.PlatformLogger; import sun.misc.SoftCache; import sun.font.FontDesignMetrics; @@ -1135,6 +1137,26 @@ public abstract class SunToolkit extends Toolkit return ((mods & InputEvent.ALT_MASK) == (mods & InputEvent.CTRL_MASK)); } + /** + * Returns whether popup is allowed to be shown above the task bar. + * This is a default implementation of this method, which checks + * corresponding security permission. + */ + public boolean canPopupOverlapTaskBar() { + boolean result = true; + try { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission( + SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); + } + } catch (SecurityException se) { + // There is no permission to show popups over the task bar + result = false; + } + return result; + } + /** * Returns a new input method window, with behavior as specified in * {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}. From 9dac65e6e500ac1eedc40d7137f34488e83eea3c Mon Sep 17 00:00:00 2001 From: Scott Kovatch Date: Wed, 25 Apr 2012 12:18:10 -0700 Subject: [PATCH 31/51] 7128699: Fix bundle name so it contains the bugfix number in the name Reviewed-by: robilad --- jdk/make/common/Release-macosx.gmk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/make/common/Release-macosx.gmk b/jdk/make/common/Release-macosx.gmk index 9235afa0eb8..f56370f3ca1 100644 --- a/jdk/make/common/Release-macosx.gmk +++ b/jdk/make/common/Release-macosx.gmk @@ -29,14 +29,14 @@ JA_DIRNAME=ja_JP.UTF-8 # Defines the release targets for Mac OS X build products -JDK_BUNDLE_DIR = $(ABS_OUTPUTDIR)/j2sdk-bundle/$(THIS_JDK_VERSION).jdk/Contents -JRE_BUNDLE_DIR = $(ABS_OUTPUTDIR)/j2re-bundle/$(THIS_JDK_VERSION).jre/Contents +JDK_BUNDLE_DIR = $(ABS_OUTPUTDIR)/j2sdk-bundle/jdk$(JDK_VERSION).jdk/Contents +JRE_BUNDLE_DIR = $(ABS_OUTPUTDIR)/j2re-bundle/jre$(JDK_VERSION).jre/Contents MACOSX_SRC = $(JDK_TOPDIR)/src/macosx BUNDLE_ID ?= net.java.openjdk -BUNLDE_ID_JRE ?= $(BUNDLE_ID).jre -BUNLDE_ID_JDK ?= $(BUNDLE_ID).jdk +BUNDLE_ID_JRE ?= $(BUNDLE_ID).jre +BUNDLE_ID_JDK ?= $(BUNDLE_ID).jdk BUNDLE_NAME ?= OpenJDK $(JDK_MINOR_VERSION) BUNDLE_NAME_JRE ?= $(BUNDLE_NAME) From 6d834825dea9aeac8e403291ec9f7b9de13f6174 Mon Sep 17 00:00:00 2001 From: Kurchi Subhra Hazra Date: Wed, 25 Apr 2012 12:31:31 -0700 Subject: [PATCH 32/51] 7160242: (prefs) Preferences.remove(null) does not throw NPE [macosx] Insert null check of argument in remove()'s implementation Reviewed-by: forax, chegar, alanb --- .../java/util/prefs/MacOSXPreferences.java | 3 ++ .../java/util/prefs/RemoveNullKeyCheck.java | 44 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 jdk/test/java/util/prefs/RemoveNullKeyCheck.java diff --git a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java index 8f3f461e1dd..66b3e3af4e0 100644 --- a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java +++ b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java @@ -25,6 +25,8 @@ package java.util.prefs; +import java.util.Objects; + class MacOSXPreferences extends AbstractPreferences { // fixme need security checks? @@ -147,6 +149,7 @@ class MacOSXPreferences extends AbstractPreferences { // AbstractPreferences implementation protected void removeSpi(String key) { + Objects.requireNonNull(key, "Specified key cannot be null"); file.removeKeyFromNode(path, key); } diff --git a/jdk/test/java/util/prefs/RemoveNullKeyCheck.java b/jdk/test/java/util/prefs/RemoveNullKeyCheck.java new file mode 100644 index 00000000000..e45459b4495 --- /dev/null +++ b/jdk/test/java/util/prefs/RemoveNullKeyCheck.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 7160242 + * @summary Check if NullPointerException is thrown if the key passed + * to remove() is null. + */ + +import java.util.prefs.Preferences; + +public class RemoveNullKeyCheck { + + public static void main(String[] args) throws Exception { + try { + Preferences node = Preferences.userRoot().node("N1"); + node.remove(null); + throw new RuntimeException("Expected NullPointerException " + + "not thrown"); + } catch (NullPointerException npe) { + System.out.println("NullPointerException thrown"); + } + } +} From 5b91fbd2b55dbd35b3ad80621797bac27cd42fa9 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 25 Apr 2012 15:06:51 -0700 Subject: [PATCH 33/51] 7164344: enabling ZIP_DEBUGINFO_FILES causes unexpected test failures on Solaris and Windows Disable FDS by default on Solaris; disable ZIP_DEBUGINFO_FILES by default on Windows. Reviewed-by: acorn, sspitsyn --- hotspot/make/solaris/makefiles/defs.make | 14 +++++++++++--- hotspot/make/windows/makefiles/defs.make | 4 +++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/hotspot/make/solaris/makefiles/defs.make b/hotspot/make/solaris/makefiles/defs.make index 260524e2645..f35533132d8 100644 --- a/hotspot/make/solaris/makefiles/defs.make +++ b/hotspot/make/solaris/makefiles/defs.make @@ -109,12 +109,18 @@ ifeq ($(JDK6_OR_EARLIER),0) # overridden in some situations, e.g., a BUILD_FLAVOR != product # build. + # Disable FULL_DEBUG_SYMBOLS by default because dtrace tests are + # failing in nightly when the debug info files are ZIP'ed. On + # Solaris debug info files need to be ZIP'ed to reduce the impact + # on disk space footprint. + FULL_DEBUG_SYMBOLS ?= 0 ifeq ($(BUILD_FLAVOR), product) - FULL_DEBUG_SYMBOLS ?= 1 + # FULL_DEBUG_SYMBOLS ?= 1 ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS) else # debug variants always get Full Debug Symbols (if available) - ENABLE_FULL_DEBUG_SYMBOLS = 1 + # ENABLE_FULL_DEBUG_SYMBOLS = 1 + ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS) endif _JUNK_ := $(shell \ echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)") @@ -172,7 +178,9 @@ ifeq ($(JDK6_OR_EARLIER),0) _JUNK_ := $(shell \ echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)") - ZIP_DEBUGINFO_FILES ?= 1 + # Disable ZIP_DEBUGINFO_FILES by default because dtrace tests are + # failing in nightly when the debug info files are ZIP'ed. + ZIP_DEBUGINFO_FILES ?= 0 _JUNK_ := $(shell \ echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)") diff --git a/hotspot/make/windows/makefiles/defs.make b/hotspot/make/windows/makefiles/defs.make index 58e6a606e65..a1c88284cc2 100644 --- a/hotspot/make/windows/makefiles/defs.make +++ b/hotspot/make/windows/makefiles/defs.make @@ -143,7 +143,9 @@ _JUNK_ := $(shell \ MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) - ZIP_DEBUGINFO_FILES ?= 1 + # Disable ZIP_DEBUGINFO_FILES by default because various tests are + # failing in nightly when the debug info files are ZIP'ed. + ZIP_DEBUGINFO_FILES ?= 0 else ZIP_DEBUGINFO_FILES=0 endif From 39c1b4be346f11aed96b70a59afc65c9ae039007 Mon Sep 17 00:00:00 2001 From: Jonathan Lu Date: Thu, 26 Apr 2012 12:39:11 +0800 Subject: [PATCH 34/51] 7154030: java.awt.Component.hide() does not repaint parent component Reviewed-by: rupashka --- .../share/classes/javax/swing/JComponent.java | 36 ++-- .../swing/JComponent/7154030/bug7154030.java | 169 ++++++++++++++++++ 2 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 jdk/test/javax/swing/JComponent/7154030/bug7154030.java diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java index 314a9315e48..78bc5c4f648 100644 --- a/jdk/src/share/classes/javax/swing/JComponent.java +++ b/jdk/src/share/classes/javax/swing/JComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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 @@ -2638,17 +2638,16 @@ public abstract class JComponent extends Container implements Serializable, * attribute: visualUpdate true */ public void setVisible(boolean aFlag) { - if(aFlag != isVisible()) { + if (aFlag != isVisible()) { super.setVisible(aFlag); - Container parent = getParent(); - if(parent != null) { - Rectangle r = getBounds(); - parent.repaint(r.x,r.y,r.width,r.height); + if (aFlag) { + Container parent = getParent(); + if (parent != null) { + Rectangle r = getBounds(); + parent.repaint(r.x, r.y, r.width, r.height); + } + revalidate(); } - // Some (all should) LayoutManagers do not consider components - // that are not visible. As such we need to revalidate when the - // visible bit changes. - revalidate(); } } @@ -5568,4 +5567,21 @@ public abstract class JComponent extends Container implements Serializable, ",preferredSize=" + preferredSizeString; } + /** + * {@inheritDoc} + */ + @Override + public void hide() { + boolean showing = isShowing(); + super.hide(); + if (showing) { + Container parent = getParent(); + if (parent != null) { + Rectangle r = getBounds(); + parent.repaint(r.x, r.y, r.width, r.height); + } + revalidate(); + } + } + } diff --git a/jdk/test/javax/swing/JComponent/7154030/bug7154030.java b/jdk/test/javax/swing/JComponent/7154030/bug7154030.java new file mode 100644 index 00000000000..50007435b55 --- /dev/null +++ b/jdk/test/javax/swing/JComponent/7154030/bug7154030.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2012 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. + */ + +/* + * Portions Copyright (c) 2012 IBM Corporation + */ + +import javax.swing.JButton; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import sun.awt.SunToolkit; + +import java.awt.AWTException; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; + +/* @test 1.1 2012/04/12 + * @bug 7154030 + * @summary Swing components fail to hide after calling hide() + * @author Jonathan Lu + * @library ../../regtesthelpers/ + * @build Util + * @run main bug7154030 + */ + +public class bug7154030 { + + private static JButton button = null; + + public static void main(String[] args) throws Exception { + BufferedImage imageInit = null; + + BufferedImage imageShow = null; + + BufferedImage imageHide = null; + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + JDesktopPane desktop = new JDesktopPane(); + button = new JButton("button"); + JFrame frame = new JFrame(); + + button.setSize(200, 200); + button.setLocation(100, 100); + button.setForeground(Color.RED); + button.setBackground(Color.RED); + button.setOpaque(true); + button.setVisible(false); + desktop.add(button); + + frame.setContentPane(desktop); + frame.setSize(300, 300); + frame.setLocation(0, 0); + frame.setVisible(true); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + } + }); + + toolkit.realSync(); + imageInit = robot.createScreenCapture(new Rectangle(0, 0, 300, 300)); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + button.show(); + } + }); + + toolkit.realSync(); + imageShow = robot.createScreenCapture(new Rectangle(0, 0, 300, 300)); + if (Util.compareBufferedImages(imageInit, imageShow)) { + throw new Exception("Failed to show opaque button"); + } + + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + button.hide(); + } + }); + + toolkit.realSync(); + imageHide = robot.createScreenCapture(new Rectangle(0, 0, 300, 300)); + + if (!Util.compareBufferedImages(imageInit, imageHide)) { + throw new Exception("Failed to hide opaque button"); + } + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + button.setOpaque(false); + button.setBackground(new Color(128, 128, 0)); + button.setVisible(false); + } + }); + + toolkit.realSync(); + imageInit = robot.createScreenCapture(new Rectangle(0, 0, 300, 300)); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + button.show(); + } + }); + + toolkit.realSync(); + imageShow = robot.createScreenCapture(new Rectangle(0, 0, 300, 300)); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + button.hide(); + } + }); + + if (Util.compareBufferedImages(imageInit, imageShow)) { + throw new Exception("Failed to show non-opaque button"); + } + + toolkit.realSync(); + imageHide = robot.createScreenCapture(new Rectangle(0, 0, 300, 300)); + + if (!Util.compareBufferedImages(imageInit, imageHide)) { + throw new Exception("Failed to hide non-opaque button"); + } + } +} From 21e63eca82ab8b04cf42eccafa1218125588f5c8 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 26 Apr 2012 21:16:12 +0400 Subject: [PATCH 35/51] 7124210: [macosx] Replacing text in a TextField does generate an extra TextEvent Reviewed-by: serb --- jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java | 9 +++++++++ .../macosx/classes/sun/lwawt/LWTextComponentPeer.java | 8 ++++---- jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java | 11 ++++++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java index e71ee173c50..ebe97745d49 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java @@ -210,6 +210,15 @@ final class LWTextAreaPeer super(); } + @Override + public void replaceSelection(String content) { + getDocument().removeDocumentListener(LWTextAreaPeer.this); + super.replaceSelection(content); + // post only one text event in this case + postTextEvent(); + getDocument().addDocumentListener(LWTextAreaPeer.this); + } + @Override public boolean hasFocus() { return getTarget().hasFocus(); diff --git a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java index acc2e298b9c..5884b119261 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java @@ -187,7 +187,7 @@ abstract class LWTextComponentPeer Date: Thu, 26 Apr 2012 21:25:14 +0400 Subject: [PATCH 36/51] 7124328: [macosx] javax.swing.JDesktopPane.getAllFramesInLayer returns unexpected value Reviewed-by: anthony --- .../classes/javax/swing/JDesktopPane.java | 62 ++++++++----------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JDesktopPane.java b/jdk/src/share/classes/javax/swing/JDesktopPane.java index 579d65af3d0..85615d3d959 100644 --- a/jdk/src/share/classes/javax/swing/JDesktopPane.java +++ b/jdk/src/share/classes/javax/swing/JDesktopPane.java @@ -27,7 +27,8 @@ package javax.swing; import java.util.List; import java.util.ArrayList; -import java.util.Vector; +import java.util.Collection; +import java.util.Iterator; import javax.swing.plaf.*; import javax.accessibility.*; @@ -42,7 +43,6 @@ import java.io.IOException; import java.beans.PropertyVetoException; import java.util.Set; import java.util.TreeSet; - /** * A container used to create a multiple-document interface or a virtual desktop. * You create JInternalFrame objects and add them to the @@ -261,25 +261,26 @@ public class JDesktopPane extends JLayeredPane implements Accessible * @return an array of JInternalFrame objects */ public JInternalFrame[] getAllFrames() { - int i, count; - JInternalFrame[] results; - Vector vResults = new Vector(10); + return getAllFrames(this).toArray(new JInternalFrame[0]); + } - count = getComponentCount(); - for(i = 0; i < count; i++) { - Component next = getComponent(i); - if(next instanceof JInternalFrame) - vResults.addElement((JInternalFrame) next); - else if(next instanceof JInternalFrame.JDesktopIcon) { - JInternalFrame tmp = ((JInternalFrame.JDesktopIcon)next).getInternalFrame(); - if(tmp != null) - vResults.addElement(tmp); + private static Collection getAllFrames(Container parent) { + int i, count; + Collection results = new ArrayList(); + count = parent.getComponentCount(); + for (i = 0; i < count; i++) { + Component next = parent.getComponent(i); + if (next instanceof JInternalFrame) { + results.add((JInternalFrame) next); + } else if (next instanceof JInternalFrame.JDesktopIcon) { + JInternalFrame tmp = ((JInternalFrame.JDesktopIcon) next).getInternalFrame(); + if (tmp != null) { + results.add(tmp); + } + } else if (next instanceof Container) { + results.addAll(getAllFrames((Container) next)); } } - - results = new JInternalFrame[vResults.size()]; - vResults.copyInto(results); - return results; } @@ -322,27 +323,14 @@ public class JDesktopPane extends JLayeredPane implements Accessible * @see JLayeredPane */ public JInternalFrame[] getAllFramesInLayer(int layer) { - int i, count; - JInternalFrame[] results; - Vector vResults = new Vector(10); - - count = getComponentCount(); - for(i = 0; i < count; i++) { - Component next = getComponent(i); - if(next instanceof JInternalFrame) { - if(((JInternalFrame)next).getLayer() == layer) - vResults.addElement((JInternalFrame) next); - } else if(next instanceof JInternalFrame.JDesktopIcon) { - JInternalFrame tmp = ((JInternalFrame.JDesktopIcon)next).getInternalFrame(); - if(tmp != null && tmp.getLayer() == layer) - vResults.addElement(tmp); + Collection allFrames = getAllFrames(this); + Iterator iterator = allFrames.iterator(); + while (iterator.hasNext()) { + if (iterator.next().getLayer() != layer) { + iterator.remove(); } } - - results = new JInternalFrame[vResults.size()]; - vResults.copyInto(results); - - return results; + return allFrames.toArray(new JInternalFrame[0]); } private List getFrames() { From c53c258233f530b5718fbdfe4a2fe7f0053db292 Mon Sep 17 00:00:00 2001 From: Kurchi Subhra Hazra Date: Thu, 26 Apr 2012 12:04:29 -0700 Subject: [PATCH 37/51] 7118100: (prefs) Inconsistency when using system and user preference on OSX Lion Enable user to read/write preferences to persistent storage Reviewed-by: alanb --- .../java/util/prefs/MacOSXPreferences.java | 10 ++++-- .../util/prefs/MacOSXPreferencesFile.java | 33 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java index 66b3e3af4e0..7a4ef4b6605 100644 --- a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java +++ b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java @@ -231,8 +231,14 @@ class MacOSXPreferences extends AbstractPreferences { if (isRemoved()) throw new IllegalStateException("Node has been removed"); // fixme! overkill - if (!MacOSXPreferencesFile.syncWorld()) { - throw new BackingStoreException("Synchronization failed for node '" + path + "'"); + if (isUser) { + if (!MacOSXPreferencesFile.syncUser()) { + throw new BackingStoreException("Synchronization failed for node '" + path + "'"); + } + } else { + if (!MacOSXPreferencesFile.syncWorld()) { + throw new BackingStoreException("Synchronization failed for node '" + path + "'"); + } } } } diff --git a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java index a5d6293bd8c..7cfb899ddf4 100644 --- a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java +++ b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java @@ -192,6 +192,39 @@ class MacOSXPreferencesFile { } + // Sync only current user preferences + static synchronized boolean syncUser() { + boolean ok = true; + if (cachedFiles != null && !cachedFiles.isEmpty()) { + Iterator iter = cachedFiles.values().iterator(); + while (iter.hasNext()) { + WeakReference ref = iter.next(); + MacOSXPreferencesFile f = (MacOSXPreferencesFile)ref.get(); + if (f != null && f.user == cfCurrentUser) { + if (!f.synchronize()) { + ok = false; + } + } else { + iter.remove(); + } + } + } + // Remove synchronized file from changed file list. The changed files were + // guaranteed to have been in the cached file list (because there was a strong + // reference from changedFiles. + if (changedFiles != null) { + Iterator iterChanged = changedFiles.iterator(); + while (iterChanged.hasNext()) { + MacOSXPreferencesFile f = iterChanged.next(); + if (f != null && f.user == cfCurrentUser) + iterChanged.remove(); + } + } + return ok; + } + + + // Write all prefs changes to disk, but do not clear all cached prefs // values. Also kills any scheduled flush task. // There's no CFPreferencesFlush() (), so lots of cached prefs From 64c6dc258c3ed1b0eecb83ffc1ce611d54afc653 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Thu, 26 Apr 2012 13:16:52 -0700 Subject: [PATCH 38/51] 7013850: Please change the mnemonic assignment system to avoid translation issue Reviewed-by: prr, mfang --- .../classes/sun/print/ServiceDialog.java | 55 +++++++++-- .../sun/print/resources/serviceui.properties | 96 +++++++------------ .../print/resources/serviceui_de.properties | 96 +++++++------------ .../print/resources/serviceui_es.properties | 92 ++++++------------ .../print/resources/serviceui_fr.properties | 96 +++++++------------ .../print/resources/serviceui_it.properties | 96 +++++++------------ .../print/resources/serviceui_ja.properties | 96 +++++++------------ .../print/resources/serviceui_ko.properties | 96 +++++++------------ .../resources/serviceui_pt_BR.properties | 96 +++++++------------ .../print/resources/serviceui_sv.properties | 96 +++++++------------ .../resources/serviceui_zh_CN.properties | 96 +++++++------------ .../resources/serviceui_zh_TW.properties | 96 +++++++------------ 12 files changed, 396 insertions(+), 711 deletions(-) diff --git a/jdk/src/share/classes/sun/print/ServiceDialog.java b/jdk/src/share/classes/sun/print/ServiceDialog.java index 9d2da0c7c91..136b40e487b 100644 --- a/jdk/src/share/classes/sun/print/ServiceDialog.java +++ b/jdk/src/share/classes/sun/print/ServiceDialog.java @@ -72,6 +72,7 @@ import javax.swing.text.NumberFormatter; import sun.print.SunPageSelection; import java.awt.event.KeyEvent; import java.net.URISyntaxException; +import java.lang.reflect.Field; /** @@ -479,20 +480,45 @@ public class ServiceDialog extends JDialog implements ActionListener { */ public static String getMsg(String key) { try { - return messageRB.getString(key); + return removeMnemonics(messageRB.getString(key)); } catch (java.util.MissingResourceException e) { throw new Error("Fatal: Resource for ServiceUI is broken; " + "there is no " + key + " key in resource"); } } + private static String removeMnemonics(String s) { + int i = s.indexOf('&'); + int len = s.length(); + if (i < 0 || i == (len - 1)) { + return s; + } + int j = s.indexOf('&', i+1); + if (j == i+1) { + if (j+1 == len) { + return s.substring(0, i+1); // string ends with && + } else { + return s.substring(0, i+1) + removeMnemonics(s.substring(j+1)); + } + } + // ok first & not double && + if (i == 0) { + return removeMnemonics(s.substring(1)); + } else { + return (s.substring(0, i) + removeMnemonics(s.substring(i+1))); + } + } + + /** * Returns mnemonic character from resource */ private static char getMnemonic(String key) { - String str = getMsg(key + ".mnemonic"); - if ((str != null) && (str.length() > 0)) { - return str.charAt(0); + String str = messageRB.getString(key).replace("&&", ""); + int index = str.indexOf('&'); + if (0 <= index && index < str.length() - 1) { + char c = str.charAt(index + 1); + return Character.toUpperCase(c); } else { return (char)0; } @@ -501,12 +527,23 @@ public class ServiceDialog extends JDialog implements ActionListener { /** * Returns the mnemonic as a KeyEvent.VK constant from the resource. */ + static Class _keyEventClazz = null; private static int getVKMnemonic(String key) { - String str = getMsg(key + ".vkMnemonic"); - if ((str != null) && (str.length() > 0)) { - try { - return Integer.parseInt(str); - } catch (NumberFormatException nfe) {} + String s = String.valueOf(getMnemonic(key)); + if ( s == null || s.length() != 1) { + return 0; + } + String vkString = "VK_" + s.toUpperCase(); + + try { + if (_keyEventClazz == null) { + _keyEventClazz= Class.forName("java.awt.event.KeyEvent", + true, (ServiceDialog.class).getClassLoader()); + } + Field field = _keyEventClazz.getDeclaredField(vkString); + int value = field.getInt(null); + return value; + } catch (Exception e) { } return 0; } diff --git a/jdk/src/share/classes/sun/print/resources/serviceui.properties b/jdk/src/share/classes/sun/print/resources/serviceui.properties index ca244a870d7..6c97dce95b2 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui.properties @@ -14,15 +14,11 @@ border.margins=Margins button.cancel=Cancel button.ok=OK button.print=Print -button.properties=Properties... -button.properties.mnemonic=R +button.properties=P&roperties... # -checkbox.collate=Collate -checkbox.collate.mnemonic=C -checkbox.jobsheets=Banner Page -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=Print To File -checkbox.printtofile.mnemonic=F +checkbox.collate=&Collate +checkbox.jobsheets=&Banner Page +checkbox.printtofile=Print To &File # dialog.printtitle=Print dialog.pstitle=Page Setup @@ -33,70 +29,42 @@ dialog.noprintermsg=No print service found. dialog.writeerror=Cannot write to file: # label.info=Info: -label.jobname=Job Name: -label.jobname.mnemonic=J -label.numcopies=Number of copies: -label.numcopies.mnemonic=O -label.priority=Priority: -label.priority.mnemonic=R -label.psname=Name: -label.psname.mnemonic=N +label.jobname=&Job Name: +label.numcopies=Number &of copies: +label.priority=P&riority: +label.psname=&Name: label.pstype=Type: label.rangeto=To -label.size=Size: -label.size.mnemonic=Z -label.source=Source: -label.source.mnemonic=C +label.size=Si&ze: +label.source=Sour&ce: label.status=Status: -label.username=User Name: -label.username.mnemonic=U +label.username=&User Name: label.millimetres=(mm) label.inches=(in) -label.topmargin=top -label.topmargin.mnemonic=T -label.bottommargin=bottom -label.bottommargin.mnemonic=B -label.leftmargin=left -label.leftmargin.mnemonic=F -label.rightmargin=right -label.rightmargin.mnemonic=R +label.topmargin=&top +label.bottommargin=&bottom +label.leftmargin=le&ft +label.rightmargin=&right # -radiobutton.color=Color -radiobutton.color.mnemonic=C -radiobutton.draftq=Draft -radiobutton.draftq.mnemonic=F -radiobutton.duplex=Duplex -radiobutton.duplex.mnemonic=D -radiobutton.highq=High -radiobutton.highq.mnemonic=H -radiobutton.landscape=Landscape -radiobutton.landscape.mnemonic=L -radiobutton.monochrome=Monochrome -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=Normal -radiobutton.normalq.mnemonic=N -radiobutton.oneside=One Side -radiobutton.oneside.mnemonic=O -radiobutton.portrait=Portrait -radiobutton.portrait.mnemonic=P -radiobutton.rangeall=All -radiobutton.rangeall.mnemonic=L -radiobutton.rangepages=Pages -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=Reverse Landscape -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=Reverse Portrait -radiobutton.revportrait.mnemonic=I -radiobutton.tumble=Tumble -radiobutton.tumble.mnemonic=T +radiobutton.color=&Color +radiobutton.draftq=Dra&ft +radiobutton.duplex=&Duplex +radiobutton.highq=&High +radiobutton.landscape=&Landscape +radiobutton.monochrome=&Monochrome +radiobutton.normalq=&Normal +radiobutton.oneside=&One Side +radiobutton.portrait=&Portrait +radiobutton.rangeall=A&ll +radiobutton.rangepages=Pag&es +radiobutton.revlandscape=Reverse La&ndscape +radiobutton.revportrait=Reverse Portra&it +radiobutton.tumble=&Tumble # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=Appearance -tab.appearance.vkMnemonic=65 -tab.general=General -tab.general.vkMnemonic=71 -tab.pagesetup=Page Setup -tab.pagesetup.vkMnemonic=83 +tab.appearance=&Appearance +tab.general=&General +tab.pagesetup=Page &Setup # error.pagerange=Invalid page range; please re-enter values (e.g. 1-3,5,7-10) error.destination=Invalid filename; please try again diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_de.properties b/jdk/src/share/classes/sun/print/resources/serviceui_de.properties index b89af429b2e..67d06a3312f 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_de.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_de.properties @@ -14,15 +14,11 @@ border.margins=R\u00E4nder button.cancel=Abbrechen button.ok=OK button.print=Drucken -button.properties=Eigenschaften... -button.properties.mnemonic=I +button.properties=E&igenschaften... # -checkbox.collate=Sortieren -checkbox.collate.mnemonic=R -checkbox.jobsheets=Bannerseite -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=Ausgabe in Datei -checkbox.printtofile.mnemonic=U +checkbox.collate=So&rtieren +checkbox.jobsheets=&Bannerseite +checkbox.printtofile=A&usgabe in Datei # dialog.printtitle=Drucken dialog.pstitle=Seite einrichten @@ -33,70 +29,42 @@ dialog.noprintermsg=Kein Druckservice gefunden. dialog.writeerror=Schreiben in Datei nicht m\u00F6glich: # label.info=Info: -label.jobname=Job-Name: -label.jobname.mnemonic=J -label.numcopies=Anzahl Kopien: -label.numcopies.mnemonic=K -label.priority=Priorit\u00E4t: -label.priority.mnemonic=R -label.psname=Name: -label.psname.mnemonic=N +label.jobname=&Job-Name: +label.numcopies=Anzahl &Kopien: +label.priority=P&riorit\u00E4t: +label.psname=&Name: label.pstype=Typ: label.rangeto=Bis -label.size=Gr\u00F6\u00DFe: -label.size.mnemonic=E -label.source=Quelle: -label.source.mnemonic=U +label.size=Gr\u00F6\u00DF&e: +label.source=Q&uelle: label.status=Status: -label.username=Benutzername: -label.username.mnemonic=U +label.username=Ben&utzername: label.millimetres=(mm) label.inches=(Zoll) -label.topmargin=oben -label.topmargin.mnemonic=O -label.bottommargin=unten -label.bottommargin.mnemonic=N -label.leftmargin=links -label.leftmargin.mnemonic=L -label.rightmargin=rechts -label.rightmargin.mnemonic=R +label.topmargin=&oben +label.bottommargin=u&nten +label.leftmargin=&links +label.rightmargin=&rechts # -radiobutton.color=Farbe -radiobutton.color.mnemonic=F -radiobutton.draftq=Entwurf -radiobutton.draftq.mnemonic=W -radiobutton.duplex=Duplex -radiobutton.duplex.mnemonic=P -radiobutton.highq=Hoch -radiobutton.highq.mnemonic=H -radiobutton.landscape=Querformat -radiobutton.landscape.mnemonic=Q -radiobutton.monochrome=Monochrom -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=Normal -radiobutton.normalq.mnemonic=N -radiobutton.oneside=Einseitig -radiobutton.oneside.mnemonic=E -radiobutton.portrait=Hochformat -radiobutton.portrait.mnemonic=H -radiobutton.rangeall=Alle -radiobutton.rangeall.mnemonic=L -radiobutton.rangepages=Seiten -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=Umgekehrtes Querformat -radiobutton.revlandscape.mnemonic=M -radiobutton.revportrait=Umgekehrtes Hochformat -radiobutton.revportrait.mnemonic=K -radiobutton.tumble=Kalenderdruck -radiobutton.tumble.mnemonic=K +radiobutton.color=&Farbe +radiobutton.draftq=Ent&wurf +radiobutton.duplex=Du&plex +radiobutton.highq=&Hoch +radiobutton.landscape=&Querformat +radiobutton.monochrome=&Monochrom +radiobutton.normalq=&Normal +radiobutton.oneside=&Einseitig +radiobutton.portrait=&Hochformat +radiobutton.rangeall=A&lle +radiobutton.rangepages=S&eiten +radiobutton.revlandscape=U&mgekehrtes Querformat +radiobutton.revportrait=Umge&kehrtes Hochformat +radiobutton.tumble=&Kalenderdruck # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=Darstellung -tab.appearance.vkMnemonic=68 -tab.general=Allgemein -tab.general.vkMnemonic=65 -tab.pagesetup=Seite einrichten -tab.pagesetup.vkMnemonic=83 +tab.appearance=&Darstellung +tab.general=&Allgemein +tab.pagesetup=&Seite einrichten # error.pagerange=Ung\u00FCltiger Seitenbereich. Geben Sie die Werte erneut ein (Beispiel: 1-3,5,7-10) error.destination=Ung\u00FCltiger Dateiname. Wiederholen Sie den Vorgang diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_es.properties b/jdk/src/share/classes/sun/print/resources/serviceui_es.properties index ddca5ab9e01..f92f58e8e00 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_es.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_es.properties @@ -14,15 +14,11 @@ border.margins=M\u00E1rgenes button.cancel=Cancelar button.ok=Aceptar button.print=Imprimir -button.properties=Propiedades... -button.properties.mnemonic=R +button.properties=P&ropiedades... # -checkbox.collate=Intercalar -checkbox.collate.mnemonic=C -checkbox.jobsheets=P\u00E1gina de R\u00F3tulo -checkbox.jobsheets.mnemonic=E -checkbox.printtofile=Imprimir en Archivo -checkbox.printtofile.mnemonic=M +checkbox.collate=Inter&calar +checkbox.jobsheets=P\u00E1gina d&e R\u00F3tulo +checkbox.printtofile=I&mprimir en Archivo # dialog.printtitle=Imprimir dialog.pstitle=Preparar P\u00E1gina @@ -33,70 +29,42 @@ dialog.noprintermsg=No se ha encontrado el servicio de impresi\u00F3n. dialog.writeerror=No se puede escribir en el archivo: # label.info=Informaci\u00F3n: -label.jobname=Nombre del Trabajo: -label.jobname.mnemonic=T -label.numcopies=N\u00FAmero de Copias: -label.numcopies.mnemonic=O -label.priority=Prioridad: -label.priority.mnemonic=I -label.psname=Nombre: -label.psname.mnemonic=N +label.jobname=Nombre del &Trabajo: +label.numcopies=N\u00FAmer&o de Copias: +label.priority=Pr&ioridad: +label.psname=&Nombre: label.pstype=Tipo: label.rangeto=A -label.size=Tama\u00F1o: -label.size.mnemonic=T +label.size=&Tama\u00F1o: label.source=Origen: -label.source.mnemonic=O label.status=Estado: -label.username=Usuario: -label.username.mnemonic=S +label.username=U&suario: label.millimetres=(mm) label.inches=(pulg.) label.topmargin=superior -label.topmargin.mnemonic=S -label.bottommargin=inferior -label.bottommargin.mnemonic=F -label.leftmargin=izquierdo -label.leftmargin.mnemonic=Q -label.rightmargin=derecho -label.rightmargin.mnemonic=E +label.bottommargin=in&ferior +label.leftmargin=iz&quierdo +label.rightmargin=d&erecho # -radiobutton.color=Color -radiobutton.color.mnemonic=C -radiobutton.draftq=Borrador -radiobutton.draftq.mnemonic=R -radiobutton.duplex=D\u00FAplex -radiobutton.duplex.mnemonic=D -radiobutton.highq=Alta -radiobutton.highq.mnemonic=L -radiobutton.landscape=Horizontal -radiobutton.landscape.mnemonic=Z -radiobutton.monochrome=Monocromo -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=Normal -radiobutton.normalq.mnemonic=N -radiobutton.oneside=Una Cara -radiobutton.oneside.mnemonic=U -radiobutton.portrait=Vertical -radiobutton.portrait.mnemonic=V -radiobutton.rangeall=Todo -radiobutton.rangeall.mnemonic=T -radiobutton.rangepages=P\u00E1ginas -radiobutton.rangepages.mnemonic=G -radiobutton.revlandscape=Horizontal Inverso -radiobutton.revlandscape.mnemonic=H -radiobutton.revportrait=Vertical Inverso -radiobutton.revportrait.mnemonic=R -radiobutton.tumble=Cambio de Cara -radiobutton.tumble.mnemonic=B +radiobutton.color=&Color +radiobutton.draftq=Bo&rrador +radiobutton.duplex=&D\u00FAplex +radiobutton.highq=A<a +radiobutton.landscape=Hori&zontal +radiobutton.monochrome=&Monocromo +radiobutton.normalq=&Normal +radiobutton.oneside=&Una Cara +radiobutton.portrait=&Vertical +radiobutton.rangeall=&Todo +radiobutton.rangepages=P\u00E1&ginas +radiobutton.revlandscape=&Horizontal Inverso +radiobutton.revportrait=Ve&rtical Inverso +radiobutton.tumble=Cam&bio de Cara # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=Apariencia -tab.appearance.vkMnemonic=65 -tab.general=General -tab.general.vkMnemonic=71 -tab.pagesetup=Preparar P\u00E1gina -tab.pagesetup.vkMnemonic=80 +tab.appearance=&Apariencia +tab.general=&General +tab.pagesetup=&Preparar P\u00E1gina # error.pagerange=Rango de p\u00E1ginas no v\u00E1lido; vuelva a introducir los valores (por ejemplo, 1-3, 5, 7-10) error.destination=Nombre de archivo no v\u00E1lido; int\u00E9ntelo de nuevo diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties index a74d5677454..2b7b160c75a 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties @@ -14,15 +14,11 @@ border.margins=Marges button.cancel=Annuler button.ok=OK button.print=Imprimer -button.properties=Propri\u00E9t\u00E9s... -button.properties.mnemonic=R +button.properties=P&ropri\u00E9t\u00E9s... # -checkbox.collate=Collationner -checkbox.collate.mnemonic=C -checkbox.jobsheets=Page de banni\u00E8re -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=Imprimer dans un fichier -checkbox.printtofile.mnemonic=F +checkbox.collate=&Collationner +checkbox.jobsheets=Page de &banni\u00E8re +checkbox.printtofile=Imprimer dans un &fichier # dialog.printtitle=Imprimer dialog.pstitle=Mise en page @@ -33,70 +29,42 @@ dialog.noprintermsg=Service d'impression introuvable. dialog.writeerror=Impossible d'\u00E9crire dans le fichier : # label.info=Infos : -label.jobname=Nom du travail : -label.jobname.mnemonic=T -label.numcopies=Nombre de copies : -label.numcopies.mnemonic=O -label.priority=Priorit\u00E9 : -label.priority.mnemonic=R -label.psname=Nom : -label.psname.mnemonic=N +label.jobname=Nom du &travail : +label.numcopies=N&ombre de copies : +label.priority=P&riorit\u00E9 : +label.psname=&Nom : label.pstype=Type : label.rangeto=A -label.size=Taille : -label.size.mnemonic=L -label.source=Source : -label.source.mnemonic=C +label.size=Tai&lle : +label.source=Sour&ce : label.status=Statut : -label.username=Nom utilisateur : -label.username.mnemonic=O +label.username=N&om utilisateur : label.millimetres=(mm) label.inches=(po) -label.topmargin=haut -label.topmargin.mnemonic=H -label.bottommargin=bas -label.bottommargin.mnemonic=B -label.leftmargin=gauche -label.leftmargin.mnemonic=G -label.rightmargin=droite -label.rightmargin.mnemonic=D +label.topmargin=&haut +label.bottommargin=&bas +label.leftmargin=&gauche +label.rightmargin=&droite # -radiobutton.color=Couleur -radiobutton.color.mnemonic=C -radiobutton.draftq=Brouillon -radiobutton.draftq.mnemonic=L -radiobutton.duplex=Duplex -radiobutton.duplex.mnemonic=D -radiobutton.highq=Max. -radiobutton.highq.mnemonic=X -radiobutton.landscape=Paysage -radiobutton.landscape.mnemonic=Y -radiobutton.monochrome=Monochrome -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=Normal -radiobutton.normalq.mnemonic=N -radiobutton.oneside=Un c\u00F4t\u00E9 -radiobutton.oneside.mnemonic=U -radiobutton.portrait=Portrait -radiobutton.portrait.mnemonic=P -radiobutton.rangeall=Tout -radiobutton.rangeall.mnemonic=T -radiobutton.rangepages=Pages -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=Paysage invers\u00E9 -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=Portrait invers\u00E9 -radiobutton.revportrait.mnemonic=I -radiobutton.tumble=T\u00EAte-b\u00EAche -radiobutton.tumble.mnemonic=T +radiobutton.color=&Couleur +radiobutton.draftq=Broui&llon +radiobutton.duplex=&Duplex +radiobutton.highq=Ma&x. +radiobutton.landscape=Pa&ysage +radiobutton.monochrome=&Monochrome +radiobutton.normalq=&Normal +radiobutton.oneside=&Un c\u00F4t\u00E9 +radiobutton.portrait=&Portrait +radiobutton.rangeall=&Tout +radiobutton.rangepages=Pag&es +radiobutton.revlandscape=Paysage i&nvers\u00E9 +radiobutton.revportrait=Portra&it invers\u00E9 +radiobutton.tumble=&T\u00EAte-b\u00EAche # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=Apparence -tab.appearance.vkMnemonic=65 -tab.general=G\u00E9n\u00E9ral -tab.general.vkMnemonic=71 -tab.pagesetup=Mise en page -tab.pagesetup.vkMnemonic=83 +tab.appearance=&Apparence +tab.general=&G\u00E9n\u00E9ral +tab.pagesetup=Mi&se en page # error.pagerange=Plage de pages non valide. Sp\u00E9cifiez les valeurs de nouveau (ex. : 1-3,5,7-10) error.destination=Nom de fichier non valide ; recommencez diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_it.properties b/jdk/src/share/classes/sun/print/resources/serviceui_it.properties index e23da1c57ec..a824ef18223 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_it.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_it.properties @@ -14,15 +14,11 @@ border.margins=Margini button.cancel=Annulla button.ok=OK button.print=Stampa -button.properties=Propriet\u00E0... -button.properties.mnemonic=R +button.properties=P&ropriet\u00E0... # -checkbox.collate=Fascicola -checkbox.collate.mnemonic=L -checkbox.jobsheets=Pagina banner -checkbox.jobsheets.mnemonic=P -checkbox.printtofile=Stampa su file -checkbox.printtofile.mnemonic=F +checkbox.collate=Fascico&la +checkbox.jobsheets=&Pagina banner +checkbox.printtofile=Stampa su &file # dialog.printtitle=Stampa dialog.pstitle=Imposta pagina @@ -33,70 +29,42 @@ dialog.noprintermsg=Nessun servizio di stampa trovato dialog.writeerror=Impossibile scrivere nel file: # label.info=Informazioni: -label.jobname=Nome job: -label.jobname.mnemonic=J -label.numcopies=Numero di copie: -label.numcopies.mnemonic=O -label.priority=Priorit\u00E0: -label.priority.mnemonic=I -label.psname=Nome: -label.psname.mnemonic=N +label.jobname=Nome &job: +label.numcopies=Numer&o di copie: +label.priority=Pr&iorit\u00E0: +label.psname=&Nome: label.pstype=Tipo: label.rangeto=A -label.size=Dimensioni: -label.size.mnemonic=M -label.source=Origine: -label.source.mnemonic=R +label.size=Di&mensioni: +label.source=O&rigine: label.status=Stato: -label.username=Nome utente: -label.username.mnemonic=U +label.username=Nome &utente: label.millimetres=(mm) label.inches=(poll.) -label.topmargin=superiore -label.topmargin.mnemonic=P -label.bottommargin=inferiore -label.bottommargin.mnemonic=F -label.leftmargin=sinistro -label.leftmargin.mnemonic=T -label.rightmargin=destro -label.rightmargin.mnemonic=D +label.topmargin=su&periore +label.bottommargin=in&feriore +label.leftmargin=sinis&tro +label.rightmargin=&destro # -radiobutton.color=Colore -radiobutton.color.mnemonic=C -radiobutton.draftq=Bozza -radiobutton.draftq.mnemonic=B -radiobutton.duplex=Fronte retro -radiobutton.duplex.mnemonic=R -radiobutton.highq=Alta -radiobutton.highq.mnemonic=L -radiobutton.landscape=Orizzontale -radiobutton.landscape.mnemonic=L -radiobutton.monochrome=Monocromatico -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=Normale -radiobutton.normalq.mnemonic=N -radiobutton.oneside=Un lato -radiobutton.oneside.mnemonic=O -radiobutton.portrait=Verticale -radiobutton.portrait.mnemonic=V -radiobutton.rangeall=Tutto -radiobutton.rangeall.mnemonic=U -radiobutton.rangepages=Pagine -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=Orizzontale capovolto -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=Verticale capovolto -radiobutton.revportrait.mnemonic=I -radiobutton.tumble=Lato corto -radiobutton.tumble.mnemonic=T +radiobutton.color=&Colore +radiobutton.draftq=&Bozza +radiobutton.duplex=F&ronte retro +radiobutton.highq=A<a +radiobutton.landscape=Orizzonta&le +radiobutton.monochrome=&Monocromatico +radiobutton.normalq=&Normale +radiobutton.oneside=Un lat&o +radiobutton.portrait=&Verticale +radiobutton.rangeall=T&utto +radiobutton.rangepages=Pagin&e +radiobutton.revlandscape=Orizzo&ntale capovolto +radiobutton.revportrait=Vert&icale capovolto +radiobutton.tumble=La&to corto # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=Aspetto -tab.appearance.vkMnemonic=65 -tab.general=Generale -tab.general.vkMnemonic=71 -tab.pagesetup=Imposta pagina -tab.pagesetup.vkMnemonic=83 +tab.appearance=&Aspetto +tab.general=&Generale +tab.pagesetup=Impo&sta pagina # error.pagerange=Intervallo pagine non valido; immettere nuovamente i valori (ad es. 1-3,5,7-10) error.destination=Nome file non valido; riprovare diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_ja.properties b/jdk/src/share/classes/sun/print/resources/serviceui_ja.properties index d707013a300..a6dbd3802ce 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_ja.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_ja.properties @@ -14,15 +14,11 @@ border.margins=\u30DE\u30FC\u30B8\u30F3 button.cancel=\u53D6\u6D88 button.ok=OK button.print=\u5370\u5237 -button.properties=\u30D7\u30ED\u30D1\u30C6\u30A3(R)... -button.properties.mnemonic=R +button.properties=\u30D7\u30ED\u30D1\u30C6\u30A3(&R)... # -checkbox.collate=\u4E01\u5408\u3044(C) -checkbox.collate.mnemonic=C -checkbox.jobsheets=\u30D0\u30CA\u30FC\u30FB\u30DA\u30FC\u30B8(B) -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=\u30D5\u30A1\u30A4\u30EB\u306B\u51FA\u529B(F) -checkbox.printtofile.mnemonic=F +checkbox.collate=\u4E01\u5408\u3044(&C) +checkbox.jobsheets=\u30D0\u30CA\u30FC\u30FB\u30DA\u30FC\u30B8(&B) +checkbox.printtofile=\u30D5\u30A1\u30A4\u30EB\u306B\u51FA\u529B(&F) # dialog.printtitle=\u5370\u5237 dialog.pstitle=\u30DA\u30FC\u30B8\u8A2D\u5B9A @@ -33,70 +29,42 @@ dialog.noprintermsg=\u5370\u5237\u30B5\u30FC\u30D3\u30B9\u304C\u898B\u3064\u304B dialog.writeerror=\u30D5\u30A1\u30A4\u30EB\u306B\u66F8\u304D\u8FBC\u3081\u307E\u305B\u3093: # label.info=\u60C5\u5831: -label.jobname=\u30B8\u30E7\u30D6\u540D(J): -label.jobname.mnemonic=J -label.numcopies=\u5370\u5237\u90E8\u6570(O): -label.numcopies.mnemonic=O -label.priority=\u512A\u5148\u5EA6(R): -label.priority.mnemonic=R -label.psname=\u540D\u524D(N): -label.psname.mnemonic=N +label.jobname=\u30B8\u30E7\u30D6\u540D(&J): +label.numcopies=\u5370\u5237\u90E8\u6570(&O): +label.priority=\u512A\u5148\u5EA6(&R): +label.psname=\u540D\u524D(&N): label.pstype=\u30BF\u30A4\u30D7: label.rangeto=\u5370\u5237\u7BC4\u56F2 -label.size=\u30B5\u30A4\u30BA(Z): -label.size.mnemonic=Z -label.source=\u30BD\u30FC\u30B9(C): -label.source.mnemonic=C +label.size=\u30B5\u30A4\u30BA(&Z): +label.source=\u30BD\u30FC\u30B9(&C): label.status=\u72B6\u614B: -label.username=\u30E6\u30FC\u30B6\u30FC\u540D(U): -label.username.mnemonic=U +label.username=\u30E6\u30FC\u30B6\u30FC\u540D(&U): label.millimetres=(mm) label.inches=(in) -label.topmargin=\u4E0A(T) -label.topmargin.mnemonic=T -label.bottommargin=\u4E0B(B) -label.bottommargin.mnemonic=B -label.leftmargin=\u5DE6(F) -label.leftmargin.mnemonic=F -label.rightmargin=\u53F3(R) -label.rightmargin.mnemonic=R +label.topmargin=\u4E0A(&T) +label.bottommargin=\u4E0B(&B) +label.leftmargin=\u5DE6(&F) +label.rightmargin=\u53F3(&R) # -radiobutton.color=\u30AB\u30E9\u30FC(C) -radiobutton.color.mnemonic=C -radiobutton.draftq=\u30C9\u30E9\u30D5\u30C8(F) -radiobutton.draftq.mnemonic=F -radiobutton.duplex=\u4E21\u9762(D) -radiobutton.duplex.mnemonic=D -radiobutton.highq=\u9AD8(H) -radiobutton.highq.mnemonic=H -radiobutton.landscape=\u6A2A(L) -radiobutton.landscape.mnemonic=L -radiobutton.monochrome=\u30E2\u30CE\u30AF\u30ED(M) -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=\u6A19\u6E96(N) -radiobutton.normalq.mnemonic=N -radiobutton.oneside=\u7247\u9762(O) -radiobutton.oneside.mnemonic=O -radiobutton.portrait=\u7E26(P) -radiobutton.portrait.mnemonic=P -radiobutton.rangeall=\u3059\u3079\u3066(L) -radiobutton.rangeall.mnemonic=L -radiobutton.rangepages=\u30DA\u30FC\u30B8(E) -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=\u30E9\u30F3\u30C9\u30B9\u30B1\u30FC\u30D7(\u53CD\u8EE2)(N) -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=\u30DD\u30FC\u30C8\u30EC\u30A4\u30C8(\u53CD\u8EE2)(I) -radiobutton.revportrait.mnemonic=I -radiobutton.tumble=\u53CD\u8EE2(T) -radiobutton.tumble.mnemonic=T +radiobutton.color=\u30AB\u30E9\u30FC(&C) +radiobutton.draftq=\u30C9\u30E9\u30D5\u30C8(&F) +radiobutton.duplex=\u4E21\u9762(&D) +radiobutton.highq=\u9AD8(&H) +radiobutton.landscape=\u6A2A(&L) +radiobutton.monochrome=\u30E2\u30CE\u30AF\u30ED(&M) +radiobutton.normalq=\u6A19\u6E96(&N) +radiobutton.oneside=\u7247\u9762(&O) +radiobutton.portrait=\u7E26(&P) +radiobutton.rangeall=\u3059\u3079\u3066(&L) +radiobutton.rangepages=\u30DA\u30FC\u30B8(&E) +radiobutton.revlandscape=\u30E9\u30F3\u30C9\u30B9\u30B1\u30FC\u30D7(\u53CD\u8EE2)(&N) +radiobutton.revportrait=\u30DD\u30FC\u30C8\u30EC\u30A4\u30C8(\u53CD\u8EE2)(&I) +radiobutton.tumble=\u53CD\u8EE2(&T) # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=\u5916\u89B3(A) -tab.appearance.vkMnemonic=65 -tab.general=\u4E00\u822C(G) -tab.general.vkMnemonic=71 -tab.pagesetup=\u30DA\u30FC\u30B8\u8A2D\u5B9A(S) -tab.pagesetup.vkMnemonic=83 +tab.appearance=\u5916\u89B3(&A) +tab.general=\u4E00\u822C(&G) +tab.pagesetup=\u30DA\u30FC\u30B8\u8A2D\u5B9A(&S) # error.pagerange=\u7121\u52B9\u306A\u30DA\u30FC\u30B8\u7BC4\u56F2\u3002\u5024\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044(\u4F8B\u30011-3,5,7-10) error.destination=\u7121\u52B9\u306A\u30D5\u30A1\u30A4\u30EB\u540D\u3002\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044 diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_ko.properties b/jdk/src/share/classes/sun/print/resources/serviceui_ko.properties index d4acf2fea3e..e0db7aa7098 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_ko.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_ko.properties @@ -14,15 +14,11 @@ border.margins=\uC5EC\uBC31 button.cancel=\uCDE8\uC18C button.ok=\uD655\uC778 button.print=\uC778\uC1C4 -button.properties=\uC18D\uC131(R)... -button.properties.mnemonic=R +button.properties=\uC18D\uC131(&R)... # -checkbox.collate=\uD55C \uBD80\uC529 \uC778\uC1C4(C) -checkbox.collate.mnemonic=C -checkbox.jobsheets=\uBC30\uB108 \uD398\uC774\uC9C0(B) -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=\uD30C\uC77C\uB85C \uC778\uC1C4(F) -checkbox.printtofile.mnemonic=F +checkbox.collate=\uD55C \uBD80\uC529 \uC778\uC1C4(&C) +checkbox.jobsheets=\uBC30\uB108 \uD398\uC774\uC9C0(&B) +checkbox.printtofile=\uD30C\uC77C\uB85C \uC778\uC1C4(&F) # dialog.printtitle=\uC778\uC1C4 dialog.pstitle=\uD398\uC774\uC9C0 \uC124\uC815 @@ -33,70 +29,42 @@ dialog.noprintermsg=\uC778\uC1C4 \uC11C\uBE44\uC2A4\uB97C \uCC3E\uC744 \uC218 \u dialog.writeerror=\uD30C\uC77C\uC5D0 \uC4F8 \uC218 \uC5C6\uC74C: # label.info=\uC815\uBCF4: -label.jobname=\uC791\uC5C5 \uC774\uB984(J): -label.jobname.mnemonic=J -label.numcopies=\uB9E4\uC218(O): -label.numcopies.mnemonic=O -label.priority=\uC6B0\uC120\uC21C\uC704(R): -label.priority.mnemonic=R -label.psname=\uC774\uB984(N): -label.psname.mnemonic=N +label.jobname=\uC791\uC5C5 \uC774\uB984(&J): +label.numcopies=\uB9E4\uC218(&O): +label.priority=\uC6B0\uC120\uC21C\uC704(&R): +label.psname=\uC774\uB984(&N): label.pstype=\uC720\uD615: label.rangeto=\uC885\uB8CC -label.size=\uD06C\uAE30(Z): -label.size.mnemonic=Z -label.source=\uC18C\uC2A4(C): -label.source.mnemonic=C +label.size=\uD06C\uAE30(&Z): +label.source=\uC18C\uC2A4(&C): label.status=\uC0C1\uD0DC: -label.username=\uC0AC\uC6A9\uC790 \uC774\uB984(U): -label.username.mnemonic=U +label.username=\uC0AC\uC6A9\uC790 \uC774\uB984(&U): label.millimetres=(mm) label.inches=(\uC778\uCE58) -label.topmargin=\uC704\uCABD(T) -label.topmargin.mnemonic=T -label.bottommargin=\uC544\uB798\uCABD(B) -label.bottommargin.mnemonic=B -label.leftmargin=\uC67C\uCABD(F) -label.leftmargin.mnemonic=F -label.rightmargin=\uC624\uB978\uCABD(R) -label.rightmargin.mnemonic=R +label.topmargin=\uC704\uCABD(&T) +label.bottommargin=\uC544\uB798\uCABD(&B) +label.leftmargin=\uC67C\uCABD(&F) +label.rightmargin=\uC624\uB978\uCABD(&R) # -radiobutton.color=\uC0C9\uC0C1(C) -radiobutton.color.mnemonic=C -radiobutton.draftq=\uCD08\uC548(F) -radiobutton.draftq.mnemonic=F -radiobutton.duplex=\uC591\uBA74(D) -radiobutton.duplex.mnemonic=D -radiobutton.highq=\uB192\uC74C(H) -radiobutton.highq.mnemonic=H -radiobutton.landscape=\uAC00\uB85C(L) -radiobutton.landscape.mnemonic=L -radiobutton.monochrome=\uB2E8\uC0C9(M) -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=\uBCF4\uD1B5(N) -radiobutton.normalq.mnemonic=N -radiobutton.oneside=\uB2E8\uBA74(O) -radiobutton.oneside.mnemonic=O -radiobutton.portrait=\uC138\uB85C(P) -radiobutton.portrait.mnemonic=P -radiobutton.rangeall=\uC804\uCCB4(L) -radiobutton.rangeall.mnemonic=L -radiobutton.rangepages=\uD398\uC774\uC9C0(E) -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=\uAC00\uB85C \uBC18\uC804(N) -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=\uC138\uB85C \uBC18\uC804(I) -radiobutton.revportrait.mnemonic=I -radiobutton.tumble=\uD68C\uC804\uC2DD(T) -radiobutton.tumble.mnemonic=T +radiobutton.color=\uC0C9\uC0C1(&C) +radiobutton.draftq=\uCD08\uC548(&F) +radiobutton.duplex=\uC591\uBA74(&D) +radiobutton.highq=\uB192\uC74C(&H) +radiobutton.landscape=\uAC00\uB85C(&L) +radiobutton.monochrome=\uB2E8\uC0C9(&M) +radiobutton.normalq=\uBCF4\uD1B5(&N) +radiobutton.oneside=\uB2E8\uBA74(&O) +radiobutton.portrait=\uC138\uB85C(&P) +radiobutton.rangeall=\uC804\uCCB4(&L) +radiobutton.rangepages=\uD398\uC774\uC9C0(&E) +radiobutton.revlandscape=\uAC00\uB85C \uBC18\uC804(&N) +radiobutton.revportrait=\uC138\uB85C \uBC18\uC804(&I) +radiobutton.tumble=\uD68C\uC804\uC2DD(&T) # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=\uBAA8\uC591(A) -tab.appearance.vkMnemonic=65 -tab.general=\uC77C\uBC18 \uC0AC\uD56D(G) -tab.general.vkMnemonic=71 -tab.pagesetup=\uD398\uC774\uC9C0 \uC124\uC815(S) -tab.pagesetup.vkMnemonic=83 +tab.appearance=\uBAA8\uC591(&A) +tab.general=\uC77C\uBC18 \uC0AC\uD56D(&G) +tab.pagesetup=\uD398\uC774\uC9C0 \uC124\uC815(&S) # error.pagerange=\uBD80\uC801\uD569\uD55C \uD398\uC774\uC9C0 \uBC94\uC704: \uAC12\uC744 \uB2E4\uC2DC \uC785\uB825\uD558\uC2ED\uC2DC\uC624(\uC608: 1-3,5,7-10). error.destination=\uBD80\uC801\uD569\uD55C \uD30C\uC77C \uC774\uB984: \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC2ED\uC2DC\uC624. diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties index d82178f3a4e..fbd00aa9569 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties @@ -14,15 +14,11 @@ border.margins=Margens button.cancel=Cancelar button.ok=OK button.print=Imprimir -button.properties=Propriedades... -button.properties.mnemonic=D +button.properties=Proprie&dades... # -checkbox.collate=Agrupar -checkbox.collate.mnemonic=R -checkbox.jobsheets=P\u00E1gina com Banner -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=Imprimir em Arquivo -checkbox.printtofile.mnemonic=I +checkbox.collate=Ag&rupar +checkbox.jobsheets=P\u00E1gina com &Banner +checkbox.printtofile=&Imprimir em Arquivo # dialog.printtitle=Imprimir dialog.pstitle=Configura\u00E7\u00E3o da P\u00E1gina @@ -33,70 +29,42 @@ dialog.noprintermsg=Nenhum servi\u00E7o de impress\u00E3o encontrado. dialog.writeerror=N\u00E3o \u00E9 poss\u00EDvel gravar no arquivo: # label.info=Informa\u00E7\u00F5es: -label.jobname=Nome do Job: -label.jobname.mnemonic=J -label.numcopies=N\u00FAmero de c\u00F3pias: -label.numcopies.mnemonic=O -label.priority=Prioridade: -label.priority.mnemonic=P -label.psname=Nome: -label.psname.mnemonic=N +label.jobname=Nome do &Job: +label.numcopies=N\u00FAmer&o de c\u00F3pias: +label.priority=&Prioridade: +label.psname=&Nome: label.pstype=Tipo: label.rangeto=At\u00E9 -label.size=Tamanho: -label.size.mnemonic=M -label.source=Origem: -label.source.mnemonic=O +label.size=Ta&manho: +label.source=&Origem: label.status=Status: -label.username=Nome do Usu\u00E1rio: -label.username.mnemonic=U +label.username=Nome do &Usu\u00E1rio: label.millimetres=(mm) label.inches=(pol) -label.topmargin=superior -label.topmargin.mnemonic=S -label.bottommargin=inferior -label.bottommargin.mnemonic=I -label.leftmargin=esquerda: -label.leftmargin.mnemonic=Q -label.rightmargin=direita -label.rightmargin.mnemonic=D +label.topmargin=&superior +label.bottommargin=&inferior +label.leftmargin=es&querda: +label.rightmargin=&direita # -radiobutton.color=Cor -radiobutton.color.mnemonic=O -radiobutton.draftq=Rascunho -radiobutton.draftq.mnemonic=R -radiobutton.duplex=Duplex -radiobutton.duplex.mnemonic=D -radiobutton.highq=Alta -radiobutton.highq.mnemonic=T -radiobutton.landscape=Paisagem -radiobutton.landscape.mnemonic=P -radiobutton.monochrome=Monocrom\u00E1tico -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=Normal -radiobutton.normalq.mnemonic=N -radiobutton.oneside=Um Lado -radiobutton.oneside.mnemonic=L -radiobutton.portrait=Retrato -radiobutton.portrait.mnemonic=R -radiobutton.rangeall=Tudo -radiobutton.rangeall.mnemonic=U -radiobutton.rangepages=P\u00E1ginas -radiobutton.rangepages.mnemonic=P -radiobutton.revlandscape=Paisagem Invertida -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=Retrato Invertido -radiobutton.revportrait.mnemonic=E -radiobutton.tumble=Virar -radiobutton.tumble.mnemonic=V +radiobutton.color=C&or +radiobutton.draftq=&Rascunho +radiobutton.duplex=&Duplex +radiobutton.highq=Al&ta +radiobutton.landscape=&Paisagem +radiobutton.monochrome=&Monocrom\u00E1tico +radiobutton.normalq=&Normal +radiobutton.oneside=Um &Lado +radiobutton.portrait=&Retrato +radiobutton.rangeall=T&udo +radiobutton.rangepages=&P\u00E1ginas +radiobutton.revlandscape=Paisagem I&nvertida +radiobutton.revportrait=R&etrato Invertido +radiobutton.tumble=&Virar # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=Apar\u00EAncia -tab.appearance.vkMnemonic=65 -tab.general=Geral -tab.general.vkMnemonic=71 -tab.pagesetup=Configura\u00E7\u00E3o de P\u00E1gina -tab.pagesetup.vkMnemonic=67 +tab.appearance=&Apar\u00EAncia +tab.general=&Geral +tab.pagesetup=&Configura\u00E7\u00E3o de P\u00E1gina # error.pagerange=Faixa de p\u00E1ginas inv\u00E1lida; insira novamente os valores (por exemplo, 1-3,5,7-10) error.destination=Nome de arquivo inv\u00E1lido; tente novamente diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties b/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties index 859c0494610..35ae3741fdc 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties @@ -14,15 +14,11 @@ border.margins=Marginaler button.cancel=Avbryt button.ok=OK button.print=Skriv ut -button.properties=Egenskaper... -button.properties.mnemonic=R +button.properties=Egenskape&r... # -checkbox.collate=Sortera -checkbox.collate.mnemonic=T -checkbox.jobsheets=F\u00F6rs\u00E4ttsblad -checkbox.jobsheets.mnemonic=R -checkbox.printtofile=Skriv ut till fil -checkbox.printtofile.mnemonic=K +checkbox.collate=Sor&tera +checkbox.jobsheets=F\u00F6&rs\u00E4ttsblad +checkbox.printtofile=S&kriv ut till fil # dialog.printtitle=Skriv ut dialog.pstitle=Utskriftsformat @@ -33,70 +29,42 @@ dialog.noprintermsg=Hittade ingen utskriftstj\u00E4nst. dialog.writeerror=Kan inte skriva till filen: # label.info=Information: -label.jobname=Utskrift: -label.jobname.mnemonic=U -label.numcopies=Antal exemplar: -label.numcopies.mnemonic=E -label.priority=Prioritet: -label.priority.mnemonic=R -label.psname=Namn: -label.psname.mnemonic=N +label.jobname=&Utskrift: +label.numcopies=Antal &exemplar: +label.priority=P&rioritet: +label.psname=&Namn: label.pstype=Typ: label.rangeto=Till -label.size=Storlek: -label.size.mnemonic=O -label.source=K\u00E4lla: -label.source.mnemonic=K +label.size=St&orlek: +label.source=&K\u00E4lla: label.status=Status: -label.username=Anv\u00E4ndarnamn: -label.username.mnemonic=N +label.username=A&nv\u00E4ndarnamn: label.millimetres=(mm) label.inches=(tum) -label.topmargin=\u00F6verkant -label.topmargin.mnemonic=R -label.bottommargin=nederkant -label.bottommargin.mnemonic=N -label.leftmargin=v\u00E4nster -label.leftmargin.mnemonic=V -label.rightmargin=h\u00F6ger -label.rightmargin.mnemonic=H +label.topmargin=\u00F6ve&rkant +label.bottommargin=&nederkant +label.leftmargin=&v\u00E4nster +label.rightmargin=&h\u00F6ger # -radiobutton.color=F\u00E4rg -radiobutton.color.mnemonic=G -radiobutton.draftq=Utkast -radiobutton.draftq.mnemonic=K -radiobutton.duplex=Dubbelsidig -radiobutton.duplex.mnemonic=D -radiobutton.highq=H\u00F6g -radiobutton.highq.mnemonic=H -radiobutton.landscape=Liggande -radiobutton.landscape.mnemonic=L -radiobutton.monochrome=Monokrom -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=Normal -radiobutton.normalq.mnemonic=O -radiobutton.oneside=Ensidig -radiobutton.oneside.mnemonic=E -radiobutton.portrait=St\u00E5ende -radiobutton.portrait.mnemonic=D -radiobutton.rangeall=Alla -radiobutton.rangeall.mnemonic=L -radiobutton.rangepages=Sidor -radiobutton.rangepages.mnemonic=D -radiobutton.revlandscape=Omv\u00E4nt liggande -radiobutton.revlandscape.mnemonic=G -radiobutton.revportrait=Omv\u00E4nt st\u00E5ende -radiobutton.revportrait.mnemonic=M -radiobutton.tumble=V\u00E4nd -radiobutton.tumble.mnemonic=V +radiobutton.color=F\u00E4r&g +radiobutton.draftq=Ut&kast +radiobutton.duplex=&Dubbelsidig +radiobutton.highq=&H\u00F6g +radiobutton.landscape=&Liggande +radiobutton.monochrome=&Monokrom +radiobutton.normalq=N&ormal +radiobutton.oneside=&Ensidig +radiobutton.portrait=St\u00E5en&de +radiobutton.rangeall=A&lla +radiobutton.rangepages=Si&dor +radiobutton.revlandscape=Omv\u00E4nt li&ggande +radiobutton.revportrait=O&mv\u00E4nt st\u00E5ende +radiobutton.tumble=&V\u00E4nd # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=Format -tab.appearance.vkMnemonic=70 -tab.general=Allm\u00E4nt -tab.general.vkMnemonic=65 -tab.pagesetup=Utskriftsformat -tab.pagesetup.vkMnemonic=83 +tab.appearance=&Format +tab.general=&Allm\u00E4nt +tab.pagesetup=Ut&skriftsformat # error.pagerange=Ogiltigt sidintervall. Skriv in v\u00E4rdena igen (t ex 1-3,5,7-10) error.destination=Ogiltigt filnamn. F\u00F6rs\u00F6k igen. diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_zh_CN.properties b/jdk/src/share/classes/sun/print/resources/serviceui_zh_CN.properties index 98824cc9ae2..2d2f91b4219 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_zh_CN.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_zh_CN.properties @@ -14,15 +14,11 @@ border.margins=\u8FB9\u8DDD button.cancel=\u53D6\u6D88 button.ok=\u786E\u5B9A button.print=\u6253\u5370 -button.properties=\u5C5E\u6027(R)... -button.properties.mnemonic=R +button.properties=\u5C5E\u6027(&R)... # -checkbox.collate=\u9010\u4EFD\u6253\u5370(C) -checkbox.collate.mnemonic=C -checkbox.jobsheets=\u6807\u5E1C\u9875(B) -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=\u6253\u5370\u5230\u6587\u4EF6(F) -checkbox.printtofile.mnemonic=F +checkbox.collate=\u9010\u4EFD\u6253\u5370(&C) +checkbox.jobsheets=\u6807\u5E1C\u9875(&B) +checkbox.printtofile=\u6253\u5370\u5230\u6587\u4EF6(&F) # dialog.printtitle=\u6253\u5370 dialog.pstitle=\u9875\u9762\u8BBE\u7F6E @@ -33,70 +29,42 @@ dialog.noprintermsg=\u627E\u4E0D\u5230\u6253\u5370\u670D\u52A1\u3002 dialog.writeerror=\u65E0\u6CD5\u5199\u5165\u6587\u4EF6: # label.info=\u4FE1\u606F: -label.jobname=\u4F5C\u4E1A\u540D(J): -label.jobname.mnemonic=J -label.numcopies=\u6253\u5370\u4EFD\u6570(O): -label.numcopies.mnemonic=O -label.priority=\u4F18\u5148\u7EA7(R): -label.priority.mnemonic=R -label.psname=\u540D\u79F0(N): -label.psname.mnemonic=N +label.jobname=\u4F5C\u4E1A\u540D(&J): +label.numcopies=\u6253\u5370\u4EFD\u6570(&O): +label.priority=\u4F18\u5148\u7EA7(&R): +label.psname=\u540D\u79F0(&N): label.pstype=\u7C7B\u578B: label.rangeto=\u81F3 -label.size=\u5927\u5C0F(Z): -label.size.mnemonic=Z -label.source=\u6765\u6E90(C): -label.source.mnemonic=C +label.size=\u5927\u5C0F(&Z): +label.source=\u6765\u6E90(&C): label.status=\u72B6\u6001: -label.username=\u7528\u6237\u540D(U): -label.username.mnemonic=U +label.username=\u7528\u6237\u540D(&U): label.millimetres=(\u6BEB\u7C73) label.inches=(\u82F1\u5BF8) -label.topmargin=\u4E0A\u8FB9\u8DDD(T) -label.topmargin.mnemonic=T -label.bottommargin=\u4E0B\u8FB9\u8DDD(B) -label.bottommargin.mnemonic=B -label.leftmargin=\u5DE6\u8FB9\u8DDD(F) -label.leftmargin.mnemonic=F -label.rightmargin=\u53F3\u8FB9\u8DDD(R) -label.rightmargin.mnemonic=R +label.topmargin=\u4E0A\u8FB9\u8DDD(&T) +label.bottommargin=\u4E0B\u8FB9\u8DDD(&B) +label.leftmargin=\u5DE6\u8FB9\u8DDD(&F) +label.rightmargin=\u53F3\u8FB9\u8DDD(&R) # -radiobutton.color=\u989C\u8272(C) -radiobutton.color.mnemonic=C -radiobutton.draftq=\u8349\u56FE(F) -radiobutton.draftq.mnemonic=F -radiobutton.duplex=\u53CC\u9762\u6253\u5370(D) -radiobutton.duplex.mnemonic=D -radiobutton.highq=\u9AD8(H) -radiobutton.highq.mnemonic=H -radiobutton.landscape=\u6A2A\u5411(L) -radiobutton.landscape.mnemonic=L -radiobutton.monochrome=\u5355\u8272(M) -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=\u6B63\u5E38(N) -radiobutton.normalq.mnemonic=N -radiobutton.oneside=\u5355\u9762(O) -radiobutton.oneside.mnemonic=O -radiobutton.portrait=\u7EB5\u5411(P) -radiobutton.portrait.mnemonic=P -radiobutton.rangeall=\u5168\u90E8(L) -radiobutton.rangeall.mnemonic=L -radiobutton.rangepages=\u9875\u7801\u8303\u56F4(E) -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=\u6A2A\u5411\u53CD\u9762\u6253\u5370(N) -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=\u7EB5\u5411\u53CD\u9762\u6253\u5370(I) -radiobutton.revportrait.mnemonic=I -radiobutton.tumble=\u7FFB\u8F6C(T) -radiobutton.tumble.mnemonic=T +radiobutton.color=\u989C\u8272(&C) +radiobutton.draftq=\u8349\u56FE(&F) +radiobutton.duplex=\u53CC\u9762\u6253\u5370(&D) +radiobutton.highq=\u9AD8(&H) +radiobutton.landscape=\u6A2A\u5411(&L) +radiobutton.monochrome=\u5355\u8272(&M) +radiobutton.normalq=\u6B63\u5E38(&N) +radiobutton.oneside=\u5355\u9762(&O) +radiobutton.portrait=\u7EB5\u5411(&P) +radiobutton.rangeall=\u5168\u90E8(&L) +radiobutton.rangepages=\u9875\u7801\u8303\u56F4(&E) +radiobutton.revlandscape=\u6A2A\u5411\u53CD\u9762\u6253\u5370(&N) +radiobutton.revportrait=\u7EB5\u5411\u53CD\u9762\u6253\u5370(&I) +radiobutton.tumble=\u7FFB\u8F6C(&T) # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=\u5916\u89C2(A) -tab.appearance.vkMnemonic=65 -tab.general=\u4E00\u822C\u4FE1\u606F(G) -tab.general.vkMnemonic=71 -tab.pagesetup=\u9875\u9762\u8BBE\u7F6E(S) -tab.pagesetup.vkMnemonic=83 +tab.appearance=\u5916\u89C2(&A) +tab.general=\u4E00\u822C\u4FE1\u606F(&G) +tab.pagesetup=\u9875\u9762\u8BBE\u7F6E(&S) # error.pagerange=\u65E0\u6548\u7684\u9875\u9762\u8303\u56F4; \u8BF7\u91CD\u65B0\u8F93\u5165\u6570\u503C (\u4F8B\u5982 1-3,5,7-10) error.destination=\u65E0\u6548\u7684\u6587\u4EF6\u540D; \u8BF7\u91CD\u8BD5 diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_zh_TW.properties b/jdk/src/share/classes/sun/print/resources/serviceui_zh_TW.properties index d6a796325ea..41ce68ca516 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_zh_TW.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_zh_TW.properties @@ -14,15 +14,11 @@ border.margins=\u908A\u8DDD button.cancel=\u53D6\u6D88 button.ok=\u78BA\u5B9A button.print=\u5217\u5370 -button.properties=\u7279\u6027(R)... -button.properties.mnemonic=R +button.properties=\u7279\u6027(&R)... # -checkbox.collate=\u7406\u5E8F(C) -checkbox.collate.mnemonic=C -checkbox.jobsheets=\u6A19\u984C\u9801(B) -checkbox.jobsheets.mnemonic=B -checkbox.printtofile=\u5217\u5370\u81F3\u6A94\u6848(F) -checkbox.printtofile.mnemonic=F +checkbox.collate=\u7406\u5E8F(&C) +checkbox.jobsheets=\u6A19\u984C\u9801(&B) +checkbox.printtofile=\u5217\u5370\u81F3\u6A94\u6848(&F) # dialog.printtitle=\u5217\u5370 dialog.pstitle=\u9801\u9762\u8A2D\u5B9A @@ -33,70 +29,42 @@ dialog.noprintermsg=\u627E\u4E0D\u5230\u5217\u5370\u670D\u52D9\u3002 dialog.writeerror=\u7121\u6CD5\u5BEB\u5165\u81F3\u6A94\u6848: # label.info=\u8CC7\u8A0A: -label.jobname=\u5DE5\u4F5C\u540D\u7A31(J): -label.jobname.mnemonic=J -label.numcopies=\u5217\u5370\u4EFD\u6578(O): -label.numcopies.mnemonic=O -label.priority=\u512A\u5148\u6B0A(R): -label.priority.mnemonic=R -label.psname=\u540D\u7A31(N): -label.psname.mnemonic=N +label.jobname=\u5DE5\u4F5C\u540D\u7A31(&J): +label.numcopies=\u5217\u5370\u4EFD\u6578(&O): +label.priority=\u512A\u5148\u6B0A(&R): +label.psname=\u540D\u7A31(&N): label.pstype=\u985E\u578B: label.rangeto=\u81F3 -label.size=\u5927\u5C0F(Z): -label.size.mnemonic=Z -label.source=\u4F86\u6E90(C): -label.source.mnemonic=C +label.size=\u5927\u5C0F(&Z): +label.source=\u4F86\u6E90(&C): label.status=\u72C0\u614B: -label.username=\u4F7F\u7528\u8005\u540D\u7A31(U): -label.username.mnemonic=U +label.username=\u4F7F\u7528\u8005\u540D\u7A31(&U): label.millimetres=(mm) label.inches=(in) -label.topmargin=\u9802\u7AEF\u908A\u8DDD(T) -label.topmargin.mnemonic=T -label.bottommargin=\u5E95\u90E8\u908A\u8DDD(B) -label.bottommargin.mnemonic=B -label.leftmargin=\u5DE6\u908A\u8DDD(F) -label.leftmargin.mnemonic=F -label.rightmargin=\u53F3\u908A\u8DDD(R) -label.rightmargin.mnemonic=R +label.topmargin=\u9802\u7AEF\u908A\u8DDD(&T) +label.bottommargin=\u5E95\u90E8\u908A\u8DDD(&B) +label.leftmargin=\u5DE6\u908A\u8DDD(&F) +label.rightmargin=\u53F3\u908A\u8DDD(&R) # -radiobutton.color=\u984F\u8272(C) -radiobutton.color.mnemonic=C -radiobutton.draftq=\u8349\u7A3F(F) -radiobutton.draftq.mnemonic=F -radiobutton.duplex=\u96D9\u9762\u5217\u5370(D) -radiobutton.duplex.mnemonic=D -radiobutton.highq=\u9AD8(H) -radiobutton.highq.mnemonic=H -radiobutton.landscape=\u6A6B\u5411(L) -radiobutton.landscape.mnemonic=L -radiobutton.monochrome=\u55AE\u8272(M) -radiobutton.monochrome.mnemonic=M -radiobutton.normalq=\u6B63\u5E38(N) -radiobutton.normalq.mnemonic=N -radiobutton.oneside=\u55AE\u9762(O) -radiobutton.oneside.mnemonic=O -radiobutton.portrait=\u76F4\u5411(P) -radiobutton.portrait.mnemonic=P -radiobutton.rangeall=\u5168\u90E8(L) -radiobutton.rangeall.mnemonic=L -radiobutton.rangepages=\u9801\u9762(E) -radiobutton.rangepages.mnemonic=E -radiobutton.revlandscape=\u53CD\u5411\u6A6B\u5370(N) -radiobutton.revlandscape.mnemonic=N -radiobutton.revportrait=\u53CD\u5411\u76F4\u5370(I) -radiobutton.revportrait.mnemonic=I -radiobutton.tumble=\u7FFB\u8F49(T) -radiobutton.tumble.mnemonic=T +radiobutton.color=\u984F\u8272(&C) +radiobutton.draftq=\u8349\u7A3F(&F) +radiobutton.duplex=\u96D9\u9762\u5217\u5370(&D) +radiobutton.highq=\u9AD8(&H) +radiobutton.landscape=\u6A6B\u5411(&L) +radiobutton.monochrome=\u55AE\u8272(&M) +radiobutton.normalq=\u6B63\u5E38(&N) +radiobutton.oneside=\u55AE\u9762(&O) +radiobutton.portrait=\u76F4\u5411(&P) +radiobutton.rangeall=\u5168\u90E8(&L) +radiobutton.rangepages=\u9801\u9762(&E) +radiobutton.revlandscape=\u53CD\u5411\u6A6B\u5370(&N) +radiobutton.revportrait=\u53CD\u5411\u76F4\u5370(&I) +radiobutton.tumble=\u7FFB\u8F49(&T) # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=\u5916\u89C0(A) -tab.appearance.vkMnemonic=65 -tab.general=\u4E00\u822C(G) -tab.general.vkMnemonic=71 -tab.pagesetup=\u9801\u9762\u8A2D\u5B9A(S) -tab.pagesetup.vkMnemonic=83 +tab.appearance=\u5916\u89C0(&A) +tab.general=\u4E00\u822C(&G) +tab.pagesetup=\u9801\u9762\u8A2D\u5B9A(&S) # error.pagerange=\u7121\u6548\u7684\u9801\u9762\u7BC4\u570D; \u8ACB\u91CD\u65B0\u8F38\u5165\u6578\u503C (\u4F8B\u5982 1-3,5,7-10) error.destination=\u7121\u6548\u7684\u6A94\u540D; \u8ACB\u518D\u8A66\u4E00\u6B21 From ea892424477360da7071e91a0aab459c88340e75 Mon Sep 17 00:00:00 2001 From: Dean Long Date: Thu, 26 Apr 2012 16:24:15 -0400 Subject: [PATCH 39/51] 7162955: Attach api on Solaris, too many open files Release server-side socket after client receives it. Reviewed-by: sla, dsamersoff, dcubed, acorn --- hotspot/src/os/solaris/vm/attachListener_solaris.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp index b56a32a40af..b5b38bdc814 100644 --- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp @@ -336,7 +336,9 @@ extern "C" { // Return 0 (success) + file descriptor, or non-0 (error) if (res == 0) { door_desc_t desc; - desc.d_attributes = DOOR_DESCRIPTOR; + // DOOR_RELEASE flag makes sure fd is closed after passing it to + // the client. See door_return(3DOOR) man page. + desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; desc.d_data.d_desc.d_descriptor = return_fd; door_return((char*)&res, sizeof(res), &desc, 1); } else { From 03b36bd4549497eaf3c28d98c8ceeb51e68d87bc Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Fri, 27 Apr 2012 04:25:50 -0700 Subject: [PATCH 40/51] 6996372: synchronizing handshaking hash Remove the unnecessary synchronization. Also reviewed by David Schlosnagle (schlosna@gmail.com) Reviewed-by: weijun --- .../security/util/DisabledAlgorithmConstraints.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java index 103c3d4b463..ca0393a323d 100644 --- a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java +++ b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java @@ -59,10 +59,10 @@ public class DisabledAlgorithmConstraints implements AlgorithmConstraints { public final static String PROPERTY_TLS_DISABLED_ALGS = "jdk.tls.disabledAlgorithms"; - private static Map disabledAlgorithmsMap = - Collections.synchronizedMap(new HashMap()); - private static Map keySizeConstraintsMap = - Collections.synchronizedMap(new HashMap()); + private final static Map disabledAlgorithmsMap = + new HashMap<>(); + private final static Map keySizeConstraintsMap = + new HashMap<>(); private String[] disabledAlgorithms; private KeySizeConstraints keySizeConstraints; @@ -74,6 +74,8 @@ public class DisabledAlgorithmConstraints implements AlgorithmConstraints { * algorithm constraints */ public DisabledAlgorithmConstraints(String propertyName) { + // Both disabledAlgorithmsMap and keySizeConstraintsMap are + // synchronized with the lock of disabledAlgorithmsMap. synchronized (disabledAlgorithmsMap) { if(!disabledAlgorithmsMap.containsKey(propertyName)) { loadDisabledAlgorithmsMap(propertyName); From 6fed495d1f5c79877a24c0cc1adebbf9b00587c0 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Tue, 1 May 2012 11:17:20 +0100 Subject: [PATCH 41/51] 7164570: (fs) WatchService queues CREATE event but not DELETE event for very short lived files [sol11] Reviewed-by: chegar --- .../sun/nio/fs/SolarisWatchService.java | 66 ++++--- .../java/nio/file/WatchService/MayFlies.java | 181 ++++++++++++++++++ 2 files changed, 213 insertions(+), 34 deletions(-) create mode 100644 jdk/test/java/nio/file/WatchService/MayFlies.java diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java index 76187ec4df7..171dbfe0de2 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java +++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java @@ -314,7 +314,7 @@ class SolarisWatchService fileKey2WatchKey.put(fileKey, watchKey); // register all entries in directory - registerChildren(dir, watchKey, false); + registerChildren(dir, watchKey, false, false); return watchKey; } @@ -486,7 +486,8 @@ class SolarisWatchService void processDirectoryEvents(SolarisWatchKey key, int mask) { if ((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) { registerChildren(key.getDirectory(), key, - key.events().contains(StandardWatchEventKinds.ENTRY_CREATE)); + key.events().contains(StandardWatchEventKinds.ENTRY_CREATE), + key.events().contains(StandardWatchEventKinds.ENTRY_DELETE)); } } @@ -535,14 +536,16 @@ class SolarisWatchService /** * Registers all entries in the given directory * - * The {@code sendEvents} parameter indicates if ENTRY_CREATE events - * should be queued when new entries are found. When initially - * registering a directory then will always be false. When re-scanning - * a directory then it depends on if the event is enabled or not. + * The {@code sendCreateEvents} and {@code sendDeleteEvents} parameters + * indicates if ENTRY_CREATE and ENTRY_DELETE events should be queued + * when new entries are found. When initially registering a directory + * they will always be false. When re-scanning a directory then it + * depends on if the events are enabled or not. */ void registerChildren(UnixPath dir, SolarisWatchKey parent, - boolean sendEvents) + boolean sendCreateEvents, + boolean sendDeleteEvents) { // if the ENTRY_MODIFY event is not enabled then we don't need // modification events for entries in the directory @@ -550,14 +553,7 @@ class SolarisWatchService if (parent.events().contains(StandardWatchEventKinds.ENTRY_MODIFY)) events |= (FILE_MODIFIED | FILE_ATTRIB); - DirectoryStream stream = null; - try { - stream = Files.newDirectoryStream(dir); - } catch (IOException x) { - // nothing we can do - return; - } - try { + try (DirectoryStream stream = Files.newDirectoryStream(dir)) { for (Path entry: stream) { Path name = entry.getFileName(); @@ -565,32 +561,34 @@ class SolarisWatchService if (parent.getChild(name) != null) continue; - // send ENTRY_CREATE if enabled - if (sendEvents) { - parent.signalEvent(StandardWatchEventKinds.ENTRY_CREATE, name); - } - - // register it + // attempt to register entry long object = 0L; + int errno = 0; try { object = registerImpl((UnixPath)entry, events); } catch (UnixException x) { - // can't register so ignore for now. - continue; + errno = x.errno(); } - // create node - EntryNode node = new EntryNode(object, entry.getFileName(), parent); - // tell the parent about it - parent.addChild(entry.getFileName(), node); - object2Node.put(object, node); + boolean registered = (object != 0L); + boolean deleted = (errno == ENOENT); + + if (registered) { + // create node + EntryNode node = new EntryNode(object, entry.getFileName(), parent); + // tell the parent about it + parent.addChild(entry.getFileName(), node); + object2Node.put(object, node); + } + + if (sendCreateEvents && (registered || deleted)) + parent.signalEvent(StandardWatchEventKinds.ENTRY_CREATE, name); + if (sendDeleteEvents && deleted) + parent.signalEvent(StandardWatchEventKinds.ENTRY_DELETE, name); + } - } catch (ConcurrentModificationException x) { - // error during iteration which we ignore for now - } finally { - try { - stream.close(); - } catch (IOException x) { } + } catch (DirectoryIteratorException | IOException x) { + // nothing we can do } } diff --git a/jdk/test/java/nio/file/WatchService/MayFlies.java b/jdk/test/java/nio/file/WatchService/MayFlies.java new file mode 100644 index 00000000000..f311d0a4f21 --- /dev/null +++ b/jdk/test/java/nio/file/WatchService/MayFlies.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 7164570 + * @summary Test that CREATE and DELETE events are paired for very + * short lived files + * @library .. + * @run main MayFlies + */ + +import java.nio.file.*; +import static java.nio.file.StandardWatchEventKinds.*; +import java.util.*; +import java.util.concurrent.*; + +public class MayFlies { + + static volatile boolean stopped; + + static volatile boolean failure; + + /** + * Continuously creates short-lived files in a directory until {@code + * stopped} is set to {@code true}. + */ + static class MayFlyHatcher implements Runnable { + static final Random rand = new Random(); + + private final Path dir; + private final String prefix; + + private MayFlyHatcher(Path dir, String prefix) { + this.dir = dir; + this.prefix = prefix; + } + + static void start(Path dir, String prefix) { + MayFlyHatcher hatcher = new MayFlyHatcher(dir, prefix); + new Thread(hatcher).start(); + } + + public void run() { + try { + int n = 0; + while (!stopped) { + Path name = dir.resolve(prefix + (++n)); + Files.createFile(name); + if (rand.nextBoolean()) + Thread.sleep(rand.nextInt(500)); + Files.delete(name); + Thread.sleep(rand.nextInt(100)); + } + System.out.format("%d %ss hatched%n", n, prefix); + } catch (Exception x) { + failure = true; + x.printStackTrace(); + } + } + } + + /** + * Test phases. + */ + static enum Phase { + /** + * Short-lived files are being created + */ + RUNNING, + /** + * Draining the final events + */ + FINISHING, + /** + * No more events or overflow detected + */ + FINISHED + }; + + + public static void main(String[] args) throws Exception { + + // schedules file creation to stop after 10 seconds + ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor(); + pool.schedule( + new Runnable() { public void run() { stopped = true; }}, + 10, TimeUnit.SECONDS); + + Path dir = TestUtil.createTemporaryDirectory(); + + Set entries = new HashSet<>(); + int nCreateEvents = 0; + boolean overflow = false; + + try (WatchService watcher = FileSystems.getDefault().newWatchService()) { + WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE); + + // start hatching Mayflies + MayFlyHatcher.start(dir, "clinger"); + MayFlyHatcher.start(dir, "crawler"); + MayFlyHatcher.start(dir, "burrower"); + MayFlyHatcher.start(dir, "swimmer"); + + Phase phase = Phase.RUNNING; + while (phase != Phase.FINISHED) { + // during the running phase then poll for 1 second. + // once the file creation has stopped then move to the finishing + // phase where we do a long poll to ensure that all events have + // been read. + int time = (phase == Phase.RUNNING) ? 1 : 15; + key = watcher.poll(time, TimeUnit.SECONDS); + if (key == null) { + if (phase == Phase.RUNNING && stopped) + phase = Phase.FINISHING; + else if (phase == Phase.FINISHING) + phase = Phase.FINISHED; + } else { + // process events + for (WatchEvent event: key.pollEvents()) { + if (event.kind() == ENTRY_CREATE) { + Path name = (Path)event.context(); + boolean added = entries.add(name); + if (!added) + throw new RuntimeException("Duplicate ENTRY_CREATE event"); + nCreateEvents++; + } else if (event.kind() == ENTRY_DELETE) { + Path name = (Path)event.context(); + boolean removed = entries.remove(name); + if (!removed) + throw new RuntimeException("ENTRY_DELETE event without ENTRY_CREATE event"); + } else if (event.kind() == OVERFLOW) { + overflow = true; + phase = Phase.FINISHED; + } else { + throw new RuntimeException("Unexpected event: " + event.kind()); + } + } + key.reset(); + } + } + + System.out.format("%d ENTRY_CREATE events read%n", nCreateEvents); + + // there should be a DELETE event for each CREATE event and so the + // entries set should be empty. + if (!overflow && !entries.isEmpty()) + throw new RuntimeException("Missed " + entries.size() + " DELETE event(s)"); + + + } finally { + try { + TestUtil.removeAll(dir); + } finally { + pool.shutdown(); + } + } + + if (failure) + throw new RuntimeException("Test failed - see log file for details"); + } +} From 4a3f30b7446403c5318d326a3f520d1a18c6f1b9 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Tue, 1 May 2012 03:48:26 -0700 Subject: [PATCH 42/51] 7158688: Typo in SSLContext Spec Reviewed-by: weijun, wetmore --- jdk/src/share/classes/javax/net/ssl/SSLContext.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/javax/net/ssl/SSLContext.java b/jdk/src/share/classes/javax/net/ssl/SSLContext.java index 6852df2f98c..7aba5314e36 100644 --- a/jdk/src/share/classes/javax/net/ssl/SSLContext.java +++ b/jdk/src/share/classes/javax/net/ssl/SSLContext.java @@ -145,7 +145,7 @@ public class SSLContext { * @return the new SSLContext object. * * @exception NoSuchAlgorithmException if no Provider supports a - * TrustManagerFactorySpi implementation for the + * SSLContextSpi implementation for the * specified protocol. * @exception NullPointerException if protocol is null. * @@ -222,11 +222,11 @@ public class SSLContext { * * @return the new SSLContext object. * - * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi + * @throws NoSuchAlgorithmException if a SSLContextSpi * implementation for the specified protocol is not available * from the specified Provider object. * - * @throws IllegalArgumentException if the provider name is null. + * @throws IllegalArgumentException if the provider is null. * @throws NullPointerException if protocol is null. * * @see java.security.Provider From 728600d4e30d3af2b74cc524af32b2800bcad07b Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Tue, 1 May 2012 19:45:34 -0700 Subject: [PATCH 43/51] 7164376: Replace use of sun.security.action.LoadLibraryAction with System.loadLibrary Reviewed-by: alanb, mullan, prr --- .../apple/launcher/JavaAppLauncher.java | 9 ++- .../classes/apple/security/KeychainStore.java | 8 ++- .../apple/concurrent/LibDispatchNative.java | 28 +++++--- .../classes/com/apple/eawt/Application.java | 9 ++- .../classes/com/apple/eio/FileManager.java | 8 ++- .../classes/com/apple/laf/AquaFileView.java | 9 ++- .../com/apple/laf/AquaLookAndFeel.java | 12 +++- .../com/apple/laf/AquaNativeResources.java | 9 ++- .../classes/com/apple/laf/ScreenMenu.java | 9 ++- .../com/apple/laf/ScreenPopupFactory.java | 10 ++- .../util/prefs/MacOSXPreferencesFile.java | 8 ++- .../classes/sun/awt/CGraphicsEnvironment.java | 12 +++- .../sun/lwawt/macosx/CAccessibility.java | 9 ++- .../imageio/plugins/jpeg/JPEGImageReader.java | 7 +- .../imageio/plugins/jpeg/JPEGImageWriter.java | 7 +- .../sun/java/util/jar/pack/NativeUnpack.java | 7 +- .../share/classes/java/awt/SplashScreen.java | 7 +- jdk/src/share/classes/java/awt/Toolkit.java | 7 +- .../java/awt/event/NativeLibLoader.java | 7 +- .../classes/java/awt/image/ColorModel.java | 7 +- .../net/AbstractPlainDatagramSocketImpl.java | 7 +- .../java/net/AbstractPlainSocketImpl.java | 7 +- .../classes/java/net/DatagramPacket.java | 7 +- .../share/classes/java/net/InetAddress.java | 8 ++- .../classes/java/net/NetworkInterface.java | 9 ++- .../classes/sun/awt/NativeLibLoader.java | 7 +- .../sun/awt/image/JPEGImageDecoder.java | 7 +- .../sun/awt/image/NativeLibLoader.java | 9 ++- .../share/classes/sun/java2d/Disposer.java | 7 +- .../management/ManagementFactoryHelper.java | 9 ++- .../share/classes/sun/net/sdp/SdpSupport.java | 7 +- .../sun/net/spi/DefaultProxySelector.java | 7 +- jdk/src/share/classes/sun/nio/ch/Util.java | 13 ++-- .../security/action/LoadLibraryAction.java | 70 ------------------- .../security/krb5/SCDynamicStoreConfig.java | 8 ++- .../sun/security/smartcardio/PCSC.java | 2 - .../share/classes/sun/tracing/dtrace/JVM.java | 9 ++- .../sun/management/FileSystemImpl.java | 9 ++- .../net/dns/ResolverConfigurationImpl.java | 7 +- .../sun/nio/ch/sctp/SctpChannelImpl.java | 7 +- .../sun/nio/ch/sctp/SctpMultiChannelImpl.java | 7 +- .../nio/ch/sctp/SctpServerChannelImpl.java | 7 +- .../classes/sun/print/CUPSPrinter.java | 7 +- .../awt/shell/Win32ShellFolderManager2.java | 10 ++- .../classes/sun/awt/windows/WToolkit.java | 7 +- .../sun/management/FileSystemImpl.java | 9 ++- .../net/dns/ResolverConfigurationImpl.java | 7 +- .../sun/print/Win32PrintServiceLookup.java | 7 +- .../security/smartcardio/PlatformPCSC.java | 10 ++- 49 files changed, 323 insertions(+), 153 deletions(-) delete mode 100644 jdk/src/share/classes/sun/security/action/LoadLibraryAction.java diff --git a/jdk/src/macosx/classes/apple/launcher/JavaAppLauncher.java b/jdk/src/macosx/classes/apple/launcher/JavaAppLauncher.java index 599a575f311..486a46266bf 100644 --- a/jdk/src/macosx/classes/apple/launcher/JavaAppLauncher.java +++ b/jdk/src/macosx/classes/apple/launcher/JavaAppLauncher.java @@ -27,7 +27,6 @@ package apple.launcher; import java.io.*; import java.lang.reflect.*; -import java.security.PrivilegedAction; import java.text.MessageFormat; import java.util.*; import java.util.jar.*; @@ -36,7 +35,13 @@ import javax.swing.*; class JavaAppLauncher implements Runnable { static { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("osx")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osx"); + return null; + } + }); } private static native T nativeConvertAndRelease(final long ptr); diff --git a/jdk/src/macosx/classes/apple/security/KeychainStore.java b/jdk/src/macosx/classes/apple/security/KeychainStore.java index 62919436a57..e8eb55315d3 100644 --- a/jdk/src/macosx/classes/apple/security/KeychainStore.java +++ b/jdk/src/macosx/classes/apple/security/KeychainStore.java @@ -103,7 +103,13 @@ public final class KeychainStore extends KeyStoreSpi { private static final int SALT_LEN = 20; static { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("osx")); + AccessController.doPrivileged( + new PrivilegedAction() { + public Void run() { + System.loadLibrary("osx"); + return null; + } + }); try { PKCS8ShroudedKeyBag_OID = new ObjectIdentifier(keyBag); pbeWithSHAAnd3KeyTripleDESCBC_OID = new ObjectIdentifier(pbeWithSHAAnd3KeyTripleDESCBC); diff --git a/jdk/src/macosx/classes/com/apple/concurrent/LibDispatchNative.java b/jdk/src/macosx/classes/com/apple/concurrent/LibDispatchNative.java index 470027fc69e..7e190b3cc01 100644 --- a/jdk/src/macosx/classes/com/apple/concurrent/LibDispatchNative.java +++ b/jdk/src/macosx/classes/com/apple/concurrent/LibDispatchNative.java @@ -26,17 +26,23 @@ package com.apple.concurrent; final class LibDispatchNative { - static { - java.security.AccessController.doPrivileged((java.security.PrivilegedAction)new sun.security.action.LoadLibraryAction("osx")); - } + static { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osx"); + return null; + } + }); + } - static native boolean nativeIsDispatchSupported(); - static native long nativeGetMainQueue(); - static native long nativeCreateConcurrentQueue(int priority); - static native long nativeCreateSerialQueue(String name); - static native void nativeReleaseQueue(long nativeQueue); - static native void nativeExecuteAsync(long nativeQueue, Runnable task); - static native void nativeExecuteSync(long nativeQueue, Runnable task); + static native boolean nativeIsDispatchSupported(); + static native long nativeGetMainQueue(); + static native long nativeCreateConcurrentQueue(int priority); + static native long nativeCreateSerialQueue(String name); + static native void nativeReleaseQueue(long nativeQueue); + static native void nativeExecuteAsync(long nativeQueue, Runnable task); + static native void nativeExecuteSync(long nativeQueue, Runnable task); - private LibDispatchNative() { } + private LibDispatchNative() { } } diff --git a/jdk/src/macosx/classes/com/apple/eawt/Application.java b/jdk/src/macosx/classes/com/apple/eawt/Application.java index f4657d622f2..e761a5ad0aa 100644 --- a/jdk/src/macosx/classes/com/apple/eawt/Application.java +++ b/jdk/src/macosx/classes/com/apple/eawt/Application.java @@ -28,7 +28,6 @@ package com.apple.eawt; import java.awt.*; import java.awt.peer.*; import java.beans.Beans; -import java.security.PrivilegedAction; import javax.swing.JMenuBar; @@ -59,7 +58,13 @@ public class Application { static Application sApplication = null; static { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("awt")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); checkSecurity(); if (!Beans.isDesignTime()) { diff --git a/jdk/src/macosx/classes/com/apple/eio/FileManager.java b/jdk/src/macosx/classes/com/apple/eio/FileManager.java index 12eb47a2a5b..1c421832600 100644 --- a/jdk/src/macosx/classes/com/apple/eio/FileManager.java +++ b/jdk/src/macosx/classes/com/apple/eio/FileManager.java @@ -55,7 +55,13 @@ import java.io.*; */ public class FileManager { static { - java.security.AccessController.doPrivileged((java.security.PrivilegedAction)new sun.security.action.LoadLibraryAction("osx")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osx"); + return null; + } + }); } /** diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaFileView.java b/jdk/src/macosx/classes/com/apple/laf/AquaFileView.java index 258b10baf6d..6f09963ce0f 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaFileView.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaFileView.java @@ -26,7 +26,6 @@ package com.apple.laf; import java.io.*; -import java.security.PrivilegedAction; import java.util.*; import java.util.Map.Entry; @@ -57,7 +56,13 @@ class AquaFileView extends FileView { static final int kLSItemInfoExtensionIsHidden = 0x00100000; /* Item has a hidden extension*/ static { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("osxui")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osxui"); + return null; + } + }); } // TODO: Un-comment this out when the native version exists diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java b/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java index f95de47fd15..c7d970c13fd 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java @@ -134,10 +134,16 @@ public class AquaLookAndFeel extends BasicLookAndFeel { * @see UIManager#setLookAndFeel */ public void initialize() { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("osxui")); - java.security.AccessController.doPrivileged(new PrivilegedAction(){ + java.security.AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + System.loadLibrary("osxui"); + return null; + } + }); + + java.security.AccessController.doPrivileged(new PrivilegedAction(){ @Override - public Object run() { + public Void run() { JRSUIControl.initJRSUI(); return null; } diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaNativeResources.java b/jdk/src/macosx/classes/com/apple/laf/AquaNativeResources.java index 5a227d9f31e..8923a03a29c 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaNativeResources.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaNativeResources.java @@ -27,7 +27,6 @@ package com.apple.laf; import java.awt.*; import java.awt.image.BufferedImage; -import java.security.PrivilegedAction; import javax.swing.plaf.UIResource; @@ -35,7 +34,13 @@ import com.apple.laf.AquaUtils.RecyclableSingleton; public class AquaNativeResources { static { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("osxui")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osxui"); + return null; + } + }); } // TODO: removing CColorPaint for now diff --git a/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java b/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java index ec4c3f7ee6e..23c55c8d2a1 100644 --- a/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java +++ b/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java @@ -28,7 +28,6 @@ package com.apple.laf; import java.awt.*; import java.awt.event.*; import java.awt.peer.MenuComponentPeer; -import java.security.PrivilegedAction; import java.util.Hashtable; import javax.swing.*; @@ -38,7 +37,13 @@ import sun.lwawt.macosx.*; class ScreenMenu extends Menu implements ContainerListener, ComponentListener, ScreenMenuPropertyHandler { static { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("awt")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); } // screen menu stuff diff --git a/jdk/src/macosx/classes/com/apple/laf/ScreenPopupFactory.java b/jdk/src/macosx/classes/com/apple/laf/ScreenPopupFactory.java index 6993d4f17b9..c3a09f03a62 100644 --- a/jdk/src/macosx/classes/com/apple/laf/ScreenPopupFactory.java +++ b/jdk/src/macosx/classes/com/apple/laf/ScreenPopupFactory.java @@ -26,15 +26,19 @@ package com.apple.laf; import java.awt.*; -import java.security.PrivilegedAction; - import javax.swing.*; import sun.lwawt.macosx.CPlatformWindow; class ScreenPopupFactory extends PopupFactory { static { - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("osxui")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osxui"); + return null; + } + }); } static final Float TRANSLUCENT = new Float(248f/255f); diff --git a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java index 7cfb899ddf4..992ae620338 100644 --- a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java +++ b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java @@ -79,7 +79,13 @@ import java.lang.ref.WeakReference; class MacOSXPreferencesFile { static { - java.security.AccessController.doPrivileged(new sun.security.action.LoadLibraryAction("osx")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osx"); + return null; + } + }); } private class FlushTask extends TimerTask { diff --git a/jdk/src/macosx/classes/sun/awt/CGraphicsEnvironment.java b/jdk/src/macosx/classes/sun/awt/CGraphicsEnvironment.java index b8c244b4260..8a647d1de36 100644 --- a/jdk/src/macosx/classes/sun/awt/CGraphicsEnvironment.java +++ b/jdk/src/macosx/classes/sun/awt/CGraphicsEnvironment.java @@ -58,9 +58,15 @@ public class CGraphicsEnvironment extends SunGraphicsEnvironment { public static void init() { } static { - java.security.AccessController.doPrivileged(new sun.security.action.LoadLibraryAction("awt")); - java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); + + java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { + public Void run() { if (isHeadless()) return null; initCocoa(); return null; diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java index a1d535ec818..97c5ef9e2c6 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java @@ -29,7 +29,6 @@ import java.awt.*; import java.beans.*; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; -import java.security.PrivilegedAction; import java.util.*; import java.util.concurrent.Callable; @@ -41,7 +40,13 @@ class CAccessibility implements PropertyChangeListener { static { // Need to load the native library for this code. - java.security.AccessController.doPrivileged((PrivilegedAction)new sun.security.action.LoadLibraryAction("awt")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); } static CAccessibility sAccessibility; diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java index 3df7048ab32..efff47adcbd 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java @@ -87,7 +87,12 @@ public class JPEGImageReader extends ImageReader { static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jpeg")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("jpeg"); + return null; + } + }); initReaderIDs(ImageInputStream.class, JPEGQTable.class, JPEGHuffmanTable.class); diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java index 58e3192ec78..15e6d815b18 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java @@ -177,7 +177,12 @@ public class JPEGImageWriter extends ImageWriter { static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jpeg")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("jpeg"); + return null; + } + }); initWriterIDs(ImageOutputStream.class, JPEGQTable.class, JPEGHuffmanTable.class); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java index c097f9eb846..7e525729034 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java @@ -87,7 +87,12 @@ class NativeUnpack { // If loading from stand alone build uncomment this. // System.loadLibrary("unpack"); java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("unpack")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("unpack"); + return null; + } + }); initIDs(); } diff --git a/jdk/src/share/classes/java/awt/SplashScreen.java b/jdk/src/share/classes/java/awt/SplashScreen.java index 867ecb330c5..f9d3af15e13 100644 --- a/jdk/src/share/classes/java/awt/SplashScreen.java +++ b/jdk/src/share/classes/java/awt/SplashScreen.java @@ -119,7 +119,12 @@ public final class SplashScreen { // SplashScreen class is now a singleton if (!wasClosed && theInstance == null) { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("splashscreen")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("splashscreen"); + return null; + } + }); long ptr = _getInstance(); if (ptr != 0 && _isVisible(ptr)) { theInstance = new SplashScreen(ptr); diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index d9f8cf07efb..8509534734c 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1646,7 +1646,12 @@ public abstract class Toolkit { static void loadLibraries() { if (!loaded) { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); loaded = true; } } diff --git a/jdk/src/share/classes/java/awt/event/NativeLibLoader.java b/jdk/src/share/classes/java/awt/event/NativeLibLoader.java index 1d702287a27..4336669312d 100644 --- a/jdk/src/share/classes/java/awt/event/NativeLibLoader.java +++ b/jdk/src/share/classes/java/awt/event/NativeLibLoader.java @@ -54,6 +54,11 @@ class NativeLibLoader { */ static void loadLibraries() { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); } } diff --git a/jdk/src/share/classes/java/awt/image/ColorModel.java b/jdk/src/share/classes/java/awt/image/ColorModel.java index 010fc53829a..5ce313e1bf3 100644 --- a/jdk/src/share/classes/java/awt/image/ColorModel.java +++ b/jdk/src/share/classes/java/awt/image/ColorModel.java @@ -204,7 +204,12 @@ public abstract class ColorModel implements Transparency{ static void loadLibraries() { if (!loaded) { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); loaded = true; } } diff --git a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java index 3b9f531c08d..32d1e709475 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java @@ -67,7 +67,12 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl */ static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("net")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); } /** diff --git a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java index c510c6179fd..e3373e821b0 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java @@ -78,7 +78,12 @@ abstract class AbstractPlainSocketImpl extends SocketImpl */ static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("net")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); } /** diff --git a/jdk/src/share/classes/java/net/DatagramPacket.java b/jdk/src/share/classes/java/net/DatagramPacket.java index 195ee8603fc..910fed66cbf 100644 --- a/jdk/src/share/classes/java/net/DatagramPacket.java +++ b/jdk/src/share/classes/java/net/DatagramPacket.java @@ -47,7 +47,12 @@ class DatagramPacket { */ static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("net")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); init(); } diff --git a/jdk/src/share/classes/java/net/InetAddress.java b/jdk/src/share/classes/java/net/InetAddress.java index d927d160a68..cfeac4a4e19 100644 --- a/jdk/src/share/classes/java/net/InetAddress.java +++ b/jdk/src/share/classes/java/net/InetAddress.java @@ -234,7 +234,13 @@ class InetAddress implements java.io.Serializable { static { preferIPv6Address = java.security.AccessController.doPrivileged( new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue(); - AccessController.doPrivileged(new LoadLibraryAction("net")); + AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); init(); } diff --git a/jdk/src/share/classes/java/net/NetworkInterface.java b/jdk/src/share/classes/java/net/NetworkInterface.java index 6314d15c18f..b6cd711bb1b 100644 --- a/jdk/src/share/classes/java/net/NetworkInterface.java +++ b/jdk/src/share/classes/java/net/NetworkInterface.java @@ -53,7 +53,14 @@ public final class NetworkInterface { private static final int defaultIndex; /* index of defaultInterface */ static { - AccessController.doPrivileged(new LoadLibraryAction("net")); + AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); + init(); defaultInterface = DefaultInterface.getDefault(); if (defaultInterface != null) { diff --git a/jdk/src/share/classes/sun/awt/NativeLibLoader.java b/jdk/src/share/classes/sun/awt/NativeLibLoader.java index ee9f695b6eb..32a31b9cb49 100644 --- a/jdk/src/share/classes/sun/awt/NativeLibLoader.java +++ b/jdk/src/share/classes/sun/awt/NativeLibLoader.java @@ -54,6 +54,11 @@ class NativeLibLoader { */ static void loadLibraries() { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); } } diff --git a/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java b/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java index 72ac1d06a70..c971b414ae1 100644 --- a/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java +++ b/jdk/src/share/classes/sun/awt/image/JPEGImageDecoder.java @@ -54,7 +54,12 @@ public class JPEGImageDecoder extends ImageDecoder { static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jpeg")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("jpeg"); + return null; + } + }); initIDs(InputStreamClass); RGBcolormodel = new DirectColorModel(24, 0xff0000, 0xff00, 0xff); ARGBcolormodel = ColorModel.getRGBdefault(); diff --git a/jdk/src/share/classes/sun/awt/image/NativeLibLoader.java b/jdk/src/share/classes/sun/awt/image/NativeLibLoader.java index 5c6a765c414..d713d79b5c0 100644 --- a/jdk/src/share/classes/sun/awt/image/NativeLibLoader.java +++ b/jdk/src/share/classes/sun/awt/image/NativeLibLoader.java @@ -53,7 +53,12 @@ class NativeLibLoader { * that the name of the library is "awt". -br. */ static void loadLibraries() { - java.security.AccessController.doPrivileged - (new sun.security.action.LoadLibraryAction("awt")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); } } diff --git a/jdk/src/share/classes/sun/java2d/Disposer.java b/jdk/src/share/classes/sun/java2d/Disposer.java index 83951023fbb..dcedfe3846e 100644 --- a/jdk/src/share/classes/sun/java2d/Disposer.java +++ b/jdk/src/share/classes/sun/java2d/Disposer.java @@ -57,7 +57,12 @@ public class Disposer implements Runnable { static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); initIDs(); String type = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.java2d.reftype")); diff --git a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java index 025b7a26d64..bd1cd2581e7 100644 --- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java +++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java @@ -37,7 +37,6 @@ import javax.management.RuntimeOperationsException; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import sun.security.action.LoadLibraryAction; import sun.util.logging.LoggingSupport; @@ -422,7 +421,13 @@ public class ManagementFactoryHelper { } static { - AccessController.doPrivileged(new LoadLibraryAction("management")); + AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("management"); + return null; + } + }); jvm = new VMManagementImpl(); } diff --git a/jdk/src/share/classes/sun/net/sdp/SdpSupport.java b/jdk/src/share/classes/sun/net/sdp/SdpSupport.java index 5baca6e4925..b70a729cc56 100644 --- a/jdk/src/share/classes/sun/net/sdp/SdpSupport.java +++ b/jdk/src/share/classes/sun/net/sdp/SdpSupport.java @@ -76,6 +76,11 @@ public final class SdpSupport { static { AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("net")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); } } diff --git a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java index d7aa358d596..23c1338e8f1 100644 --- a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java +++ b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java @@ -95,7 +95,12 @@ public class DefaultProxySelector extends ProxySelector { }}); if (b != null && b.booleanValue()) { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("net")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); hasSystemProxies = init(); } } diff --git a/jdk/src/share/classes/sun/nio/ch/Util.java b/jdk/src/share/classes/sun/nio/ch/Util.java index 56aa1f65e39..985f7ffefe5 100644 --- a/jdk/src/share/classes/sun/nio/ch/Util.java +++ b/jdk/src/share/classes/sun/nio/ch/Util.java @@ -472,10 +472,15 @@ public class Util { if (loaded) return; loaded = true; - java.security.AccessController - .doPrivileged(new sun.security.action.LoadLibraryAction("net")); - java.security.AccessController - .doPrivileged(new sun.security.action.LoadLibraryAction("nio")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + System.loadLibrary("nio"); + return null; + } + }); + // IOUtil must be initialized; Its native methods are called from // other places in native nio code so they must be set up. IOUtil.initIDs(); diff --git a/jdk/src/share/classes/sun/security/action/LoadLibraryAction.java b/jdk/src/share/classes/sun/security/action/LoadLibraryAction.java deleted file mode 100644 index c3510151438..00000000000 --- a/jdk/src/share/classes/sun/security/action/LoadLibraryAction.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.action; - -/** - * A convenience class for loading a system library as a privileged action. - * - *

An instance of this class can be used as the argument of - * AccessController.doPrivileged. - * - *

The following code attempts to load the system library named - * "lib" as a privileged action:

- * - *

- * java.security.AccessController.doPrivileged(new LoadLibraryAction("lib"));
- * 
- * - * @author Roland Schemers - * @see java.security.PrivilegedAction - * @see java.security.AccessController - * @since 1.2 - */ - -public class LoadLibraryAction implements java.security.PrivilegedAction { - private String theLib; - - /** - * Constructor that takes the name of the system library that needs to be - * loaded. - * - *

The manner in which a library name is mapped to the - * actual system library is system dependent. - * - * @param theLib the name of the library. - */ - public LoadLibraryAction(String theLib) { - this.theLib = theLib; - } - - /** - * Loads the system library whose name was specified in the constructor. - */ - public Void run() { - System.loadLibrary(theLib); - return null; - } -} diff --git a/jdk/src/share/classes/sun/security/krb5/SCDynamicStoreConfig.java b/jdk/src/share/classes/sun/security/krb5/SCDynamicStoreConfig.java index d4b51f88ad9..c6e5e70a94b 100644 --- a/jdk/src/share/classes/sun/security/krb5/SCDynamicStoreConfig.java +++ b/jdk/src/share/classes/sun/security/krb5/SCDynamicStoreConfig.java @@ -36,7 +36,13 @@ public class SCDynamicStoreConfig { private static native Hashtable getKerberosConfig(); static { - java.security.AccessController.doPrivileged(new sun.security.action.LoadLibraryAction("osx")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("osx"); + return null; + } + }); installNotificationCallback(); } diff --git a/jdk/src/share/classes/sun/security/smartcardio/PCSC.java b/jdk/src/share/classes/sun/security/smartcardio/PCSC.java index e9e98d9f659..c1ebe4c7b3e 100644 --- a/jdk/src/share/classes/sun/security/smartcardio/PCSC.java +++ b/jdk/src/share/classes/sun/security/smartcardio/PCSC.java @@ -27,8 +27,6 @@ package sun.security.smartcardio; import java.security.AccessController; -import sun.security.action.LoadLibraryAction; - /** * Access to native PC/SC functions and definition of PC/SC constants. * Initialization and platform specific PC/SC constants are handled in diff --git a/jdk/src/share/classes/sun/tracing/dtrace/JVM.java b/jdk/src/share/classes/sun/tracing/dtrace/JVM.java index 2bea9740c09..c59ce68cb3c 100644 --- a/jdk/src/share/classes/sun/tracing/dtrace/JVM.java +++ b/jdk/src/share/classes/sun/tracing/dtrace/JVM.java @@ -35,8 +35,13 @@ import java.lang.reflect.Method; class JVM { static { - java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jsdt")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("jsdt"); + return null; + } + }); } static long activate(String moduleName, DTraceProvider[] providers) { diff --git a/jdk/src/solaris/classes/sun/management/FileSystemImpl.java b/jdk/src/solaris/classes/sun/management/FileSystemImpl.java index 2961eca36af..67445c58d4e 100644 --- a/jdk/src/solaris/classes/sun/management/FileSystemImpl.java +++ b/jdk/src/solaris/classes/sun/management/FileSystemImpl.java @@ -48,7 +48,12 @@ public class FileSystemImpl extends FileSystem { // Initialization static { - java.security.AccessController - .doPrivileged(new sun.security.action.LoadLibraryAction("management")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("management"); + return null; + } + }); } } diff --git a/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java b/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java index 66430d40495..670a675d95c 100644 --- a/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java +++ b/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java @@ -251,7 +251,12 @@ public class ResolverConfigurationImpl static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("net")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java index 25afcff2695..92f17cb3e8b 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java @@ -1100,7 +1100,12 @@ public class SctpChannelImpl extends SctpChannel static { Util.load(); /* loads nio & net native libraries */ java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("sctp")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("sctp"); + return null; + } + }); initIDs(); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java index e00247f3970..fa44072f4dc 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java @@ -989,6 +989,11 @@ public class SctpMultiChannelImpl extends SctpMultiChannel static { Util.load(); /* loads nio & net native libraries */ java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("sctp")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("sctp"); + return null; + } + }); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java index 15d281bd309..e5d5a892bd7 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java @@ -428,7 +428,12 @@ public class SctpServerChannelImpl extends SctpServerChannel static { Util.load(); // loads nio & net native libraries java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("sctp")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("sctp"); + return null; + } + }); initIDs(); } } diff --git a/jdk/src/solaris/classes/sun/print/CUPSPrinter.java b/jdk/src/solaris/classes/sun/print/CUPSPrinter.java index 9648488b166..c64ea8b1122 100644 --- a/jdk/src/solaris/classes/sun/print/CUPSPrinter.java +++ b/jdk/src/solaris/classes/sun/print/CUPSPrinter.java @@ -77,7 +77,12 @@ public class CUPSPrinter { static { // load awt library to access native code java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); libFound = initIDs(); if (libFound) { cupsServer = getCupsServer(); diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index 5d34d4fffe6..7e23874e0dd 100644 --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -37,8 +37,6 @@ import java.util.*; import java.util.List; import java.util.concurrent.*; -import sun.security.action.LoadLibraryAction; - import static sun.awt.shell.Win32ShellFolder2.*; import sun.awt.OSInfo; @@ -56,7 +54,13 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { static { // Load library here - AccessController.doPrivileged(new LoadLibraryAction("awt")); + AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); } public ShellFolder createShellFolder(File file) throws FileNotFoundException { diff --git a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java index 0c0cdd47aa7..515a8230bf3 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java +++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java @@ -94,7 +94,12 @@ public class WToolkit extends SunToolkit implements Runnable { public static void loadLibraries() { if (!loaded) { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); loaded = true; } } diff --git a/jdk/src/windows/classes/sun/management/FileSystemImpl.java b/jdk/src/windows/classes/sun/management/FileSystemImpl.java index 71fdaf2d297..789b7ee64ee 100644 --- a/jdk/src/windows/classes/sun/management/FileSystemImpl.java +++ b/jdk/src/windows/classes/sun/management/FileSystemImpl.java @@ -56,8 +56,13 @@ public class FileSystemImpl extends FileSystem { // Initialization static { - java.security.AccessController - .doPrivileged(new sun.security.action.LoadLibraryAction("management")); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("management"); + return null; + } + }); init0(); } } diff --git a/jdk/src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java b/jdk/src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java index eb7405de9d3..b896fbf6344 100644 --- a/jdk/src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java +++ b/jdk/src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java @@ -161,7 +161,12 @@ public class ResolverConfigurationImpl static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("net")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("net"); + return null; + } + }); init0(); // start the address listener thread diff --git a/jdk/src/windows/classes/sun/print/Win32PrintServiceLookup.java b/jdk/src/windows/classes/sun/print/Win32PrintServiceLookup.java index 899ef23e461..dc9e9ee1b27 100644 --- a/jdk/src/windows/classes/sun/print/Win32PrintServiceLookup.java +++ b/jdk/src/windows/classes/sun/print/Win32PrintServiceLookup.java @@ -56,7 +56,12 @@ public class Win32PrintServiceLookup extends PrintServiceLookup { static { java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("awt")); + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("awt"); + return null; + } + }); } /* The singleton win32 print lookup service. diff --git a/jdk/src/windows/classes/sun/security/smartcardio/PlatformPCSC.java b/jdk/src/windows/classes/sun/security/smartcardio/PlatformPCSC.java index ea6e2fcd72b..0af23c0ddde 100644 --- a/jdk/src/windows/classes/sun/security/smartcardio/PlatformPCSC.java +++ b/jdk/src/windows/classes/sun/security/smartcardio/PlatformPCSC.java @@ -26,8 +26,7 @@ package sun.security.smartcardio; import java.security.AccessController; - -import sun.security.action.LoadLibraryAction; +import java.security.PrivilegedAction; // Platform specific code and constants class PlatformPCSC { @@ -44,7 +43,12 @@ class PlatformPCSC { private static Throwable loadLibrary() { try { - AccessController.doPrivileged(new LoadLibraryAction("j2pcsc")); + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + System.loadLibrary("j2pcsc"); + return null; + } + }); return null; } catch (Throwable e) { return e; From 3f596509e181e5c24b3dcc25cf9e8287aa5a6d6a Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Wed, 2 May 2012 13:53:06 +0400 Subject: [PATCH 44/51] 7154062: [macosx] Mouse cursor isn't updated in applets Reviewed-by: anthony, art --- .../sun/lwawt/macosx/CCursorManager.java | 1 + .../sun/lwawt/macosx/CEmbeddedFrame.java | 6 +++++ .../macosx/native/sun/awt/CCursorManager.m | 27 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java index b17618452ac..6554dc9028f 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java @@ -36,6 +36,7 @@ final class CCursorManager extends LWCursorManager { private static native Point2D nativeGetCursorPosition(); private static native void nativeSetBuiltInCursor(final int type, final String name); private static native void nativeSetCustomCursor(final long imgPtr, final double x, final double y); + public static native void nativeSetAllowsCursorSetInBackground(final boolean allows); private static final int NAMED_CURSOR = -1; diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java index e173d7372f2..fa711c9a9d2 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java @@ -76,6 +76,12 @@ public class CEmbeddedFrame extends EmbeddedFrame { int screenX = locationOnScreen.x + x; int screenY = locationOnScreen.y + y; + if (eventType == CocoaConstants.NPCocoaEventMouseEntered) { + CCursorManager.nativeSetAllowsCursorSetInBackground(true); + } else if (eventType == CocoaConstants.NPCocoaEventMouseExited) { + CCursorManager.nativeSetAllowsCursorSetInBackground(false); + } + responder.handleMouseEvent(eventType, modifierFlags, buttonNumber, clickCount, x, y, screenX, screenY); } diff --git a/jdk/src/macosx/native/sun/awt/CCursorManager.m b/jdk/src/macosx/native/sun/awt/CCursorManager.m index 02933291263..e7378d3929a 100644 --- a/jdk/src/macosx/native/sun/awt/CCursorManager.m +++ b/jdk/src/macosx/native/sun/awt/CCursorManager.m @@ -137,3 +137,30 @@ JNF_COCOA_EXIT(env); return jpt; } + + +JNIEXPORT void JNICALL +Java_sun_lwawt_macosx_CCursorManager_nativeSetAllowsCursorSetInBackground +(JNIEnv *env, jclass class, jboolean allows) +{ + +JNF_COCOA_ENTER(env); +AWT_ASSERT_NOT_APPKIT_THREAD; + + SEL allowsSetInBackground_SEL = @selector(javaSetAllowsCursorSetInBackground:); + if ([[NSCursor class] respondsToSelector:allowsSetInBackground_SEL]) { + [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ + NSMethodSignature *allowsSetInBackground_sig = + [[NSCursor class] methodSignatureForSelector:allowsSetInBackground_SEL]; + NSInvocation *invocation = + [NSInvocation invocationWithMethodSignature:allowsSetInBackground_sig]; + BOOL arg = (BOOL)allows; + [invocation setSelector:allowsSetInBackground_SEL]; + [invocation setArgument:&arg atIndex:2]; + [invocation invokeWithTarget:[NSCursor class]]; + }]; + } + +JNF_COCOA_EXIT(env); + +} From 43ef89d4a63d4ed4a2db0418034e635ff571c085 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Wed, 2 May 2012 14:50:46 +0100 Subject: [PATCH 45/51] 7087021: TEST: com/sun/crypto/provider/Mac/MacClone.java failed on Solaris sparc 5.10 Reviewed-by: mullan --- jdk/test/com/sun/crypto/provider/Mac/MacClone.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/test/com/sun/crypto/provider/Mac/MacClone.java b/jdk/test/com/sun/crypto/provider/Mac/MacClone.java index 2f2d25f9d2f..83447767c37 100644 --- a/jdk/test/com/sun/crypto/provider/Mac/MacClone.java +++ b/jdk/test/com/sun/crypto/provider/Mac/MacClone.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 0000000 + * @bug 7087021 * @summary MacClone * @author Jan Luehe */ @@ -56,7 +56,7 @@ public class MacClone { KeyGenerator kgen = KeyGenerator.getInstance("DES"); SecretKey skey = kgen.generateKey(); - mac = Mac.getInstance("HmacSHA1"); + mac = Mac.getInstance("HmacSHA1", "SunJCE"); mac.init(skey); macClone = (Mac)mac.clone(); System.out.println(macClone.getProvider().toString()); From 4d0e923a60838f431d2b5ce65ea12e87d8990e4c Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Wed, 2 May 2012 17:54:18 +0400 Subject: [PATCH 46/51] 7154048: [macosx] At least drag twice, the toolbar can be dragged to the left side Reviewed-by: anthony, leonidr --- .../classes/sun/lwawt/LWWindowPeer.java | 59 ++-- .../sun/lwawt/macosx/CPlatformWindow.java | 5 + jdk/src/macosx/native/sun/awt/AWTView.h | 3 + jdk/src/macosx/native/sun/awt/AWTView.m | 14 +- jdk/src/macosx/native/sun/awt/AWTWindow.h | 1 + jdk/src/macosx/native/sun/awt/AWTWindow.m | 83 ++++++ .../DragWindowOutOfFrameTest.java | 267 ++++++++++++++++++ .../Mouse/EnterExitEvents/DragWindowTest.java | 219 ++++++++++++++ .../EnterExitEvents/ResizingFrameTest.java | 232 +++++++++++++++ jdk/test/java/awt/regtesthelpers/Util.java | 30 ++ 10 files changed, 884 insertions(+), 29 deletions(-) create mode 100644 jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java create mode 100644 jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java create mode 100644 jdk/test/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java diff --git a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java index 535a89be9c2..9e3796c7083 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -669,39 +669,42 @@ public class LWWindowPeer } } else { if (targetPeer != lastMouseEventPeer) { - // lastMouseEventPeer may be null if mouse was out of Java windows - if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { - // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit - // later), in which case lastWindowPeer is another window - if (lastWindowPeer != this) { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer); - // Additionally translate from this to lastWindowPeer coordinates - Rectangle lr = lastWindowPeer.getBounds(); - oldp.x += r.x - lr.x; - oldp.y += r.y - lr.y; - postEvent(new MouseEvent(lastMouseEventPeer.getTarget(), - MouseEvent.MOUSE_EXITED, + + if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) { + // lastMouseEventPeer may be null if mouse was out of Java windows + if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { + // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit + // later), in which case lastWindowPeer is another window + if (lastWindowPeer != this) { + Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer); + // Additionally translate from this to lastWindowPeer coordinates + Rectangle lr = lastWindowPeer.getBounds(); + oldp.x += r.x - lr.x; + oldp.y += r.y - lr.y; + postEvent(new MouseEvent(lastMouseEventPeer.getTarget(), + MouseEvent.MOUSE_EXITED, + when, modifiers, + oldp.x, oldp.y, screenX, screenY, + clickCount, popupTrigger, button)); + } else { + Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); + postEvent(new MouseEvent(lastMouseEventPeer.getTarget(), + MouseEvent.MOUSE_EXITED, + when, modifiers, + oldp.x, oldp.y, screenX, screenY, + clickCount, popupTrigger, button)); + } + } + if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) { + Point newp = targetPeer.windowToLocal(x, y, curWindowPeer); + postEvent(new MouseEvent(targetPeer.getTarget(), + MouseEvent.MOUSE_ENTERED, when, modifiers, - oldp.x, oldp.y, screenX, screenY, - clickCount, popupTrigger, button)); - } else { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); - postEvent(new MouseEvent(lastMouseEventPeer.getTarget(), - MouseEvent.MOUSE_EXITED, - when, modifiers, - oldp.x, oldp.y, screenX, screenY, + newp.x, newp.y, screenX, screenY, clickCount, popupTrigger, button)); } } lastMouseEventPeer = targetPeer; - if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) { - Point newp = targetPeer.windowToLocal(x, y, curWindowPeer); - postEvent(new MouseEvent(targetPeer.getTarget(), - MouseEvent.MOUSE_ENTERED, - when, modifiers, - newp.x, newp.y, screenX, screenY, - clickCount, popupTrigger, button)); - } } // TODO: fill "bdata" member of AWTEvent diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 588449858b4..9f8c8f545d0 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -61,6 +61,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage); private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename); private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY); + private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr); private static native int nativeGetScreenNSWindowIsOn_AppKitThread(long nsWindowPtr); @@ -582,6 +583,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo } } + nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + // 6. Configure stuff #2 updateFocusabilityForAutoRequestFocus(true); @@ -791,6 +794,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo throw new RuntimeException("Unknown window state: " + windowState); } + nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + // NOTE: the SWP.windowState field gets updated to the newWindowState // value when the native notification comes to us } diff --git a/jdk/src/macosx/native/sun/awt/AWTView.h b/jdk/src/macosx/native/sun/awt/AWTView.h index e6733e61ad3..f1d141fc2a0 100644 --- a/jdk/src/macosx/native/sun/awt/AWTView.h +++ b/jdk/src/macosx/native/sun/awt/AWTView.h @@ -52,9 +52,12 @@ BOOL fPAHNeedsToSelect; id cglLayer; // is a sublayer of view.layer + + BOOL mouseIsOver; } @property (nonatomic, retain) id cglLayer; +@property (nonatomic) BOOL mouseIsOver; - (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer; - (void) deliverJavaMouseEvent: (NSEvent *) event; diff --git a/jdk/src/macosx/native/sun/awt/AWTView.m b/jdk/src/macosx/native/sun/awt/AWTView.m index 4555d2732ca..896d05c4c72 100644 --- a/jdk/src/macosx/native/sun/awt/AWTView.m +++ b/jdk/src/macosx/native/sun/awt/AWTView.m @@ -61,6 +61,7 @@ static BOOL shouldUsePressAndHold() { @synthesize _dropTarget; @synthesize _dragSource; @synthesize cglLayer; +@synthesize mouseIsOver; // Note: Must be called on main (AppKit) thread only - (id) initWithRect: (NSRect) rect @@ -80,6 +81,8 @@ AWT_ASSERT_APPKIT_THREAD; fEnablePressAndHold = shouldUsePressAndHold(); fInPressAndHold = NO; fPAHNeedsToSelect = NO; + + mouseIsOver = NO; if (windowLayer != nil) { self.cglLayer = windowLayer; @@ -299,6 +302,16 @@ AWT_ASSERT_APPKIT_THREAD; */ -(void) deliverJavaMouseEvent: (NSEvent *) event { + + NSEventType type = [event type]; + + // check synthesized mouse entered/exited events + if ((type == NSMouseEntered && mouseIsOver) || (type == NSMouseExited && !mouseIsOver)) { + return; + }else if ((type == NSMouseEntered && !mouseIsOver) || (type == NSMouseExited && mouseIsOver)) { + mouseIsOver = !mouseIsOver; + } + [AWTToolkit eventCountPlusPlus]; JNIEnv *env = [ThreadUtilities getJNIEnv]; @@ -306,7 +319,6 @@ AWT_ASSERT_APPKIT_THREAD; NSPoint eventLocation = [event locationInWindow]; NSPoint localPoint = [self convertPoint: eventLocation fromView: nil]; NSPoint absP = [NSEvent mouseLocation]; - NSEventType type = [event type]; // Convert global numbers between Cocoa's coordinate system and Java. // TODO: need consitent way for doing that both with global as well as with local coordinates. diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.h b/jdk/src/macosx/native/sun/awt/AWTWindow.h index f511f9b739c..58280927fbf 100644 --- a/jdk/src/macosx/native/sun/awt/AWTWindow.h +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.h @@ -56,6 +56,7 @@ contentView:(NSView *)contentView; - (void) adjustGrowBoxWindow; +- (BOOL) isTopmostWindowUnderMouse; @end #endif _AWTWINDOW_H diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.m b/jdk/src/macosx/native/sun/awt/AWTWindow.m index 90c3372a979..7add839f8e6 100644 --- a/jdk/src/macosx/native/sun/awt/AWTWindow.m +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m @@ -170,6 +170,66 @@ AWT_ASSERT_APPKIT_THREAD; return self; } +// checks that this window is under the mouse cursor and this point is not overlapped by others windows +- (BOOL) isTopmostWindowUnderMouse { + + int currentWinID = [self windowNumber]; + + NSRect screenRect = [[NSScreen mainScreen] frame]; + NSPoint nsMouseLocation = [NSEvent mouseLocation]; + CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y); + + NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID); + + + for (NSDictionary *window in windows) { + int layer = [[window objectForKey:(id)kCGWindowLayer] intValue]; + if (layer == 0) { + int winID = [[window objectForKey:(id)kCGWindowNumber] intValue]; + CGRect rect; + CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect); + if (CGRectContainsPoint(rect, cgMouseLocation)) { + return currentWinID == winID; + } else if (currentWinID == winID) { + return NO; + } + } + } + return NO; +} + +- (void) synthesizeMouseEnteredExitedEvents { + + int eventType = 0; + BOOL isUnderMouse = [self isTopmostWindowUnderMouse]; + BOOL mouseIsOver = [[self contentView] mouseIsOver]; + + if (isUnderMouse && !mouseIsOver) { + eventType = NSMouseEntered; + } else if (!isUnderMouse && mouseIsOver) { + eventType = NSMouseExited; + } else { + return; + } + + NSPoint screenLocation = [NSEvent mouseLocation]; + NSPoint windowLocation = [self convertScreenToBase: screenLocation]; + int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask; + + NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType + location: windowLocation + modifierFlags: modifierFlags + timestamp: 0 + windowNumber: [self windowNumber] + context: nil + eventNumber: 0 + trackingNumber: 0 + userData: nil + ]; + + [[self contentView] deliverJavaMouseEvent: mouseEvent]; +} + - (void) dealloc { AWT_ASSERT_APPKIT_THREAD; @@ -669,6 +729,8 @@ AWT_ASSERT_NOT_APPKIT_THREAD; // ensure we repaint the whole window after the resize operation // (this will also re-enable screen updates, which were disabled above) // TODO: send PaintEvent + + [window synthesizeMouseEnteredExitedEvents]; }]; JNF_COCOA_EXIT(env); @@ -897,6 +959,27 @@ AWT_ASSERT_NOT_APPKIT_THREAD; JNF_COCOA_EXIT(env); } +/* + * Class: sun_lwawt_macosx_CPlatformWindow + * Method: nativeSynthesizeMouseEnteredExitedEvents + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents +(JNIEnv *env, jclass clazz, jlong windowPtr) +{ + JNF_COCOA_ENTER(env); + AWT_ASSERT_NOT_APPKIT_THREAD; + + AWTWindow *window = OBJC(windowPtr); + [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){ + AWT_ASSERT_APPKIT_THREAD; + + [window synthesizeMouseEnteredExitedEvents]; + }]; + + JNF_COCOA_EXIT(env); +} + /* * Class: sun_lwawt_macosx_CPlatformWindow * Method: nativeGetScreenNSWindowIsOn_AppKitThread diff --git a/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java b/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java new file mode 100644 index 00000000000..57637710a16 --- /dev/null +++ b/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7154048 + * @summary Window created under a mouse does not receive mouse enter event. + * Mouse Entered/Exited events should be generated during dragging the window + * out of the frame and to the frame. + * @library ../../regtesthelpers + * @build Util + * @author alexandr.scherbatiy area=awt.event + * @run main DragWindowOutOfFrameTest + */ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +import java.util.concurrent.*; +import sun.awt.SunToolkit; + +import test.java.awt.regtesthelpers.Util; + +public class DragWindowOutOfFrameTest { + + private static volatile int dragWindowMouseEnteredCount = 0; + private static volatile int dragWindowMouseExitedCount = 0; + private static volatile int dragWindowMouseReleasedCount = 0; + private static volatile int buttonMouseEnteredCount = 0; + private static volatile int buttonMouseExitedCount = 0; + private static volatile int labelMouseEnteredCount = 0; + private static volatile int labelMouseExitedCount = 0; + private static volatile int labelMouseReleasedCount = 0; + private static MyDragWindow dragWindow; + private static JLabel label; + private static JButton button; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + Point pointToClick = Util.invokeOnEDT(new Callable() { + + @Override + public Point call() throws Exception { + return getCenterPoint(label); + } + }); + + + robot.mouseMove(pointToClick.x, pointToClick.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (dragWindowMouseEnteredCount != 1 && dragWindowMouseExitedCount != 0) { + throw new RuntimeException( + "Wrong number mouse Entered/Exited events on Drag Window!"); + } + + Point pointToDrag = Util.invokeOnEDT(new Callable() { + + @Override + public Point call() throws Exception { + label.addMouseListener(new LabelMouseListener()); + button.addMouseListener(new ButtonMouseListener()); + return getCenterPoint(button); + } + }); + + robot.mouseMove(450, pointToClick.y); + toolkit.realSync(); + + if (labelMouseEnteredCount != 0 && labelMouseExitedCount != 1) { + throw new RuntimeException( + "Wrong number Mouse Entered/Exited events on label!"); + } + + robot.mouseMove(450, pointToDrag.y); + toolkit.realSync(); + + if (labelMouseEnteredCount != 0 && labelMouseExitedCount != 1) { + throw new RuntimeException( + "Wrong number Mouse Entered/Exited events on label!"); + } + + if (buttonMouseEnteredCount != 0 && buttonMouseExitedCount != 0) { + throw new RuntimeException( + "Wrong number Mouse Entered/Exited events on button!"); + } + + robot.mouseMove(pointToDrag.y, pointToDrag.y); + toolkit.realSync(); + + if (buttonMouseEnteredCount != 1 && buttonMouseExitedCount != 0) { + throw new RuntimeException( + "Wrong number Mouse Entered/Exited events on button!"); + } + + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (labelMouseReleasedCount != 1) { + throw new RuntimeException("No MouseReleased event on label!"); + } + } + + private static Point getCenterPoint(Component comp) { + Point p = comp.getLocationOnScreen(); + Rectangle rect = comp.getBounds(); + return new Point(p.x + rect.width / 2, p.y + rect.height / 2); + } + + private static void createAndShowGUI() { + + JFrame frame = new JFrame("Main Frame"); + frame.setLocation(100, 100); + frame.setSize(300, 200); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + label = new JLabel("Label"); + + DragWindowCreationMouseListener listener = new DragWindowCreationMouseListener(frame); + label.addMouseListener(listener); + label.addMouseMotionListener(listener); + + button = new JButton("Button"); + Panel panel = new Panel(new BorderLayout()); + + panel.add(label, BorderLayout.NORTH); + panel.add(button, BorderLayout.CENTER); + + frame.getContentPane().add(panel); + frame.setVisible(true); + + } + + private static Point getAbsoluteLocation(MouseEvent e) { + return new Point(e.getXOnScreen(), e.getYOnScreen()); + } + + static class MyDragWindow extends Window { + + public MyDragWindow(Window parent, Point location) { + super(parent); + setSize(500, 300); + setVisible(true); + JPanel panel = new JPanel(); + add(panel); + setLocation(location.x - 250, location.y - 150); + addMouseListener(new DragWindowMouseListener()); + } + + void dragTo(Point point) { + setLocation(point.x - 250, point.y - 150); + } + } + + static class DragWindowCreationMouseListener extends MouseAdapter { + + Point origin; + Window parent; + + public DragWindowCreationMouseListener(Window parent) { + this.parent = parent; + } + + @Override + public void mousePressed(MouseEvent e) { + if (dragWindow == null) { + dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e)); + } else { + dragWindow.setVisible(true); + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + labelMouseReleasedCount++; + if (dragWindow != null) { + dragWindow.setVisible(false); + } + } + + public void mouseDragged(MouseEvent e) { + if (dragWindow != null) { + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + } + + static class DragWindowMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + dragWindowMouseEnteredCount++; + } + + @Override + public void mouseExited(MouseEvent e) { + dragWindowMouseExitedCount++; + } + + @Override + public void mouseReleased(MouseEvent e) { + dragWindowMouseReleasedCount++; + } + } + + static class LabelMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + labelMouseEnteredCount++; + } + + @Override + public void mouseExited(MouseEvent e) { + labelMouseExitedCount++; + } + } + + static class ButtonMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + buttonMouseEnteredCount++; + } + + @Override + public void mouseExited(MouseEvent e) { + buttonMouseExitedCount++; + } + } +} diff --git a/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java b/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java new file mode 100644 index 00000000000..ccba2bcb7b0 --- /dev/null +++ b/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7154048 + * @summary Window created under a mouse does not receive mouse enter event. + * Mouse Entered/Exited events are wrongly generated during dragging the window + * from one component to another + * @library ../../regtesthelpers + * @build Util + * @author alexandr.scherbatiy area=awt.event + * @run main DragWindowTest + */ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +import java.util.concurrent.*; +import sun.awt.SunToolkit; + +import test.java.awt.regtesthelpers.Util; + +public class DragWindowTest { + + private static volatile int dragWindowMouseEnteredCount = 0; + private static volatile int dragWindowMouseReleasedCount = 0; + private static volatile int buttonMouseEnteredCount = 0; + private static volatile int labelMouseReleasedCount = 0; + private static MyDragWindow dragWindow; + private static JLabel label; + private static JButton button; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + Point pointToClick = Util.invokeOnEDT(new Callable() { + + @Override + public Point call() throws Exception { + return getCenterPoint(label); + } + }); + + + robot.mouseMove(pointToClick.x, pointToClick.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (dragWindowMouseEnteredCount != 1) { + throw new RuntimeException("No MouseEntered event on Drag Window!"); + } + + Point pointToDrag = Util.invokeOnEDT(new Callable() { + + @Override + public Point call() throws Exception { + button.addMouseListener(new ButtonMouseListener()); + return getCenterPoint(button); + } + }); + + robot.mouseMove(pointToDrag.x, pointToDrag.y); + toolkit.realSync(); + + if (buttonMouseEnteredCount != 0) { + throw new RuntimeException("Extra MouseEntered event on button!"); + } + + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (labelMouseReleasedCount != 1) { + throw new RuntimeException("No MouseReleased event on label!"); + } + + } + + private static Point getCenterPoint(Component comp) { + Point p = comp.getLocationOnScreen(); + Rectangle rect = comp.getBounds(); + return new Point(p.x + rect.width / 2, p.y + rect.height / 2); + } + + private static void createAndShowGUI() { + + JFrame frame = new JFrame("Main Frame"); + frame.setSize(300, 200); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + label = new JLabel("Label"); + + LabelMouseListener listener = new LabelMouseListener(frame); + label.addMouseListener(listener); + label.addMouseMotionListener(listener); + + button = new JButton("Button"); + Panel panel = new Panel(new BorderLayout()); + + panel.add(label, BorderLayout.NORTH); + panel.add(button, BorderLayout.CENTER); + + frame.getContentPane().add(panel); + frame.setVisible(true); + + } + + private static Point getAbsoluteLocation(MouseEvent e) { + return new Point(e.getXOnScreen(), e.getYOnScreen()); + } + + static class MyDragWindow extends Window { + + static int d = 30; + + public MyDragWindow(Window parent, Point location) { + super(parent); + setSize(150, 150); + setVisible(true); + JPanel panel = new JPanel(); + add(panel); + setLocation(location.x - d, location.y - d); + addMouseListener(new DragWindowMouseListener()); + } + + void dragTo(Point point) { + setLocation(point.x - d, point.y - d); + } + } + + static class LabelMouseListener extends MouseAdapter { + + Point origin; + Window parent; + + public LabelMouseListener(Window parent) { + this.parent = parent; + } + + @Override + public void mousePressed(MouseEvent e) { + if (dragWindow == null) { + dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e)); + } else { + dragWindow.setVisible(true); + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + labelMouseReleasedCount++; + if (dragWindow != null) { + dragWindow.setVisible(false); + } + } + + public void mouseDragged(MouseEvent e) { + if (dragWindow != null) { + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + } + + static class DragWindowMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + dragWindowMouseEnteredCount++; + } + + @Override + public void mouseReleased(MouseEvent e) { + dragWindowMouseReleasedCount++; + } + } + + static class ButtonMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + buttonMouseEnteredCount++; + } + } +} diff --git a/jdk/test/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java b/jdk/test/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java new file mode 100644 index 00000000000..9a9042b1a70 --- /dev/null +++ b/jdk/test/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7154048 + * @summary Programmatically resized window does not receive mouse entered/exited events + * @author alexandr.scherbatiy area=awt.event + * @run main ResizingFrameTest + */ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import sun.awt.SunToolkit; + +public class ResizingFrameTest { + + private static volatile int mouseEnteredCount = 0; + private static volatile int mouseExitedCount = 0; + private static JFrame frame; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.mouseMove(100, 100); + + // create a frame under the mouse cursor + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + + toolkit.realSync(); + + if (mouseEnteredCount != 1 || mouseExitedCount != 0) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + // iconify frame + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setExtendedState(Frame.ICONIFIED); + } + }); + + toolkit.realSync(); + robot.delay(200); + + if (mouseEnteredCount != 1 || mouseExitedCount != 1) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + // deiconify frame + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setExtendedState(Frame.NORMAL); + } + }); + + toolkit.realSync(); + robot.delay(200); + + if (mouseEnteredCount != 2 || mouseExitedCount != 1) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + // move the mouse out of the frame + robot.mouseMove(500, 500); + toolkit.realSync(); + robot.delay(200); + + if (mouseEnteredCount != 2 || mouseExitedCount != 2) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + // maximize the frame + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setExtendedState(Frame.MAXIMIZED_BOTH); + } + }); + + toolkit.realSync(); + robot.delay(200); + + if (mouseEnteredCount != 3 || mouseExitedCount != 2) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + + // demaximize the frame + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setExtendedState(Frame.NORMAL); + } + }); + + toolkit.realSync(); + robot.delay(200); + + if (mouseEnteredCount != 3 || mouseExitedCount != 3) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + + } + + // move the frame under the mouse + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setLocation(400, 400); + } + }); + + toolkit.realSync(); + robot.delay(200); + + if (mouseEnteredCount != 4 || mouseExitedCount != 3) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + // move the frame out of the mouse + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setLocation(100, 100); + } + }); + + toolkit.realSync(); + robot.delay(400); + + if (mouseEnteredCount != 4 || mouseExitedCount != 4) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + // enlarge the frame bounds + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setBounds(100, 100, 800, 800); + } + }); + + toolkit.realSync(); + robot.delay(200); + + if (mouseEnteredCount != 5 || mouseExitedCount != 4) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + + // make the frame bounds smaller + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + frame.setBounds(100, 100, 200, 300); + } + }); + + toolkit.realSync(); + robot.delay(400); + + + if (mouseEnteredCount != 5 || mouseExitedCount != 5) { + throw new RuntimeException("No Mouse Entered/Exited events!"); + } + } + + private static void createAndShowGUI() { + + frame = new JFrame("Main Frame"); + frame.setSize(300, 200); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + frame.addMouseListener(new MouseAdapter() { + + @Override + public void mouseEntered(MouseEvent e) { + mouseEnteredCount++; + } + + @Override + public void mouseExited(MouseEvent e) { + mouseExitedCount++; + } + }); + + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/jdk/test/java/awt/regtesthelpers/Util.java b/jdk/test/java/awt/regtesthelpers/Util.java index 5774e0bb732..42be600eef1 100644 --- a/jdk/test/java/awt/regtesthelpers/Util.java +++ b/jdk/test/java/awt/regtesthelpers/Util.java @@ -600,4 +600,34 @@ public final class Util { time, printEvent); } + + + /** + * Invokes the task on the EDT thread. + * + * @return result of the task + */ + public static T invokeOnEDT(final java.util.concurrent.Callable task) throws Exception { + final java.util.List result = new java.util.ArrayList(1); + final Exception[] exception = new Exception[1]; + + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + try { + result.add(task.call()); + } catch (Exception e) { + exception[0] = e; + } + } + }); + + if (exception[0] != null) { + throw exception[0]; + } + + return result.get(0); + } + } From 1f736c82a9c99c8dcd328d8c26c2af3e306e1c36 Mon Sep 17 00:00:00 2001 From: Edvard Wendelin Date: Thu, 3 May 2012 14:17:30 +0200 Subject: [PATCH 47/51] 7154130: Add Mac OS X Instructions to README-builds.html Reviewed-by: ohair --- README-builds.html | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README-builds.html b/README-builds.html index 1761534fab2..5e8d86af449 100644 --- a/README-builds.html +++ b/README-builds.html @@ -65,6 +65,7 @@

  • Basic Linux System Setup
  • Basic Solaris System Setup
  • Basic Windows System Setup
  • +
  • Basic Mac OS X System Setup
  • Build Dependencies
    • Bootstrap JDK
    • @@ -230,6 +231,12 @@ Microsoft Visual Studio C++ 2010 Professional Edition JDK 6u18 + + Mac OS X X64 (64-bit) + Mac OS X 10.7.3 "Lion" + XCode 4.1 or later + Java for OS X Lion Update 1 +

      @@ -951,6 +958,36 @@


      +

      Basic Mac OS X System Setup

      +
      + X64 only: + The minimum recommended hardware for building + the Mac OS X version is any 64-bit capable Intel processor, at least 2 + GB of RAM, and approximately 3 GB of free disk space. You should also + have OS X Lion 10.7.3 installed. +
      + + +

      Basic Mac OS X Check List

      +
      +
        +
      1. + Install XCode 4.1 or newer. + If you install XCode 4.3 or newer, make sure you also install + "Command line tools" found under the preferences pane "Downloads". +
      2. +
      3. + Install "Java for OS X Lion Update 1", + set ALT_BOOTDIR to `/usr/libexec/java_home -v 1.6` +
      4. +
      5. + Optional Import JDK, set + ALT_JDK_IMPORT_PATH. +
      6. +
      +
      + +

      Build Dependencies

      Depending on the platform, the OpenJDK build process has some basic @@ -1194,6 +1231,10 @@ set INCLUDE=%VSINSTALLDIR%\vc\include;%WindowsSdkDir%\include set LIB=%VSINSTALLDIR%\vc\lib\amd64;%WindowsSdkDir%\lib\x64 + OS X Lion 10.7.3: LLVM GCC +
      + LLVM GCC is bundled with XCode. The version should be at least 4.2.1. +

      Zip and Unzip

      From d1c83acabb4f929adc14b174653151ab708fd10a Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 4 May 2012 14:10:31 -0700 Subject: [PATCH 48/51] Added tag hs24-b09 for changeset 6123dd756c56 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 5a1b5041315..677a59f7b9d 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -242,3 +242,4 @@ f284b08835584517c1ca3dd67341f569e763841f jdk8-b34 f621660a297baa48fab9dca28e99d318826e8304 jdk8-b35 dff6e3459210f8dd0430b9b03ccc99280560da30 hs24-b08 50b4400ca1ecb2ac2fde35f5e53ec8f04b86be7f jdk8-b36 +7d5ec8bf38d1b12e0e09ec381f10976b8beede3b hs24-b09 From 1beaa06ed7fd9db52f55bde094f43a078531d166 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 9 May 2012 13:07:33 -0700 Subject: [PATCH 49/51] Added tag jdk8-b37 for changeset 1246483aab30 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 432c46d8709..0494bf52131 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -158,3 +158,4 @@ cc771d92284f71765eca14d6d08703c4af254c04 jdk8-b21 894a478d2c4819a1a0f230bd7bdd09f3b2de9a8c jdk8-b34 5285317ebb4e8e4f6d8d52b5616fa801e2ea844d jdk8-b35 6a6ba0a07f33d37a2f97b1107e60c6a9a69ec84d jdk8-b36 +b2972095a4b1e2a97409b7c3df61f3b263a5ce14 jdk8-b37 From e53314cbb74a584729bdbfdbb36fb8b80fa2431a Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 9 May 2012 13:07:42 -0700 Subject: [PATCH 50/51] Added tag jdk8-b37 for changeset f2944668a5b3 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 5a1b5041315..a50c47199c5 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -242,3 +242,4 @@ f284b08835584517c1ca3dd67341f569e763841f jdk8-b34 f621660a297baa48fab9dca28e99d318826e8304 jdk8-b35 dff6e3459210f8dd0430b9b03ccc99280560da30 hs24-b08 50b4400ca1ecb2ac2fde35f5e53ec8f04b86be7f jdk8-b36 +bfcf92bfefb82da00f7fdbf0d9273feaa0a9456d jdk8-b37 From 688375fd8715535ed8e16adc9854c53eae9f53a7 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 9 May 2012 13:07:57 -0700 Subject: [PATCH 51/51] Added tag jdk8-b37 for changeset 6cc8efda172c --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 6f8b44b7576..dbcbbd5fb5d 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -158,3 +158,4 @@ ddfe5562f61f54ed2121ac0c73b688b94f3e66b5 jdk8-b32 29b680393f33bf953688c17d93aca7a870ca4024 jdk8-b34 2e3e1356ffbddb2ae95c08da72830ba9ab8b3181 jdk8-b35 45da9cb055ee258dc09e69c1718e27eadea38e45 jdk8-b36 +9e82ac15ab80370d6e021aea7b98c7c9626adb5e jdk8-b37