This commit is contained in:
Kelly O'Hair 2011-03-29 20:19:55 -07:00
commit bd3a9c0f0a
265 changed files with 27167 additions and 5891 deletions

View File

@ -109,3 +109,4 @@ bdc069d3f9101f89ec3f81c2950ee2d68fa846d3 jdk7-b130
6bbc7a4734952ae7604578f270e1566639fa8752 jdk7-b132 6bbc7a4734952ae7604578f270e1566639fa8752 jdk7-b132
5e5f68a01d12a4432172f384d5201f3a05254493 jdk7-b133 5e5f68a01d12a4432172f384d5201f3a05254493 jdk7-b133
554adcfb615e63e62af530b1c10fcf7813a75b26 jdk7-b134 554adcfb615e63e62af530b1c10fcf7813a75b26 jdk7-b134
d8ced728159fbb2caa8b6adb477fd8efdbbdf179 jdk7-b135

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -44,7 +44,7 @@ SUBDIRS = java security net/ssl jarsigner
SUBDIRS_management = jmx SUBDIRS_management = jmx
SUBDIRS_desktop = image SUBDIRS_desktop = image
SUBDIRS_enterprise = crypto/provider jndi \ SUBDIRS_enterprise = crypto/provider jndi \
org xml rowset net/httpserver org rowset net/httpserver
SUBDIRS_misc = $(SCRIPT_SUBDIR) tracing servicetag nio demo SUBDIRS_misc = $(SCRIPT_SUBDIR) tracing servicetag nio demo
# Omit mirror since it's built with the apt tool. # Omit mirror since it's built with the apt tool.

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -107,6 +107,8 @@ CFLAGS_REQUIRED_sparcv9 += -m64 -mcpu=v9
LDFLAGS_COMMON_sparcv9 += -m64 -mcpu=v9 LDFLAGS_COMMON_sparcv9 += -m64 -mcpu=v9
CFLAGS_REQUIRED_sparc += -m32 -mcpu=v9 CFLAGS_REQUIRED_sparc += -m32 -mcpu=v9
LDFLAGS_COMMON_sparc += -m32 -mcpu=v9 LDFLAGS_COMMON_sparc += -m32 -mcpu=v9
CFLAGS_REQUIRED_arm += -fsigned-char -D_LITTLE_ENDIAN
CFLAGS_REQUIRED_ppc += -fsigned-char -D_BIG_ENDIAN
ifeq ($(ZERO_BUILD), true) ifeq ($(ZERO_BUILD), true)
CFLAGS_REQUIRED = $(ZERO_ARCHFLAG) CFLAGS_REQUIRED = $(ZERO_ARCHFLAG)
ifeq ($(ZERO_ENDIANNESS), little) ifeq ($(ZERO_ENDIANNESS), little)
@ -143,11 +145,9 @@ endif
# #
# Misc compiler options # Misc compiler options
# #
ifeq ($(ARCH),ppc) ifneq ($(ARCH),ppc)
CFLAGS_COMMON = -fsigned-char
else # ARCH
CFLAGS_COMMON = -fno-strict-aliasing CFLAGS_COMMON = -fno-strict-aliasing
endif # ARCH endif
PIC_CODE_LARGE = -fPIC PIC_CODE_LARGE = -fPIC
PIC_CODE_SMALL = -fpic PIC_CODE_SMALL = -fpic
GLOBAL_KPIC = $(PIC_CODE_LARGE) GLOBAL_KPIC = $(PIC_CODE_LARGE)
@ -219,8 +219,19 @@ ifdef LIBRARY
# The environment variable LD_LIBRARY_PATH will over-ride these runpaths. # The environment variable LD_LIBRARY_PATH will over-ride these runpaths.
# Try: 'readelf -d lib*.so' to see these settings in a library. # Try: 'readelf -d lib*.so' to see these settings in a library.
# #
LDFLAGS_COMMON += -Xlinker -z -Xlinker origin -Xlinker -rpath -Xlinker \$$ORIGIN Z_ORIGIN_FLAG/sparc = -Xlinker -z -Xlinker origin
LDFLAGS_COMMON += $(LD_RUNPATH_EXTRAS:%=-Xlinker -z -Xlinker origin -Xlinker -rpath -Xlinker \$$ORIGIN/%) Z_ORIGIN_FLAG/i586 = -Xlinker -z -Xlinker origin
Z_ORIGIN_FLAG/amd64 = -Xlinker -z -Xlinker origin
Z_ORIGIN_FLAG/ia64 = -Xlinker -z -Xlinker origin
Z_ORIGIN_FLAG/arm =
Z_ORIGIN_FLAG/ppc =
Z_ORIGIN_FLAG/zero = -Xlinker -z -Xlinker origin
LDFLAG_Z_ORIGIN = $(Z_ORIGIN_FLAG/$(ARCH_FAMILY))
LDFLAGS_COMMON += $(LDFLAG_Z_ORIGIN) -Xlinker -rpath -Xlinker \$$ORIGIN
LDFLAGS_COMMON += $(LD_RUNPATH_EXTRAS:%=$(LDFLAG_Z_ORIGIN) -Xlinker -rpath -Xlinker \$$ORIGIN/%)
endif endif
EXTRA_LIBS += -lc EXTRA_LIBS += -lc
@ -315,7 +326,6 @@ override LIBNSL =
override LIBTHREAD = override LIBTHREAD =
override MOOT_PRIORITIES = true override MOOT_PRIORITIES = true
override NO_INTERRUPTIBLE_IO = true override NO_INTERRUPTIBLE_IO = true
override OPENWIN_HOME = /usr/X11R6
ifeq ($(ARCH), amd64) ifeq ($(ARCH), amd64)
override OPENWIN_LIB = $(OPENWIN_HOME)/lib64 override OPENWIN_LIB = $(OPENWIN_HOME)/lib64
else else
@ -359,3 +369,9 @@ else
INCLUDE_SA = true INCLUDE_SA = true
endif endif
ifdef CROSS_COMPILE_ARCH
# X11 headers are not under /usr/include
OTHER_CFLAGS += -I$(OPENWIN_HOME)/include
OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include
OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include
endif

View File

@ -115,6 +115,36 @@ endif
include $(JDK_TOPDIR)/make/common/Defs-$(PLATFORM).gmk include $(JDK_TOPDIR)/make/common/Defs-$(PLATFORM).gmk
#
# Cross-compilation Settings
#
ifdef CROSS_COMPILE_ARCH
# Can't run the tools we just built
USE_ONLY_BOOTDIR_TOOLS = true
# When cross-compiling CC generates code for the target, but
# some parts of the build generate C code that has to be compiled
# and executed on the build host - HOST_CC is the 'local' compiler.
# For linux the default is /usr/bin/gcc; other platforms need to
# set it explicitly
ifeq ($(PLATFORM), linux)
ifndef HOST_CC
HOST_CC = $(USRBIN_PATH)gcc
endif
endif
else
# Must set HOST_CC if not already set
ifndef HOST_CC
HOST_CC = $(CC)
endif
endif
# Reset the VM name for client-only builds
ifdef BUILD_CLIENT_ONLY
VM_NAME = client
endif
# #
# Freetype logic is applicable to OpenJDK only # Freetype logic is applicable to OpenJDK only
# #
@ -334,8 +364,7 @@ endif
INCLUDES = -I. -I$(CLASSHDRDIR) \ INCLUDES = -I. -I$(CLASSHDRDIR) \
$(patsubst %,-I%,$(subst $(CLASSPATH_SEPARATOR), ,$(VPATH.h))) $(OTHER_INCLUDES) $(patsubst %,-I%,$(subst $(CLASSPATH_SEPARATOR), ,$(VPATH.h))) $(OTHER_INCLUDES)
OTHER_CPPFLAGS = $(INCLUDES) OTHER_CPPFLAGS += $(INCLUDES)
# #
# vpaths. These are the default locations searched for source files. # vpaths. These are the default locations searched for source files.
@ -466,9 +495,11 @@ CXXFLAGS_$(VARIANT)/BYFILE = $(CXXFLAGS_$(VARIANT)/$(@F)) \
# #
# Tool flags # Tool flags
# #
# EXTRA_CFLAGS are used to define cross-compilation options
#
ASFLAGS = $(ASFLAGS_$(VARIANT)) $(ASFLAGS_COMMON) $(OTHER_ASFLAGS) ASFLAGS = $(ASFLAGS_$(VARIANT)) $(ASFLAGS_COMMON) $(OTHER_ASFLAGS)
CFLAGS = $(CFLAGS_$(VARIANT)/BYFILE) $(CFLAGS_COMMON) $(OTHER_CFLAGS) CFLAGS = $(CFLAGS_$(VARIANT)/BYFILE) $(CFLAGS_COMMON) $(OTHER_CFLAGS) $(EXTRA_CFLAGS)
CXXFLAGS = $(CXXFLAGS_$(VARIANT)/BYFILE) $(CXXFLAGS_COMMON) $(OTHER_CXXFLAGS) CXXFLAGS = $(CXXFLAGS_$(VARIANT)/BYFILE) $(CXXFLAGS_COMMON) $(OTHER_CXXFLAGS) $(EXTRA_CFLAGS)
CPPFLAGS = $(CPPFLAGS_$(VARIANT)) $(CPPFLAGS_COMMON) $(OTHER_CPPFLAGS) \ CPPFLAGS = $(CPPFLAGS_$(VARIANT)) $(CPPFLAGS_COMMON) $(OTHER_CPPFLAGS) \
$(DEFINES) $(OPTIONS:%=-D%) $(DEFINES) $(OPTIONS:%=-D%)
LDFLAGS = $(LDFLAGS_$(VARIANT)) $(LDFLAGS_COMMON) $(OTHER_LDFLAGS) LDFLAGS = $(LDFLAGS_$(VARIANT)) $(LDFLAGS_COMMON) $(OTHER_LDFLAGS)

View File

@ -83,7 +83,7 @@ ifneq (,$(findstring $(PLATFORM), linux solaris)) # UNIX systems
endif endif
endif endif
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
LDFLAGS += -Wl,-z -Wl,origin LDFLAGS += $(LDFLAG_Z_ORIGIN)
LDFLAGS += -Wl,--allow-shlib-undefined LDFLAGS += -Wl,--allow-shlib-undefined
LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli
LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH)/jli LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH)/jli

View File

@ -54,9 +54,6 @@ EXCLUDE_PROPWARN_PKGS = com.sun.java.swing.plaf.windows \
com.sun.java.swing.plaf.motif \ com.sun.java.swing.plaf.motif \
com.sun.java.swing.plaf.gtk com.sun.java.swing.plaf.gtk
# This is a stopgap until 6839872 is fixed.
EXCLUDE_PROPWARN_PKGS += sun.dyn
# #
# Include the exported private packages in ct.sym. # Include the exported private packages in ct.sym.
# This is an interim solution until the ct.sym is replaced # This is an interim solution until the ct.sym is replaced

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -55,6 +55,7 @@ IMPORT_TOOLS_PACKAGES += \
com/sun/tools/internal/xjc \ com/sun/tools/internal/xjc \
com/sun/tools/internal/ws \ com/sun/tools/internal/ws \
com/sun/tools/internal/jxc \ com/sun/tools/internal/jxc \
org/relaxng \
META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory \ META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory \
META-INF/services/com.sun.tools.xjc.Plugin META-INF/services/com.sun.tools.internal.xjc.Plugin

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -102,6 +102,14 @@ else
COMPILER_PATH =/usr/bin/ COMPILER_PATH =/usr/bin/
endif endif
# OPENWIN_HOME: path to where the X11 environment is installed.
# NOTE: Must end with / so that it could be empty, allowing PATH usage.
ifneq ($(ALT_OPENWIN_HOME),)
OPENWIN_HOME :=$(call PrefixPath,$(ALT_OPENWIN_HOME))
else
OPENWIN_HOME =/usr/X11R6/
endif
# DEVTOOLS_PATH: for other tools required for building (such as zip, etc.) # DEVTOOLS_PATH: for other tools required for building (such as zip, etc.)
# NOTE: Must end with / so that it could be empty, allowing PATH usage. # NOTE: Must end with / so that it could be empty, allowing PATH usage.
ifneq "$(origin ALT_DEVTOOLS_PATH)" "undefined" ifneq "$(origin ALT_DEVTOOLS_PATH)" "undefined"
@ -181,6 +189,7 @@ HOTSPOT_SERVER_PATH:=$(call AltCheckValue,HOTSPOT_SERVER_PATH)
# Macro to check it's input file for banned dependencies and verify the # Macro to check it's input file for banned dependencies and verify the
# binary built properly. Relies on process exit code. # binary built properly. Relies on process exit code.
ifndef CROSS_COMPILE_ARCH
define binary_file_verification # binary_file define binary_file_verification # binary_file
( \ ( \
$(ECHO) "Checking for mapfile use in: $1" && \ $(ECHO) "Checking for mapfile use in: $1" && \
@ -193,4 +202,10 @@ define binary_file_verification # binary_file
( $(READELF) -d $1 | $(EGREP) 'NEEDED|RUNPATH|RPATH' ) \ ( $(READELF) -d $1 | $(EGREP) 'NEEDED|RUNPATH|RPATH' ) \
) )
endef endef
else
define binary_file_verification
( \
$(ECHO) "Skipping binary file verification for cross-compile build" \
)
endef
endif

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -190,6 +190,7 @@ HOTSPOT_SERVER_PATH:=$(call AltCheckValue,HOTSPOT_SERVER_PATH)
# Macro to check it's input file for banned dependencies and verify the # Macro to check it's input file for banned dependencies and verify the
# binary built properly. Relies on process exit code. # binary built properly. Relies on process exit code.
ifndef CROSS_COMPILE_ARCH
define binary_file_verification # binary_file define binary_file_verification # binary_file
( \ ( \
$(ECHO) "Checking for mapfile use in: $1" && \ $(ECHO) "Checking for mapfile use in: $1" && \
@ -202,4 +203,10 @@ define binary_file_verification # binary_file
( $(DUMP) -L -v $1 | $(EGREP) 'NEEDED|RUNPATH|RPATH' ) \ ( $(DUMP) -L -v $1 | $(EGREP) 'NEEDED|RUNPATH|RPATH' ) \
) )
endef endef
else
define binary_file_verification
( \
$(ECHO) "Skipping binary file verification for cross-compile build" \
)
endef
endif

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -68,9 +68,23 @@ ifeq ($(PLATFORM),windows)
endif endif
# Utilities # Utilities
ifdef CROSS_COMPILE_ARCH
AR = $(COMPILER_PATH)ar
AS = $(COMPILER_PATH)as
LD = $(COMPILER_PATH)ld
MCS = $(COMPILER_PATH)mcs
NM = $(COMPILER_PATH)nm
STRIP = $(COMPILER_PATH)strip
else
AR = $(UTILS_CCS_BIN_PATH)ar
AS = $(UTILS_CCS_BIN_PATH)as
LD = $(UTILS_CCS_BIN_PATH)ld
MCS = $(UTILS_CCS_BIN_PATH)mcs
NM = $(UTILS_CCS_BIN_PATH)nm
STRIP = $(UTILS_CCS_BIN_PATH)strip
endif
ADB = $(UTILS_COMMAND_PATH)adb ADB = $(UTILS_COMMAND_PATH)adb
AR = $(UTILS_CCS_BIN_PATH)ar
AS = $(UTILS_CCS_BIN_PATH)as
BASENAME = $(UTILS_COMMAND_PATH)basename BASENAME = $(UTILS_COMMAND_PATH)basename
BZIP2 = $(UTILS_COMMAND_PATH)bzip2 BZIP2 = $(UTILS_COMMAND_PATH)bzip2
CAT = $(UTILS_COMMAND_PATH)cat CAT = $(UTILS_COMMAND_PATH)cat
@ -99,19 +113,16 @@ HEAD = $(UTILS_USR_BIN_PATH)head
ID = $(UTILS_COMMAND_PATH)id ID = $(UTILS_COMMAND_PATH)id
ISAINFO = $(UTILS_COMMAND_PATH)isainfo ISAINFO = $(UTILS_COMMAND_PATH)isainfo
KSH = $(UTILS_COMMAND_PATH)ksh KSH = $(UTILS_COMMAND_PATH)ksh
LD = $(UTILS_CCS_BIN_PATH)ld
LDD = $(UTILS_USR_BIN_PATH)ldd LDD = $(UTILS_USR_BIN_PATH)ldd
LEX = $(UTILS_CCS_BIN_PATH)lex LEX = $(UTILS_CCS_BIN_PATH)lex
LN = $(UTILS_COMMAND_PATH)ln LN = $(UTILS_COMMAND_PATH)ln
LS = $(UTILS_COMMAND_PATH)ls LS = $(UTILS_COMMAND_PATH)ls
MCS = $(UTILS_CCS_BIN_PATH)mcs
M4 = $(UTILS_CCS_BIN_PATH)m4 M4 = $(UTILS_CCS_BIN_PATH)m4
MKDIR = $(UTILS_COMMAND_PATH)mkdir MKDIR = $(UTILS_COMMAND_PATH)mkdir
MKSINFO = $(UTILS_COMMAND_PATH)mksinfo MKSINFO = $(UTILS_COMMAND_PATH)mksinfo
MSGFMT = $(UTILS_USR_BIN_PATH)msgfmt MSGFMT = $(UTILS_USR_BIN_PATH)msgfmt
MV = $(UTILS_COMMAND_PATH)mv MV = $(UTILS_COMMAND_PATH)mv
NAWK = $(UTILS_USR_BIN_PATH)nawk NAWK = $(UTILS_USR_BIN_PATH)nawk
NM = $(UTILS_CCS_BIN_PATH)nm
PKGMK = $(UTILS_COMMAND_PATH)pkgmk PKGMK = $(UTILS_COMMAND_PATH)pkgmk
PRINTF = $(UTILS_USR_BIN_PATH)printf PRINTF = $(UTILS_USR_BIN_PATH)printf
PWD = $(UTILS_COMMAND_PATH)pwd PWD = $(UTILS_COMMAND_PATH)pwd
@ -123,7 +134,6 @@ SED = $(UTILS_COMMAND_PATH)sed
SH = $(UTILS_COMMAND_PATH)sh SH = $(UTILS_COMMAND_PATH)sh
SHOWREV = $(UTILS_USR_BIN_PATH)showrev SHOWREV = $(UTILS_USR_BIN_PATH)showrev
SORT = $(UTILS_COMMAND_PATH)sort SORT = $(UTILS_COMMAND_PATH)sort
STRIP = $(UTILS_CCS_BIN_PATH)strip
TAIL = $(UTILS_USR_BIN_PATH)tail TAIL = $(UTILS_USR_BIN_PATH)tail
TAR = $(UTILS_COMMAND_PATH)tar TAR = $(UTILS_COMMAND_PATH)tar
TEST = $(UTILS_USR_BIN_PATH)test TEST = $(UTILS_USR_BIN_PATH)test
@ -186,14 +196,16 @@ ifeq ($(PLATFORM),linux)
# Intrinsic unix command, with backslash-escaped character interpretation # Intrinsic unix command, with backslash-escaped character interpretation
ECHO = /bin/echo -e ECHO = /bin/echo -e
# These are really in UTILS_USR_BIN_PATH on Linux # These are really in UTILS_USR_BIN_PATH on Linux
AR = $(UTILS_USR_BIN_PATH)ar ifndef CROSS_COMPILE_ARCH
AS = $(UTILS_USR_BIN_PATH)as AR = $(UTILS_USR_BIN_PATH)ar
LD = $(UTILS_USR_BIN_PATH)ld AS = $(UTILS_USR_BIN_PATH)as
LD = $(UTILS_USR_BIN_PATH)ld
MCS = $(UTILS_USR_BIN_PATH)mcs
NM = $(UTILS_USR_BIN_PATH)nm
STRIP = $(UTILS_USR_BIN_PATH)strip
endif
LEX = $(UTILS_USR_BIN_PATH)lex LEX = $(UTILS_USR_BIN_PATH)lex
MCS = $(UTILS_USR_BIN_PATH)mcs
M4 = $(UTILS_USR_BIN_PATH)m4 M4 = $(UTILS_USR_BIN_PATH)m4
NM = $(UTILS_USR_BIN_PATH)nm
STRIP = $(UTILS_USR_BIN_PATH)strip
YACC = $(UTILS_USR_BIN_PATH)yacc YACC = $(UTILS_USR_BIN_PATH)yacc
endif endif

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -138,11 +138,15 @@ ifeq ($(PLATFORM), solaris)
endif endif
REQUIRED_COMPILER_NAME = Sun Studio 12 Update 1 REQUIRED_COMPILER_NAME = Sun Studio 12 Update 1
REQUIRED_COMPILER_VERSION = SS12u1 REQUIRED_COMPILER_VERSION = SS12u1
ifeq ($(CC_VERSION),sun) # Cross-compilation compiler versions are target specific
REQUIRED_CC_VER = 5.10 # so don't set a required version if cross-compiling
endif ifndef CROSS_COMPILE_ARCH
ifeq ($(CC_VERSION),gcc) ifeq ($(CC_VERSION),sun)
REQUIRED_CC_VER = 3.4.3 REQUIRED_CC_VER = 5.10
endif
ifeq ($(CC_VERSION),gcc)
REQUIRED_CC_VER = 3.4.3
endif
endif endif
REQUIRED_GCC_VER = 2.95.2 REQUIRED_GCC_VER = 2.95.2
endif endif
@ -158,11 +162,15 @@ ifeq ($(PLATFORM), linux)
REQUIRED_COMPILER_NAME = GCC4 REQUIRED_COMPILER_NAME = GCC4
REQUIRED_COMPILER_VERSION = GCC4 REQUIRED_COMPILER_VERSION = GCC4
REQUIRED_GCC_VER = 2.95 REQUIRED_GCC_VER = 2.95
ifeq ($(CC_VERSION),gcc) # Cross-compilation compiler versions are target specific
REQUIRED_CC_VER = 4.3.0 # so don't set a required version if cross-compiling
endif ifndef CROSS_COMPILE_ARCH
ifeq ($(CC_VERSION),sun) ifeq ($(CC_VERSION),gcc)
REQUIRED_CC_VER = 5.10 REQUIRED_CC_VER = 4.3.0
endif
ifeq ($(CC_VERSION),sun)
REQUIRED_CC_VER = 5.10
endif
endif endif
endif endif

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1997, 20010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -155,7 +155,11 @@ endif
ifeq ($(SYSTEM_UNAME), Linux) ifeq ($(SYSTEM_UNAME), Linux)
PLATFORM = linux PLATFORM = linux
# Arch and OS name/version # Arch and OS name/version
mach := $(shell uname -m) ifdef CROSS_COMPILE_ARCH
mach := $(CROSS_COMPILE_ARCH)
else
mach := $(shell uname -m)
endif
archExpr = case "$(mach)" in \ archExpr = case "$(mach)" in \
i[3-9]86) \ i[3-9]86) \
echo i586 \ echo i586 \
@ -192,11 +196,13 @@ ifeq ($(SYSTEM_UNAME), Linux)
ARCH=sparcv9 ARCH=sparcv9
endif endif
else else
# i586 is 32-bit, amd64 is 64-bit # Most archs are 32-bit
ifndef ARCH_DATA_MODEL ifndef ARCH_DATA_MODEL
ifeq ($(ARCH), i586) ARCH_DATA_MODEL=32
ARCH_DATA_MODEL=32 ifeq ($(ARCH), amd64)
else ARCH_DATA_MODEL=64
endif
ifeq ($(ARCH), ia64)
ARCH_DATA_MODEL=64 ARCH_DATA_MODEL=64
endif endif
endif endif

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -104,7 +104,11 @@ ifeq ($(PLATFORM),windows)
endif endif
ALL_SETTINGS+=$(call addOptionalSetting,COMPILER_NAME) ALL_SETTINGS+=$(call addOptionalSetting,COMPILER_NAME)
ALL_SETTINGS+=$(call addOptionalSetting,COMPILER_VERSION) ALL_SETTINGS+=$(call addOptionalSetting,COMPILER_VERSION)
ALL_SETTINGS+=$(call addRequiredVersionSetting,CC_VER) ifdef REQUIRED_CC_VER
ALL_SETTINGS+=$(call addRequiredVersionSetting,CC_VER)
else
ALL_SETTINGS+=$(call addOptionalSetting,CC_VER)
endif
ifeq ($(PLATFORM),solaris) ifeq ($(PLATFORM),solaris)
ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(ARCH_DATA_MODEL), 32)
ifndef OPENJDK ifndef OPENJDK

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -220,7 +220,7 @@ include $(JDK_MAKE_SHARED_DIR)/Sanity-Settings.gmk
sane-ant_version \ sane-ant_version \
sane-zip_version \ sane-zip_version \
sane-unzip_version \ sane-unzip_version \
sane-msvcrt_path \ sane-msvcrt_path \
sane-freetype sane-freetype
###################################################### ######################################################
@ -279,6 +279,12 @@ sane-arch_data_model:
" $(YOU_ARE_USING) ARCH_DATA_MODEL=$(ARCH_DATA_MODEL). \n" \ " $(YOU_ARE_USING) ARCH_DATA_MODEL=$(ARCH_DATA_MODEL). \n" \
"" >> $(ERROR_FILE) ; \ "" >> $(ERROR_FILE) ; \
fi fi
ifdef BUILD_CLIENT_ONLY
@if [ "$(ARCH_DATA_MODEL)" != 32 ]; then \
$(ECHO) "WARNING: You have requested BUILD_CLIENT_ONLY in a 64-bit build.\n" \
"" >> $(WARNING_FILE) ; \
fi
endif
###################################################### ######################################################
# Check the OS version (windows and linux have release name checks) # Check the OS version (windows and linux have release name checks)
@ -811,23 +817,26 @@ sane-cacerts:
###################################################### ######################################################
ifdef OPENJDK ifdef OPENJDK
ifndef CROSS_COMPILE_ARCH
# The freetypecheck Makefile prints out "Failed" if not good enough # The freetypecheck Makefile prints out "Failed" if not good enough
$(TEMPDIR)/freetypeinfo: FRC $(TEMPDIR)/freetypeinfo: FRC
@$(prep-target) @$(prep-target)
@(($(CD) $(BUILDDIR)/tools/freetypecheck && $(MAKE)) || \ @(($(CD) $(BUILDDIR)/tools/freetypecheck && $(MAKE)) || \
$(ECHO) "Failed to build freetypecheck." ) > $@ $(ECHO) "Failed to build freetypecheck." ) > $@
sane-freetype: $(TEMPDIR)/freetypeinfo sane-freetype: $(TEMPDIR)/freetypeinfo
@if [ "`$(CAT) $< | $(GREP) Fail`" != "" ]; then \ @if [ "`$(CAT) $< | $(GREP) Fail`" != "" ]; then \
$(ECHO) "ERROR: FreeType version " $(REQUIRED_FREETYPE_VERSION) \ $(ECHO) "ERROR: FreeType version " $(REQUIRED_FREETYPE_VERSION) \
" or higher is required. \n" \ " or higher is required. \n" \
"`$(CAT) $<` \n" >> $(ERROR_FILE) ; \ "`$(CAT) $<` \n" >> $(ERROR_FILE) ; \
fi fi
else
#do nothing (cross-compiling)
sane-freetype:
endif
else else
#do nothing (not OpenJDK) #do nothing (not OpenJDK)
sane-freetype: sane-freetype:
endif endif
###################################################### ######################################################
@ -1296,7 +1305,7 @@ ifeq ($(PLATFORM), windows)
" Microsoft DirectX 9 SDK can be downloaded from the following location:\n" \ " Microsoft DirectX 9 SDK can be downloaded from the following location:\n" \
" http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \ " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \
" Or http://www.microsoft.com/directx\n" \ " Or http://www.microsoft.com/directx\n" \
"" >> $(WARNING_FILE) ; \ "" >> $(WARNING_FILE) ; \
fi \ fi \
fi \ fi \
fi \ fi \
@ -1327,13 +1336,16 @@ endif
###################################################### ######################################################
# Check the compiler version(s) # Check the compiler version(s)
###################################################### ######################################################
CC_CHECK :=$(call CheckVersions,$(CC_VER),$(REQUIRED_CC_VER)) ifdef REQUIRED_CC_VER
CC_CHECK :=$(call CheckVersions,$(CC_VER),$(REQUIRED_CC_VER))
endif
sane-compiler: sane-link sane-compiler: sane-link
ifdef REQUIRED_CC_VER
@if [ "$(CC_CHECK)" = "missing" ]; then \ @if [ "$(CC_CHECK)" = "missing" ]; then \
$(ECHO) "ERROR: The Compiler version is undefined. \n" \ $(ECHO) "ERROR: The Compiler version is undefined. \n" \
"" >> $(ERROR_FILE) ; \ "" >> $(ERROR_FILE) ; \
fi fi
ifndef OPENJDK ifndef OPENJDK
@if [ "$(CC_CHECK)" != "same" ]; then \ @if [ "$(CC_CHECK)" != "same" ]; then \
$(ECHO) "WARNING: The $(PLATFORM) compiler is not version $(REQUIRED_COMPILER_VERSION) $(REQUIRED_CC_VER) \n" \ $(ECHO) "WARNING: The $(PLATFORM) compiler is not version $(REQUIRED_COMPILER_VERSION) $(REQUIRED_CC_VER) \n" \
" Specifically the $(REQUIRED_COMPILER_NAME) compiler. \n " \ " Specifically the $(REQUIRED_COMPILER_NAME) compiler. \n " \
@ -1342,6 +1354,7 @@ ifndef OPENJDK
" $(COMPILER_PATH) \n" \ " $(COMPILER_PATH) \n" \
"" >> $(WARNING_FILE) ; \ "" >> $(WARNING_FILE) ; \
fi fi
endif
endif endif
###################################################### ######################################################

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -55,7 +55,7 @@ EXCLUDE_PKGS = \
# This is a list of regular expressions. So foo.* matches "foo" and "foo.bar". # This is a list of regular expressions. So foo.* matches "foo" and "foo.bar".
# #
ACTIVE_JSR_PKGS= \ ACTIVE_JSR_PKGS= \
java.dyn \ java.lang.invoke \
java.sql \ java.sql \
javax.activation \ javax.activation \
javax.annotation.* \ javax.annotation.* \
@ -97,11 +97,11 @@ CORE_PKGS = \
java.awt.print \ java.awt.print \
java.beans \ java.beans \
java.beans.beancontext \ java.beans.beancontext \
java.dyn \
java.io \ java.io \
java.lang \ java.lang \
java.lang.annotation \ java.lang.annotation \
java.lang.instrument \ java.lang.instrument \
java.lang.invoke \
java.lang.management \ java.lang.management \
java.lang.ref \ java.lang.ref \
java.lang.reflect \ java.lang.reflect \

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -44,7 +44,7 @@ SUBDIRS += security math util text net nio jar
SUBDIRS_desktop = awt applet beans SUBDIRS_desktop = awt applet beans
SUBDIRS_management = management SUBDIRS_management = management
SUBDIRS_misc = npt java_crw_demo java_hprof_demo \ SUBDIRS_misc = npt java_crw_demo java_hprof_demo \
logging instrument dyn sql rmi logging instrument invoke sql rmi
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -109,7 +109,7 @@ else
LDFLAGS += -R \$$ORIGIN/jli LDFLAGS += -R \$$ORIGIN/jli
endif endif
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
LDFLAGS += -Wl,-z -Wl,origin LDFLAGS += $(LDFLAG_Z_ORIGIN)
LDFLAGS += -Wl,--allow-shlib-undefined LDFLAGS += -Wl,--allow-shlib-undefined
LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli
endif endif

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -25,18 +25,18 @@
BUILDDIR = ../.. BUILDDIR = ../..
PACKAGE = java.dyn PACKAGE = java.lang.invoke
PRODUCT = java PRODUCT = java
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
AUTO_FILES_JAVA_DIRS = java/dyn sun/dyn AUTO_FILES_JAVA_DIRS = java/lang/invoke sun/invoke
FILES_java = \
java/lang/ClassValue.java \
java/lang/BootstrapMethodError.java
# The sources built here use new language syntax to generate # The sources built here use new language syntax to generate
# method handle calls. Let's be sure we are using that format. # method handle calls. Let's be sure we are using that format.
LANGUAGE_VERSION = -source 7 LANGUAGE_VERSION = -source 7
CLASS_VERSION = -target 7 CLASS_VERSION = -target 7
# Tell the compiler not to accept transitional forms.
OTHER_JAVACFLAGS = -XDallowTransitionalJSR292=no
include $(BUILDDIR)/common/Classes.gmk include $(BUILDDIR)/common/Classes.gmk

View File

@ -78,13 +78,17 @@ FILES_c = \
zutil.c zutil.c
ifneq ($(PLATFORM), windows) ifneq ($(PLATFORM), windows)
FILES_c += ergo.c
FILES_c += \ ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c
$(CTARGDIR)ergo.c \ # if the architecture specific ergo file exists then
$(CTARGDIR)ergo_$(ERGO_FAMILY).c # use it, else use the generic definitions from ergo.c
ifneq ($(wildcard $(LAUNCHER_PLATFORM_SRC)/$(ERGO_ARCH_FILE)),)
FILES_c += $(ERGO_ARCH_FILE)
else
OTHER_CPPFLAGS += -DUSE_GENERIC_ERGO
endif
endif endif
# Names of arch directories # Names of arch directories
LIBARCH_DEFINES = -DLIBARCHNAME='"$(LIBARCH)"' LIBARCH_DEFINES = -DLIBARCHNAME='"$(LIBARCH)"'
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -43,7 +43,8 @@ $(INCLUDEDIR)/%.h: $(SHARE_SRC)/javavm/export/%.h
$(PLATFORM_INCLUDE)/%.h: $(PLATFORM_SRC)/javavm/export/%.h $(PLATFORM_INCLUDE)/%.h: $(PLATFORM_SRC)/javavm/export/%.h
$(install-file) $(install-file)
JVMCFG = $(LIBDIR)/$(LIBARCH)/jvm.cfg JVMCFG_DIR = $(LIBDIR)/$(LIBARCH)
JVMCFG = $(JVMCFG_DIR)/jvm.cfg
# #
# How to install jvm.cfg. # How to install jvm.cfg.
@ -54,8 +55,21 @@ else
JVMCFG_ARCH = $(ARCH) JVMCFG_ARCH = $(ARCH)
endif endif
ifdef BUILD_CLIENT_ONLY
$(JVMCFG)::
$(MKDIR) -p $(JVMCFG_DIR)
@# Update jvm.cfg to use -client by default and alias -server to -client
$(RM) -f $(JVMCFG)
$(ECHO) "-client KNOWN">$(JVMCFG)
$(ECHO) "-server ALIASED_TO -client">>$(JVMCFG)
$(ECHO) "-hotspot ALIASED_TO -client">>$(JVMCFG)
$(ECHO) "-classic WARN">>$(JVMCFG)
$(ECHO) "-native ERROR">>$(JVMCFG)
$(ECHO) "-green ERROR">>$(JVMCFG)
else
$(JVMCFG): $(PLATFORM_SRC)/bin/$(JVMCFG_ARCH)/jvm.cfg $(JVMCFG): $(PLATFORM_SRC)/bin/$(JVMCFG_ARCH)/jvm.cfg
$(install-file) $(install-file)
endif
all: build all: build

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -820,7 +820,7 @@ $(TEMPDIR)/$(GENSOR_SRC) : $(GENSOR_SRC)
$(GENSOR_EXE) : $(TEMPDIR)/$(GENSOR_SRC) $(GENSOR_EXE) : $(TEMPDIR)/$(GENSOR_SRC)
$(prep-target) $(prep-target)
($(CD) $(TEMPDIR); $(CC) $(CPPFLAGS) $(LDDFLAGS) \ ($(CD) $(TEMPDIR); $(HOST_CC) $(CPPFLAGS) $(LDDFLAGS) \
-o genSocketOptionRegistry$(EXE_SUFFIX) $(GENSOR_SRC)) -o genSocketOptionRegistry$(EXE_SUFFIX) $(GENSOR_SRC))
$(SCH_GEN)/SocketOptionRegistry.java: $(GENSOR_EXE) $(SCH_GEN)/SocketOptionRegistry.java: $(GENSOR_EXE)
@ -851,7 +851,7 @@ GENUC_COPYRIGHT_YEARS = $(shell $(CAT) $(GENUC_SRC) | \
$(GENUC_EXE) : $(GENUC_SRC) $(GENUC_EXE) : $(GENUC_SRC)
$(prep-target) $(prep-target)
$(CC) $(CPPFLAGS) -o $@ $(GENUC_SRC) $(HOST_CC) $(CPPFLAGS) -o $@ $(GENUC_SRC)
$(SFS_GEN)/UnixConstants.java: $(GENUC_EXE) $(SFS_GEN)/UnixConstants.java: $(GENUC_EXE)
$(prep-target) $(prep-target)
@ -867,7 +867,7 @@ GENSC_COPYRIGHT_YEARS = $(shell $(CAT) $(GENSC_SRC) | \
$(GENSC_EXE) : $(GENSC_SRC) $(GENSC_EXE) : $(GENSC_SRC)
$(prep-target) $(prep-target)
$(CC) $(CPPFLAGS) -o $@ $(GENSC_SRC) $(HOST_CC) $(CPPFLAGS) -o $@ $(GENSC_SRC)
$(SFS_GEN)/SolarisConstants.java: $(GENSC_EXE) $(SFS_GEN)/SolarisConstants.java: $(GENSC_EXE)
$(prep-target) $(prep-target)

View File

@ -95,6 +95,8 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_NativeThread_current; Java_sun_nio_ch_NativeThread_current;
Java_sun_nio_ch_NativeThread_init; Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal; Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0;
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0;
Java_sun_nio_ch_Net_socket0; Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_bind0; Java_sun_nio_ch_Net_bind0;
Java_sun_nio_ch_Net_connect0; Java_sun_nio_ch_Net_connect0;

View File

@ -82,6 +82,8 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_NativeThread_current; Java_sun_nio_ch_NativeThread_current;
Java_sun_nio_ch_NativeThread_init; Java_sun_nio_ch_NativeThread_init;
Java_sun_nio_ch_NativeThread_signal; Java_sun_nio_ch_NativeThread_signal;
Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0;
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0;
Java_sun_nio_ch_Net_socket0; Java_sun_nio_ch_Net_socket0;
Java_sun_nio_ch_Net_bind0; Java_sun_nio_ch_Net_bind0;
Java_sun_nio_ch_Net_connect0; Java_sun_nio_ch_Net_connect0;

View File

@ -76,8 +76,12 @@ all:: build
INTERNAL_IMPORT_LIST = $(LIBDIR)/classlist INTERNAL_IMPORT_LIST = $(LIBDIR)/classlist
# List of files coming from outside this workspace # List of files coming from outside this workspace
IMPORT_LIST = $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVM_NAME) \ ifndef BUILD_CLIENT_ONLY
$(LIB_LOCATION)/$(SERVER_LOCATION)/Xusage.txt IMPORT_LIST = $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVM_NAME) \
$(LIB_LOCATION)/$(SERVER_LOCATION)/Xusage.txt
else
IMPORT_LIST =
endif
# Hotspot client is only available on 32-bit non-Zero builds # Hotspot client is only available on 32-bit non-Zero builds
ifneq ($(ZERO_BUILD), true) ifneq ($(ZERO_BUILD), true)
@ -97,10 +101,12 @@ $(BINDIR)/$(MSVCRNN_DLL): $(MSVCRNN_DLL_PATH)/$(MSVCRNN_DLL)
$(call chmod-file, a+x) $(call chmod-file, a+x)
# Get the hotspot .map and .pdb files for client and server # Get the hotspot .map and .pdb files for client and server
ifndef BUILD_CLIENT_ONLY
IMPORT_LIST += \ IMPORT_LIST += \
$(LIBDIR)/$(JVMLIB_NAME) \ $(LIBDIR)/$(JVMLIB_NAME) \
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME) \ $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME) \
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME) $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME)
endif
# Add .map and .pdb files to the import path for client and kernel VMs. # Add .map and .pdb files to the import path for client and kernel VMs.
# These are only available on 32-bit windows builds. # These are only available on 32-bit windows builds.
@ -126,9 +132,11 @@ $(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVMMAP_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_KERNEL_PATH)/$(JVMMAP_NAME) $@ -$(CP) $(HOTSPOT_KERNEL_PATH)/$(JVMMAP_NAME) $@
ifndef BUILD_CLIENT_ONLY
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME): $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMMAP_NAME) $@ -$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMMAP_NAME) $@
endif
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMPDB_NAME): $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMPDB_NAME):
@$(prep-target) @$(prep-target)
@ -138,27 +146,32 @@ $(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVMPDB_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_KERNEL_PATH)/$(JVMPDB_NAME) $@ -$(CP) $(HOTSPOT_KERNEL_PATH)/$(JVMPDB_NAME) $@
ifndef BUILD_CLIENT_ONLY
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME): $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMPDB_NAME) $@ -$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMPDB_NAME) $@
endif
# Windows ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Windows # Windows ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Windows
else # PLATFORM else # PLATFORM
# NOT Windows vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv NOT Windows # NOT Windows vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv NOT Windows
IMPORT_LIST += \ IMPORT_LIST += $(LIB_LOCATION)/$(LIBJSIG_NAME)
$(LIB_LOCATION)/$(LIBJSIG_NAME) \ ifndef BUILD_CLIENT_ONLY
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(LIBJSIG_NAME) IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/$(LIBJSIG_NAME)
endif
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME) ifndef BUILD_CLIENT_ONLY
# The conditional can be removed when import JDKs contain these files. IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME)
ifneq ($(wildcard $(HOTSPOT_SERVER_PATH)/$(JVMDTRACE_NAME)),) # The conditional can be removed when import JDKs contain these files.
IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDTRACE_NAME) ifneq ($(wildcard $(HOTSPOT_SERVER_PATH)/$(JVMDTRACE_NAME)),)
else IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDTRACE_NAME)
$(warning WARNING: $(HOTSPOT_SERVER_PATH)/$(JVMDB_NAME) not found!) else
endif $(warning WARNING: $(HOTSPOT_SERVER_PATH)/$(JVMDB_NAME) not found!)
endif endif
endif
endif
ifneq ($(ZERO_BUILD), true) ifneq ($(ZERO_BUILD), true)
ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(ARCH_DATA_MODEL), 32)
@ -179,18 +192,20 @@ else
$(warning WARNING: $(HOTSPOT_CLIENT_PATH)/$(JVMDTRACE_NAME) not found!) $(warning WARNING: $(HOTSPOT_CLIENT_PATH)/$(JVMDTRACE_NAME) not found!)
endif endif
# The conditional can be removed when import JDKs contain these files. ifndef BUILD_CLIENT_ONLY
ifneq ($(wildcard $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_NAME)),) # The conditional can be removed when import JDKs contain these files.
IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDB_NAME) ifneq ($(wildcard $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_NAME)),)
else IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDB_NAME)
$(warning WARNING: $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_NAME) not found!) else
endif $(warning WARNING: $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_NAME) not found!)
endif
# The conditional can be removed when import JDKs contain these files. # The conditional can be removed when import JDKs contain these files.
ifneq ($(wildcard $(HOTSPOT_SERVER_PATH)/64/$(JVMDTRACE_NAME)),) ifneq ($(wildcard $(HOTSPOT_SERVER_PATH)/64/$(JVMDTRACE_NAME)),)
IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDTRACE_NAME) IMPORT_LIST += $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDTRACE_NAME)
else else
$(warning WARNING: $(HOTSPOT_SERVER_PATH)/64/$(JVMDTRACE_NAME) not found!) $(warning WARNING: $(HOTSPOT_SERVER_PATH)/64/$(JVMDTRACE_NAME) not found!)
endif
endif endif
# For backwards compatability, make a link of the 32-bit client JVM to $(LIBDIR) # For backwards compatability, make a link of the 32-bit client JVM to $(LIBDIR)
@ -222,10 +237,16 @@ $(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_IMPORT_PATH)/$(ARCH_VM_SUBDIR)/$(LIBJ
$(install-import-file) $(install-import-file)
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)
ifndef BUILD_CLIENT_ONLY
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME) \ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME) \
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(LIBJSIG_NAME): $(LIB_LOCATION)/$(SERVER_LOCATION)/$(LIBJSIG_NAME):
@$(prep-target) @$(prep-target)
$(call install-sym-link, ../$(LIBJSIG_NAME)) $(call install-sym-link, ../$(LIBJSIG_NAME))
else
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME):
@$(prep-target)
$(call install-sym-link, ../$(LIBJSIG_NAME))
endif
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDB_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDB_NAME) $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDB_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDB_NAME)
$(install-import-file) $(install-import-file)
@ -235,6 +256,7 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDB_NAME): $(HOTSPOT_CLIENT_PATH)/64/$
$(install-import-file) $(install-import-file)
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)
ifndef BUILD_CLIENT_ONLY
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDB_NAME) $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDB_NAME)
$(install-import-file) $(install-import-file)
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)
@ -242,6 +264,7 @@ $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDB_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDB
$(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDB_NAME): $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_NAME) $(LIB_LOCATION)/$(SERVER_LOCATION)/64/$(JVMDB_NAME): $(HOTSPOT_SERVER_PATH)/64/$(JVMDB_NAME)
$(install-import-file) $(install-import-file)
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)
endif
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDTRACE_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDTRACE_NAME) $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMDTRACE_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVMDTRACE_NAME)
$(install-import-file) $(install-import-file)
@ -251,6 +274,7 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/64/$(JVMDTRACE_NAME): $(HOTSPOT_CLIENT_PATH)/
$(install-import-file) $(install-import-file)
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)
ifndef BUILD_CLIENT_ONLY
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDTRACE_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDTRACE_NAME) $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMDTRACE_NAME): $(HOTSPOT_SERVER_PATH)/$(JVMDTRACE_NAME)
$(install-import-file) $(install-import-file)
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)
@ -265,6 +289,7 @@ $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVM_NAME): $(HOTSPOT_SERVER_PATH)/$(JVM_NAM
$(LIB_LOCATION)/$(SERVER_LOCATION)/Xusage.txt : $(HOTSPOT_SERVER_PATH)/Xusage.txt $(LIB_LOCATION)/$(SERVER_LOCATION)/Xusage.txt : $(HOTSPOT_SERVER_PATH)/Xusage.txt
$(install-import-file) $(install-import-file)
endif
$(LIB_LOCATION)/$(CLIENT_LOCATION)/Xusage.txt : $(HOTSPOT_CLIENT_PATH)/Xusage.txt $(LIB_LOCATION)/$(CLIENT_LOCATION)/Xusage.txt : $(HOTSPOT_CLIENT_PATH)/Xusage.txt
$(install-import-file) $(install-import-file)

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -73,6 +73,15 @@ else
ifeq ($(ARCH), amd64) ifeq ($(ARCH), amd64)
CPPFLAGS += -DX_ARCH=X_AMD64 CPPFLAGS += -DX_ARCH=X_AMD64
endif # ARCH amd64 endif # ARCH amd64
ifeq ($(ARCH), arm)
CPPFLAGS += -DX_ARCH=X_ARM
endif # ARCH arm
ifeq ($(ARCH), ppc)
CPPFLAGS += -DX_ARCH=X_PPC
endif # ARCH ppc
endif endif

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -24,21 +24,20 @@
# #
# #
# Makefile for building packages under javax.xml # Makefile to build the Laffy demo.
# #
BUILDDIR = ../../.. BUILDDIR = ../../..
PACKAGE = com.sun.xml PRODUCT = demo/jfc
PRODUCT = xml DEMONAME = Laffy
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# DEMO_ROOT = $(CLOSED_SRC)/share/demo/jfc/$(DEMONAME)
# Files to compile DEMO_DESTDIR = $(DEMODIR)/jfc/$(DEMONAME)
# DEMO_TOPFILES = ./readme.html ./laffy.png
AUTO_FILES_JAVA_DIRS = com/sun/activation \ DEMO_SKIP_SRCZIP = true
org/relaxng/datatype
# #
# Rules # Demo jar building rules.
# #
include $(BUILDDIR)/common/Classes.gmk include $(BUILDDIR)/common/Demo.gmk

View File

@ -43,7 +43,7 @@ SUBDIRS = \
# Some demos aren't currently included in OpenJDK # Some demos aren't currently included in OpenJDK
ifndef OPENJDK ifndef OPENJDK
SUBDIRS += Java2D SwingSet2 SwingSet3 Stylepad SUBDIRS += Java2D Laffy SwingSet2 SwingSet3 Stylepad
endif endif
include $(BUILDDIR)/common/Subdirs.gmk include $(BUILDDIR)/common/Subdirs.gmk

View File

@ -71,7 +71,8 @@ $(SERVICEDIR)/%: $(CLOSED_SRC)/share/classes/sun/java2d/cmm/kcms/META-INF/servic
# Extra rules # Extra rules
# #
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
LDLIBS += -lpthread LDLIBS += -lpthread
OTHER_CFLAGS += -Wno-missing-field-initializers
endif endif
clean clobber:: clean clobber::
@ -103,6 +104,5 @@ CPPFLAGS += -I$(CLASSHDRDIR) \
endif # PLATFORM endif # PLATFORM
#CFLAGS += -DJAVACMM -DFUT_CALC_EX -DNO_FUT_GCONST CFLAGS += -DJAVACMM -DFUT_CALC_EX -DNO_FUT_GCONST
CFLAGS += -DFUT_CALC_EX -DNO_FUT_GCONST

View File

@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any # or visit www.oracle.com if you need additional information or have any
# questions. # questions.
# #
tzdata2011b tzdata2011d

View File

@ -531,11 +531,31 @@ Zone Pacific/Pago_Pago 12:37:12 - LMT 1879 Jul 5
# to 01:00am and First Sunday April 2011 (03/04/11) - adjust clocks # to 01:00am and First Sunday April 2011 (03/04/11) - adjust clocks
# backwards from 1:00am to 12:00am" # backwards from 1:00am to 12:00am"
# From Raymond Hughes (2011-03-07)
# I believe this will be posted shortly on the website
# <a href="http://www.mcil.gov.ws">
# www.mcil.gov.ws
# </a>
#
# PUBLIC NOTICE ON DAYLIGHT SAVING TIME
#
# Pursuant to the Daylight Saving Act 2009 and Cabinets decision,
# businesses and the general public are hereby advised that daylight
# saving time is on the first Saturday of April 2011 (02/04/11).
#
# The public is therefore advised that when the standard time strikes
# the hour of four oclock (4.00am or 0400 Hours) on the 2nd April 2011,
# then all instruments used to measure standard time are to be
# adjusted/changed to three oclock (3:00am or 0300Hrs).
#
# Margaret Fruean ACTING CHIEF EXECUTIVE OFFICER MINISTRY OF COMMERCE,
# INDUSTRY AND LABOUR 28th February 2011
Zone Pacific/Apia 12:33:04 - LMT 1879 Jul 5 Zone Pacific/Apia 12:33:04 - LMT 1879 Jul 5
-11:26:56 - LMT 1911 -11:26:56 - LMT 1911
-11:30 - SAMT 1950 # Samoa Time -11:30 - SAMT 1950 # Samoa Time
-11:00 - WST 2010 Sep 26 -11:00 - WST 2010 Sep 26
-11:00 1:00 WSDT 2011 Apr 3 1:00 -11:00 1:00 WSDT 2011 Apr 2 4:00
-11:00 - WST -11:00 - WST
# Solomon Is # Solomon Is

View File

@ -58,8 +58,7 @@ Link Etc/GMT Etc/GMT0
# (i.e. west of Greenwich) even though many people would expect it to # (i.e. west of Greenwich) even though many people would expect it to
# mean 4 hours ahead of UTC (i.e. east of Greenwich). # mean 4 hours ahead of UTC (i.e. east of Greenwich).
# #
# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation # In the draft 5 of POSIX 1003.1-200x, the angle bracket notation allows for
# (which is not yet supported by the tz code) allows for
# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to # TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
# ISO 8601 you can use TZ='<-0400>+4'. Thus the commonly-expected # ISO 8601 you can use TZ='<-0400>+4'. Thus the commonly-expected
# offset is kept within the angle bracket (and is used for display) # offset is kept within the angle bracket (and is used for display)

View File

@ -2505,25 +2505,18 @@ Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12
# (on a non-government server though) describing dates between 2002 and 2006: # (on a non-government server though) describing dates between 2002 and 2006:
# http://www.alomaliye.com/bkk_2002_3769.htm # http://www.alomaliye.com/bkk_2002_3769.htm
# From Sue Williams (2008-08-11): # From G&ouml;kdeniz Karada&#x011f; (2011-03-10):
# I spotted this news article about a potential change in Turkey. #
# # According to the articles linked below, Turkey will change into summer
# <a href="http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1"> # time zone (GMT+3) on March 28, 2011 at 3:00 a.m. instead of March 27.
# http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1 # This change is due to a nationwide exam on 27th.
#
# <a href="http://www.worldbulletin.net/?aType=haber&ArticleID=70872">
# http://www.worldbulletin.net/?aType=haber&ArticleID=70872
# </a> # </a>
# Turkish:
# From Sue Williams (2008-08-20): # <a href="http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373">
# This article says that around the end of March 2011, Turkey wants to # http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373
# adjust the clocks forward by 1/2 hour and stay that way permanently.
# The article indicates that this is a change in timezone offset in addition
# to stopping observance of DST.
# This proposal has not yet been approved.
#
# Read more here...
#
# Turkey to abandon daylight saving time in 2011
# <a href="http://www.turkishdailynews.com.tr/article.php?enewsid=112989">
# http://www.turkishdailynews.com.tr/article.php?enewsid=112989
# </a> # </a>
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
@ -2591,6 +2584,8 @@ Zone Europe/Istanbul 1:55:52 - LMT 1880
2:00 Turkey EE%sT 1978 Oct 15 2:00 Turkey EE%sT 1978 Oct 15
3:00 Turkey TR%sT 1985 Apr 20 # Turkey Time 3:00 Turkey TR%sT 1985 Apr 20 # Turkey Time
2:00 Turkey EE%sT 2007 2:00 Turkey EE%sT 2007
2:00 EU EE%sT 2011 Mar 27 1:00u
2:00 - EET 2011 Mar 28 1:00u
2:00 EU EE%sT 2:00 EU EE%sT
Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.

View File

@ -78,13 +78,13 @@ Leap 2008 Dec 31 23:59:60 + S
# SERVICE DE LA ROTATION TERRESTRE # SERVICE DE LA ROTATION TERRESTRE
# OBSERVATOIRE DE PARIS # OBSERVATOIRE DE PARIS
# 61, Av. de l'Observatoire 75014 PARIS (France) # 61, Av. de l'Observatoire 75014 PARIS (France)
# Tel. : 33 (0) 1 40 51 22 26 # Tel. : 33 (0) 1 40 51 22 29
# FAX : 33 (0) 1 40 51 22 91 # FAX : 33 (0) 1 40 51 22 91
# Internet : services.iers@obspm.fr # Internet : services.iers@obspm.fr
# #
# Paris, 14 July 2010 # Paris, 2 February 2011
# #
# Bulletin C 40 # Bulletin C 41
# #
# To authorities responsible # To authorities responsible
# for the measurement and # for the measurement and
@ -92,9 +92,9 @@ Leap 2008 Dec 31 23:59:60 + S
# #
# INFORMATION ON UTC - TAI # INFORMATION ON UTC - TAI
# #
# NO positive leap second will be introduced at the end of December 2010. # NO positive leap second will be introduced at the end of June 2011.
# The difference between Coordinated Universal Time UTC and the # The difference between Coordinated Universal Time UTC and the
# International Atomic Time TAI is : # International Atomic Time TAI is :
# #
# from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s # from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s
# #
@ -104,6 +104,6 @@ Leap 2008 Dec 31 23:59:60 + S
# will be no time step at the next possible date. # will be no time step at the next possible date.
# #
# Daniel GAMBIS # Daniel GAMBIS
# Director # Head
# Earth Orientation Center of IERS # Earth Orientation Center of the IERS
# Observatoire de Paris, France # Observatoire de Paris, France

View File

@ -448,15 +448,74 @@ Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02
# were nearby inhabitants in some cases and for our purposes perhaps # were nearby inhabitants in some cases and for our purposes perhaps
# it's best to simply use the official transition. # it's best to simply use the official transition.
# #
# From Steve Ferguson (2011-01-31):
# The author lives in Alaska and many of the references listed are only
# available to Alaskan residents.
#
# <a href="http://www.alaskahistoricalsociety.org/index.cfm?section=discover%20alaska&page=Glimpses%20of%20the%20Past&viewpost=2&ContentId=98">
# http://www.alaskahistoricalsociety.org/index.cfm?section=discover%20alaska&page=Glimpses%20of%20the%20Past&viewpost=2&ContentId=98
# </a>
# From Arthur David Olson (2011-02-01):
# Here's database-relevant material from the 2001 "Alaska History" article:
#
# On September 20 [1979]...DOT...officials decreed that on April 27,
# 1980, Juneau and other nearby communities would move to Yukon Time.
# Sitka, Petersburg, Wrangell, and Ketchikan, however, would remain on
# Pacific Time.
#
# ...on September 22, 1980, DOT Secretary Neil E. Goldschmidt rescinded the
# Department's September 1979 decision. Juneau and other communities in
# northern Southeast reverted to Pacific Time on October 26.
#
# On October 28 [1983]...the Metlakatla Indian Community Council voted
# unanimously to keep the reservation on Pacific Time.
#
# According to DOT official Joanne Petrie, Indian reservations are not
# bound to follow time zones imposed by neighboring jurisdictions.
#
# (The last is consistent with how the database now handles the Navajo
# Nation.)
# From Arthur David Olson (2011-02-09):
# I just spoke by phone with a staff member at the Metlakatla Indian
# Community office (using contact information available at
# <a href="http://www.commerce.state.ak.us/dca/commdb/CIS.cfm?Comm_Boro_name=Metlakatla">
# http://www.commerce.state.ak.us/dca/commdb/CIS.cfm?Comm_Boro_name=Metlakatla
# </a>).
# It's shortly after 1:00 here on the east coast of the United States;
# the staffer said it was shortly after 10:00 there. When I asked whether
# that meant they were on Pacific time, they said no--they were on their
# own time. I asked about daylight saving; they said it wasn't used. I
# did not inquire about practices in the past.
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Juneau 15:02:19 - LMT 1867 Oct 18 Zone America/Juneau 15:02:19 - LMT 1867 Oct 18
-8:57:41 - LMT 1900 Aug 20 12:00 -8:57:41 - LMT 1900 Aug 20 12:00
-8:00 - PST 1942 -8:00 - PST 1942
-8:00 US P%sT 1946 -8:00 US P%sT 1946
-8:00 - PST 1969 -8:00 - PST 1969
-8:00 US P%sT 1980 Apr 27 2:00
-9:00 US Y%sT 1980 Oct 26 2:00
-8:00 US P%sT 1983 Oct 30 2:00 -8:00 US P%sT 1983 Oct 30 2:00
-9:00 US Y%sT 1983 Nov 30 -9:00 US Y%sT 1983 Nov 30
-9:00 US AK%sT -9:00 US AK%sT
Zone America/Sitka -14:58:47 - LMT 1867 Oct 18
-9:01:13 - LMT 1900 Aug 20 12:00
-8:00 - PST 1942
-8:00 US P%sT 1946
-8:00 - PST 1969
-8:00 US P%sT 1983 Oct 30 2:00
-9:00 US Y%sT 1983 Nov 30
-9:00 US AK%sT
Zone America/Metlakatla 15:13:42 - LMT 1867 Oct 18
-8:46:18 - LMT 1900 Aug 20 12:00
-8:00 - PST 1942
-8:00 US P%sT 1946
-8:00 - PST 1969
-8:00 US P%sT 1983 Oct 30 2:00
-8:00 US MeST
Zone America/Yakutat 14:41:05 - LMT 1867 Oct 18 Zone America/Yakutat 14:41:05 - LMT 1867 Oct 18
-9:18:55 - LMT 1900 Aug 20 12:00 -9:18:55 - LMT 1900 Aug 20 12:00
-9:00 - YST 1942 -9:00 - YST 1942
@ -2569,6 +2628,21 @@ Zone America/Costa_Rica -5:36:20 - LMT 1890 # San Jose
# the time was announced as "diez cinco"--the same time as here, indicating # the time was announced as "diez cinco"--the same time as here, indicating
# that has indeed switched to DST. Assume second Sunday from 2009 forward. # that has indeed switched to DST. Assume second Sunday from 2009 forward.
# From Steffen Thorsen (2011-03-08):
# Granma announced that Cuba is going to start DST on 2011-03-20 00:00:00
# this year. Nothing about the end date known so far (if that has
# changed at all).
#
# Source:
# <a href="http://granma.co.cu/2011/03/08/nacional/artic01.html">
# http://granma.co.cu/2011/03/08/nacional/artic01.html
# </a>
#
# Our info:
# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-2011.html">
# http://www.timeanddate.com/news/time/cuba-starts-dst-2011.html
# </a>
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Cuba 1928 only - Jun 10 0:00 1:00 D Rule Cuba 1928 only - Jun 10 0:00 1:00 D
Rule Cuba 1928 only - Oct 10 0:00 0 S Rule Cuba 1928 only - Oct 10 0:00 0 S
@ -2602,7 +2676,9 @@ Rule Cuba 2000 2004 - Apr Sun>=1 0:00s 1:00 D
Rule Cuba 2006 max - Oct lastSun 0:00s 0 S Rule Cuba 2006 max - Oct lastSun 0:00s 0 S
Rule Cuba 2007 only - Mar Sun>=8 0:00s 1:00 D Rule Cuba 2007 only - Mar Sun>=8 0:00s 1:00 D
Rule Cuba 2008 only - Mar Sun>=15 0:00s 1:00 D Rule Cuba 2008 only - Mar Sun>=15 0:00s 1:00 D
Rule Cuba 2009 max - Mar Sun>=8 0:00s 1:00 D Rule Cuba 2009 2010 - Mar Sun>=8 0:00s 1:00 D
Rule Cuba 2011 only - Mar Sun>=15 0:00s 1:00 D
Rule Cuba 2012 max - Mar Sun>=8 0:00s 1:00 D
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Havana -5:29:28 - LMT 1890 Zone America/Havana -5:29:28 - LMT 1890

View File

@ -1176,6 +1176,23 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# From Arthur Daivd Olson (2010-03-06): # From Arthur Daivd Olson (2010-03-06):
# Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch. # Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch.
# From Glenn Eychaner (2011-03-02): [geychaner@mac.com]
# It appears that the Chilean government has decided to postpone the
# change from summer time to winter time again, by three weeks to April
# 2nd:
# <a href="http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651">
# http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651
# </a>
#
# This is not yet reflected in the offical "cambio de hora" site, but
# probably will be soon:
# <a href="http://www.horaoficial.cl/cambio.htm">
# http://www.horaoficial.cl/cambio.htm
# </a>
# From Arthur David Olson (2011-03-02):
# The emol.com article mentions a water shortage as the cause of the
# postponement, which may mean that it's not a permanent change.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Chile 1927 1932 - Sep 1 0:00 1:00 S Rule Chile 1927 1932 - Sep 1 0:00 1:00 S
Rule Chile 1928 1932 - Apr 1 0:00 0 - Rule Chile 1928 1932 - Apr 1 0:00 0 -
@ -1211,8 +1228,8 @@ Rule Chile 2000 2007 - Mar Sun>=9 3:00u 0 -
# which is used below in specifying the transition. # which is used below in specifying the transition.
Rule Chile 2008 only - Mar 30 3:00u 0 - Rule Chile 2008 only - Mar 30 3:00u 0 -
Rule Chile 2009 only - Mar Sun>=9 3:00u 0 - Rule Chile 2009 only - Mar Sun>=9 3:00u 0 -
Rule Chile 2010 only - Apr 4 3:00u 0 - Rule Chile 2010 2011 - Apr Sun>=1 3:00u 0 -
Rule Chile 2011 max - Mar Sun>=9 3:00u 0 - Rule Chile 2012 max - Mar Sun>=9 3:00u 0 -
# IATA SSIM anomalies: (1992-02) says 1992-03-14; # IATA SSIM anomalies: (1992-02) says 1992-03-14;
# (1996-09) says 1998-03-08. Ignore these. # (1996-09) says 1998-03-08. Ignore these.
# Zone NAME GMTOFF RULES FORMAT [UNTIL] # Zone NAME GMTOFF RULES FORMAT [UNTIL]

View File

@ -434,9 +434,11 @@ US +332654-1120424 America/Phoenix Mountain Standard Time - Arizona
US +340308-1181434 America/Los_Angeles Pacific Time US +340308-1181434 America/Los_Angeles Pacific Time
US +611305-1495401 America/Anchorage Alaska Time US +611305-1495401 America/Anchorage Alaska Time
US +581807-1342511 America/Juneau Alaska Time - Alaska panhandle US +581807-1342511 America/Juneau Alaska Time - Alaska panhandle
US +571035-1351807 America/Sitka Alaska Time - southeast Alaska panhandle
US +593249-1394338 America/Yakutat Alaska Time - Alaska panhandle neck US +593249-1394338 America/Yakutat Alaska Time - Alaska panhandle neck
US +643004-1652423 America/Nome Alaska Time - west Alaska US +643004-1652423 America/Nome Alaska Time - west Alaska
US +515248-1763929 America/Adak Aleutian Islands US +515248-1763929 America/Adak Aleutian Islands
US +550737-1313435 America/Metlakatla Metlakatla Time - Annette Island
US +211825-1575130 Pacific/Honolulu Hawaii US +211825-1575130 Pacific/Honolulu Hawaii
UY -3453-05611 America/Montevideo UY -3453-05611 America/Montevideo
UZ +3940+06648 Asia/Samarkand west Uzbekistan UZ +3940+06648 Asia/Samarkand west Uzbekistan

View File

@ -61,7 +61,7 @@ ifneq ($(PLATFORM), windows)
# ODBC_LIBRARY_LOCATION, and delete the variable assignments below. # ODBC_LIBRARY_LOCATION, and delete the variable assignments below.
# #
# Tell linker to ignore missing externals when building this shared library. # Tell linker to ignore missing externals when building this shared library.
LDFLAGS_DEFS_OPTION = -z nodefs LDFLAGS_DEFS_OPTION = -Xlinker -z -Xlinker nodefs
# Define a place to create the fake libraries and their names. # Define a place to create the fake libraries and their names.
ODBC_LIBRARY_LOCATION = $(TEMPDIR) ODBC_LIBRARY_LOCATION = $(TEMPDIR)
ODBC_FAKE_LIBRARIES = $(ODBC_LIBRARY_LOCATION)/libodbcinst.so $(ODBC_LIBRARY_LOCATION)/libodbc.so ODBC_FAKE_LIBRARIES = $(ODBC_LIBRARY_LOCATION)/libodbcinst.so $(ODBC_LIBRARY_LOCATION)/libodbc.so

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,7 @@ FILES_java = \
sun/net/ProgressListener.java \ sun/net/ProgressListener.java \
sun/net/ProgressMeteringPolicy.java \ sun/net/ProgressMeteringPolicy.java \
sun/net/SocksProxy.java \ sun/net/SocksProxy.java \
sun/net/ResourceManager.java \
sun/net/TelnetInputStream.java \ sun/net/TelnetInputStream.java \
sun/net/TelnetOutputStream.java \ sun/net/TelnetOutputStream.java \
sun/net/TelnetProtocolException.java \ sun/net/TelnetProtocolException.java \
@ -100,6 +101,7 @@ FILES_java = \
sun/net/www/protocol/http/NegotiateAuthentication.java \ sun/net/www/protocol/http/NegotiateAuthentication.java \
sun/net/www/protocol/http/Negotiator.java \ sun/net/www/protocol/http/Negotiator.java \
sun/net/www/protocol/http/ntlm/NTLMAuthentication.java \ sun/net/www/protocol/http/ntlm/NTLMAuthentication.java \
sun/net/www/protocol/http/ntlm/NTLMAuthenticationCallback.java \
sun/net/www/protocol/http/spnego/NegotiatorImpl.java \ sun/net/www/protocol/http/spnego/NegotiatorImpl.java \
sun/net/www/protocol/http/spnego/NegotiateCallbackHandler.java \ sun/net/www/protocol/http/spnego/NegotiateCallbackHandler.java \
sun/net/www/protocol/http/logging/HttpLogFormatter.java \ sun/net/www/protocol/http/logging/HttpLogFormatter.java \

View File

@ -376,6 +376,7 @@ FILES_gen_extcs = \
sun/nio/cs/ext/HKSCSMapping.java \ sun/nio/cs/ext/HKSCSMapping.java \
sun/nio/cs/ext/HKSCS2001Mapping.java \ sun/nio/cs/ext/HKSCS2001Mapping.java \
sun/nio/cs/ext/HKSCS_XPMapping.java \ sun/nio/cs/ext/HKSCS_XPMapping.java \
sun/nio/cs/ext/IBM1364.java \
sun/nio/cs/ext/IBM1381.java \ sun/nio/cs/ext/IBM1381.java \
sun/nio/cs/ext/IBM1383.java \ sun/nio/cs/ext/IBM1383.java \
sun/nio/cs/ext/IBM930.java \ sun/nio/cs/ext/IBM930.java \

View File

@ -0,0 +1,22 @@
#
# Diff of
# b2c: cdctables.zip/Package2.zip/IBM-1364A.zip/055444B0.TPMAP110
# c2b: cdctables.zip/Package2.zip/IBM-1364A.zip/055444B0.UPMAP110
# shows there are 6 additional c->b entries in UPMAP110, they are
# listed below (in b->c form)
#
# UPMAP110 also defines
# <subchar> \xFE\xFE
# and commend out
# #<subchar1> \x3F
# with
#
# <UFFFD> \xFE\xFD # (SUB)
# <UFFFD> \xFE\xFE # (SUB)
#
4148 00AD
4143 00B7
4149 2015
42A1 223C
496F 2299
4954 FF5E

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ MS936 x-mswin-936 MS936 basic sun.nio.cs.ext true 0x81 0xfe 0x
MS949 x-windows-949 MS949 basic sun.nio.cs.ext true 0x81 0xfe 0x41 0xfe MS949 x-windows-949 MS949 basic sun.nio.cs.ext true 0x81 0xfe 0x41 0xfe
MS950 x-windows-950 MS950 basic sun.nio.cs.ext true 0x81 0xfe 0x40 0xfe MS950 x-windows-950 MS950 basic sun.nio.cs.ext true 0x81 0xfe 0x40 0xfe
GBK GBK GBK basic sun.nio.cs.ext true 0x81 0xfe 0x40 0xfe GBK GBK GBK basic sun.nio.cs.ext true 0x81 0xfe 0x40 0xfe
IBM1364 x-IBM1364 Cp1364 ebcdic sun.nio.cs.ext false 0x40 0xde 0x40 0xfe
IBM1381 x-IBM1381 Cp1381 basic sun.nio.cs.ext true 0x8c 0xf7 0xa1 0xfe IBM1381 x-IBM1381 Cp1381 basic sun.nio.cs.ext true 0x8c 0xf7 0xa1 0xfe
IBM1383 x-IBM1383 Cp1383 euc_sim sun.nio.cs.ext true 0xa1 0xfe 0xa1 0xfe IBM1383 x-IBM1383 Cp1383 euc_sim sun.nio.cs.ext true 0xa1 0xfe 0xa1 0xfe
IBM930 x-IBM930 Cp930 ebcdic sun.nio.cs.ext false 0x40 0x7f 0x40 0xfe IBM930 x-IBM930 Cp930 ebcdic sun.nio.cs.ext false 0x40 0x7f 0x40 0xfe

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@
BUILDDIR = .. BUILDDIR = ..
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# Note: freetypecheck is built by Sanity.gmk if needed
SUBDIRS = \ SUBDIRS = \
addjsum \ addjsum \
buildmetaindex \ buildmetaindex \
@ -38,7 +39,6 @@ SUBDIRS = \
compile_properties \ compile_properties \
dir_diff \ dir_diff \
dtdbuilder \ dtdbuilder \
freetypecheck \
generate_break_iterator \ generate_break_iterator \
GenerateCharacter \ GenerateCharacter \
generatecurrencydata \ generatecurrencydata \

View File

@ -61,6 +61,9 @@
* interfaces. * interfaces.
*/ */
/* we always print to stderr */
#define USE_STDERR JNI_TRUE
static jboolean printVersion = JNI_FALSE; /* print and exit */ static jboolean printVersion = JNI_FALSE; /* print and exit */
static jboolean showVersion = JNI_FALSE; /* print but continue */ static jboolean showVersion = JNI_FALSE; /* print but continue */
static jboolean printUsage = JNI_FALSE; /* print and exit*/ static jboolean printUsage = JNI_FALSE; /* print and exit*/
@ -1136,36 +1139,18 @@ InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
return; \ return; \
} }
static jstring platformEncoding = NULL; static jclass helperClass = NULL;
static jstring getPlatformEncoding(JNIEnv *env) {
if (platformEncoding == NULL) { static jclass
jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding"); GetLauncherHelperClass(JNIEnv *env) {
if (propname) { if (helperClass == NULL) {
jclass cls; NULL_CHECK0(helperClass = FindBootStrapClass(env,
jmethodID mid; "sun/launcher/LauncherHelper"));
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"getProperty",
"(Ljava/lang/String;)Ljava/lang/String;"));
platformEncoding = (*env)->CallStaticObjectMethod (
env, cls, mid, propname);
}
} }
return platformEncoding; return helperClass;
}
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
jclass cls;
jmethodID mid;
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"isSupported",
"(Ljava/lang/String;)Z"));
return (*env)->CallStaticBooleanMethod(env, cls, mid, enc);
} }
static jmethodID makePlatformStringMID = NULL;
/* /*
* Returns a new Java string object for the specified platform string. * Returns a new Java string object for the specified platform string.
*/ */
@ -1173,36 +1158,23 @@ static jstring
NewPlatformString(JNIEnv *env, char *s) NewPlatformString(JNIEnv *env, char *s)
{ {
int len = (int)JLI_StrLen(s); int len = (int)JLI_StrLen(s);
jclass cls;
jmethodID mid;
jbyteArray ary; jbyteArray ary;
jstring enc; jclass cls = GetLauncherHelperClass(env);
NULL_CHECK0(cls);
if (s == NULL) if (s == NULL)
return 0; return 0;
enc = getPlatformEncoding(env);
ary = (*env)->NewByteArray(env, len); ary = (*env)->NewByteArray(env, len);
if (ary != 0) { if (ary != 0) {
jstring str = 0; jstring str = 0;
(*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s); (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
if (!(*env)->ExceptionOccurred(env)) { if (!(*env)->ExceptionOccurred(env)) {
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String")); if (makePlatformStringMID == NULL) {
if (isEncodingSupported(env, enc) == JNI_TRUE) { NULL_CHECK0(makePlatformStringMID = (*env)->GetStaticMethodID(env,
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", cls, "makePlatformString", "(Z[B)Ljava/lang/String;"));
"([BLjava/lang/String;)V"));
str = (*env)->NewObject(env, cls, mid, ary, enc);
} else {
/*If the encoding specified in sun.jnu.encoding is not
endorsed by "Charset.isSupported" we have to fall back
to use String(byte[]) explicitly here without specifying
the encoding name, in which the StringCoding class will
pickup the iso-8859-1 as the fallback converter for us.
*/
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([B)V"));
str = (*env)->NewObject(env, cls, mid, ary);
} }
str = (*env)->CallStaticObjectMethod(env, cls,
makePlatformStringMID, USE_STDERR, ary);
(*env)->DeleteLocalRef(env, ary); (*env)->DeleteLocalRef(env, ary);
return str; return str;
} }
@ -1239,20 +1211,28 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
static jclass static jclass
LoadMainClass(JNIEnv *env, int mode, char *name) LoadMainClass(JNIEnv *env, int mode, char *name)
{ {
jclass cls;
jmethodID mid; jmethodID mid;
jstring str; jstring str;
jobject result; jobject result;
jlong start, end; jlong start, end;
jclass cls = GetLauncherHelperClass(env);
NULL_CHECK0(cls);
if (JLI_IsTraceLauncher()) { if (JLI_IsTraceLauncher()) {
start = CounterGet(); start = CounterGet();
} }
NULL_CHECK0(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain", "checkAndLoadMain",
"(ZILjava/lang/String;)Ljava/lang/Class;")); "(ZILjava/lang/String;)Ljava/lang/Class;"));
str = (*env)->NewStringUTF(env, name);
result = (*env)->CallStaticObjectMethod(env, cls, mid, JNI_TRUE, mode, str); switch (mode) {
case LM_CLASS:
str = NewPlatformString(env, name);
break;
default:
str = (*env)->NewStringUTF(env, name);
break;
}
result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);
if (JLI_IsTraceLauncher()) { if (JLI_IsTraceLauncher()) {
end = CounterGet(); end = CounterGet();
@ -1478,15 +1458,15 @@ PrintJavaVersion(JNIEnv *env, jboolean extraLF)
static void static void
ShowSettings(JNIEnv *env, char *optString) ShowSettings(JNIEnv *env, char *optString)
{ {
jclass cls;
jmethodID showSettingsID; jmethodID showSettingsID;
jstring joptString; jstring joptString;
NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); jclass cls = GetLauncherHelperClass(env);
NULL_CHECK(cls);
NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls, NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls,
"showSettings", "(ZLjava/lang/String;JJJZ)V")); "showSettings", "(ZLjava/lang/String;JJJZ)V"));
joptString = (*env)->NewStringUTF(env, optString); joptString = (*env)->NewStringUTF(env, optString);
(*env)->CallStaticVoidMethod(env, cls, showSettingsID, (*env)->CallStaticVoidMethod(env, cls, showSettingsID,
JNI_TRUE, USE_STDERR,
joptString, joptString,
(jlong)initialHeapSize, (jlong)initialHeapSize,
(jlong)maxHeapSize, (jlong)maxHeapSize,
@ -1500,18 +1480,15 @@ ShowSettings(JNIEnv *env, char *optString)
static void static void
PrintUsage(JNIEnv* env, jboolean doXUsage) PrintUsage(JNIEnv* env, jboolean doXUsage)
{ {
jclass cls;
jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage; jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage;
jstring jprogname, vm1, vm2; jstring jprogname, vm1, vm2;
int i; int i;
jclass cls = GetLauncherHelperClass(env);
NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); NULL_CHECK(cls);
if (doXUsage) { if (doXUsage) {
NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls, NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls,
"printXUsageMessage", "(Z)V")); "printXUsageMessage", "(Z)V"));
(*env)->CallStaticVoidMethod(env, cls, printXUsageMessage, JNI_TRUE); (*env)->CallStaticVoidMethod(env, cls, printXUsageMessage, USE_STDERR);
} else { } else {
NULL_CHECK(initHelp = (*env)->GetStaticMethodID(env, cls, NULL_CHECK(initHelp = (*env)->GetStaticMethodID(env, cls,
"initHelpMessage", "(Ljava/lang/String;)V")); "initHelpMessage", "(Ljava/lang/String;)V"));
@ -1570,7 +1547,7 @@ PrintUsage(JNIEnv* env, jboolean doXUsage)
} }
/* Complete the usage message and print to stderr*/ /* Complete the usage message and print to stderr*/
(*env)->CallStaticVoidMethod(env, cls, printHelp, JNI_TRUE); (*env)->CallStaticVoidMethod(env, cls, printHelp, USE_STDERR);
} }
return; return;
} }

View File

@ -743,24 +743,24 @@ class BandStructure {
private void dumpBand() throws IOException { private void dumpBand() throws IOException {
assert(optDumpBands); assert(optDumpBands);
PrintStream ps = new PrintStream(getDumpStream(this, ".txt")); try (PrintStream ps = new PrintStream(getDumpStream(this, ".txt"))) {
String irr = (bandCoding == regularCoding) ? "" : " irregular"; String irr = (bandCoding == regularCoding) ? "" : " irregular";
ps.print("# length="+length+ ps.print("# length="+length+
" size="+outputSize()+ " size="+outputSize()+
irr+" coding="+bandCoding); irr+" coding="+bandCoding);
if (metaCoding != noMetaCoding) { if (metaCoding != noMetaCoding) {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
for (int i = 0; i < metaCoding.length; i++) { for (int i = 0; i < metaCoding.length; i++) {
if (i == 1) sb.append(" /"); if (i == 1) sb.append(" /");
sb.append(" ").append(metaCoding[i] & 0xFF); sb.append(" ").append(metaCoding[i] & 0xFF);
}
ps.print(" //header: "+sb);
} }
ps.print(" //header: "+sb); printArrayTo(ps, values, 0, length);
}
try (OutputStream ds = getDumpStream(this, ".bnd")) {
bandCoding.writeArrayTo(ds, values, 0, length);
} }
printArrayTo(ps, values, 0, length);
ps.close();
OutputStream ds = getDumpStream(this, ".bnd");
bandCoding.writeArrayTo(ds, values, 0, length);
ds.close();
} }
/** Disburse one value. */ /** Disburse one value. */
@ -829,12 +829,12 @@ class BandStructure {
private void dumpBand() throws IOException { private void dumpBand() throws IOException {
assert(optDumpBands); assert(optDumpBands);
OutputStream ds = getDumpStream(this, ".bnd"); try (OutputStream ds = getDumpStream(this, ".bnd")) {
if (bytesForDump != null) if (bytesForDump != null)
bytesForDump.writeTo(ds); bytesForDump.writeTo(ds);
else else
bytes.writeTo(ds); bytes.writeTo(ds);
ds.close(); }
} }
public void readDataFrom(InputStream in) throws IOException { public void readDataFrom(InputStream in) throws IOException {

View File

@ -150,12 +150,12 @@ class Driver {
// See if there is any other action to take. // See if there is any other action to take.
if ("--config-file=".equals(state)) { if ("--config-file=".equals(state)) {
String propFile = av.remove(0); String propFile = av.remove(0);
InputStream propIn = new FileInputStream(propFile);
Properties fileProps = new Properties(); Properties fileProps = new Properties();
fileProps.load(new BufferedInputStream(propIn)); try (InputStream propIn = new FileInputStream(propFile)) {
fileProps.load(propIn);
}
if (engProps.get(verboseProp) != null) if (engProps.get(verboseProp) != null)
fileProps.list(System.out); fileProps.list(System.out);
propIn.close();
for (Map.Entry<Object,Object> me : fileProps.entrySet()) { for (Map.Entry<Object,Object> me : fileProps.entrySet()) {
engProps.put((String) me.getKey(), (String) me.getValue()); engProps.put((String) me.getKey(), (String) me.getValue());
} }
@ -348,10 +348,10 @@ class Driver {
else else
fileOut = new FileOutputStream(outfile); fileOut = new FileOutputStream(outfile);
fileOut = new BufferedOutputStream(fileOut); fileOut = new BufferedOutputStream(fileOut);
JarOutputStream out = new JarOutputStream(fileOut); try (JarOutputStream out = new JarOutputStream(fileOut)) {
junpack.unpack(in, out); junpack.unpack(in, out);
//in.close(); // p200 closes in but not out // p200 closes in but not out
out.close(); }
// At this point, we have a good jarfile (or newfile, if -r) // At this point, we have a good jarfile (or newfile, if -r)
} }
@ -411,8 +411,7 @@ class Driver {
long filelen = new File(jarfile).length(); long filelen = new File(jarfile).length();
if (filelen <= 0) return ""; if (filelen <= 0) return "";
long skiplen = Math.max(0, filelen - tail.length); long skiplen = Math.max(0, filelen - tail.length);
InputStream in = new FileInputStream(new File(jarfile)); try (InputStream in = new FileInputStream(new File(jarfile))) {
try {
in.skip(skiplen); in.skip(skiplen);
in.read(tail); in.read(tail);
for (int i = tail.length-4; i >= 0; i--) { for (int i = tail.length-4; i >= 0; i--) {
@ -426,8 +425,6 @@ class Driver {
} }
} }
return ""; return "";
} finally {
in.close();
} }
} }

View File

@ -241,9 +241,9 @@ class NativeUnpack {
void run(File inFile, JarOutputStream jstream) throws IOException { void run(File inFile, JarOutputStream jstream) throws IOException {
// %%% maybe memory-map the file, and pass it straight into unpacker // %%% maybe memory-map the file, and pass it straight into unpacker
ByteBuffer mappedFile = null; ByteBuffer mappedFile = null;
FileInputStream fis = new FileInputStream(inFile); try (FileInputStream fis = new FileInputStream(inFile)) {
run(fis, jstream, mappedFile); run(fis, jstream, mappedFile);
fis.close(); }
// Note: caller is responsible to finish with jstream. // Note: caller is responsible to finish with jstream.
} }

View File

@ -540,9 +540,9 @@ class PackageReader extends BandStructure {
Index index = initCPIndex(tag, cpMap); Index index = initCPIndex(tag, cpMap);
if (optDumpBands) { if (optDumpBands) {
PrintStream ps = new PrintStream(getDumpStream(index, ".idx")); try (PrintStream ps = new PrintStream(getDumpStream(index, ".idx"))) {
printArrayTo(ps, index.cpMap, 0, index.cpMap.length); printArrayTo(ps, index.cpMap, 0, index.cpMap.length);
ps.close(); }
} }
} }
@ -828,26 +828,27 @@ class PackageReader extends BandStructure {
attr_definition_headers.readFrom(in); attr_definition_headers.readFrom(in);
attr_definition_name.readFrom(in); attr_definition_name.readFrom(in);
attr_definition_layout.readFrom(in); attr_definition_layout.readFrom(in);
PrintStream dump = !optDumpBands ? null try (PrintStream dump = !optDumpBands ? null
: new PrintStream(getDumpStream(attr_definition_headers, ".def")); : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
for (int i = 0; i < numAttrDefs; i++) { {
int header = attr_definition_headers.getByte(); for (int i = 0; i < numAttrDefs; i++) {
Utf8Entry name = (Utf8Entry) attr_definition_name.getRef(); int header = attr_definition_headers.getByte();
Utf8Entry layout = (Utf8Entry) attr_definition_layout.getRef(); Utf8Entry name = (Utf8Entry) attr_definition_name.getRef();
int ctype = (header & ADH_CONTEXT_MASK); Utf8Entry layout = (Utf8Entry) attr_definition_layout.getRef();
int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB; int ctype = (header & ADH_CONTEXT_MASK);
Attribute.Layout def = new Attribute.Layout(ctype, int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
name.stringValue(), Attribute.Layout def = new Attribute.Layout(ctype,
layout.stringValue()); name.stringValue(),
// Check layout string for Java 6 extensions. layout.stringValue());
String pvLayout = def.layoutForPackageMajver(getPackageMajver()); // Check layout string for Java 6 extensions.
if (!pvLayout.equals(def.layout())) { String pvLayout = def.layoutForPackageMajver(getPackageMajver());
throw new IOException("Bad attribute layout in version 150 archive: "+def.layout()); if (!pvLayout.equals(def.layout())) {
throw new IOException("Bad attribute layout in version 150 archive: "+def.layout());
}
this.setAttributeLayoutIndex(def, index);
if (dump != null) dump.println(index+" "+def);
} }
this.setAttributeLayoutIndex(def, index);
if (dump != null) dump.println(index+" "+def);
} }
if (dump != null) dump.close();
attr_definition_headers.doneDisbursing(); attr_definition_headers.doneDisbursing();
attr_definition_name.doneDisbursing(); attr_definition_name.doneDisbursing();
attr_definition_layout.doneDisbursing(); attr_definition_layout.doneDisbursing();

View File

@ -458,9 +458,9 @@ class PackageWriter extends BandStructure {
Utils.log.info("Writing "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries..."); Utils.log.info("Writing "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries...");
if (optDumpBands) { if (optDumpBands) {
PrintStream ps = new PrintStream(getDumpStream(index, ".idx")); try (PrintStream ps = new PrintStream(getDumpStream(index, ".idx"))) {
printArrayTo(ps, cpMap, 0, cpMap.length); printArrayTo(ps, cpMap, 0, cpMap.length);
ps.close(); }
} }
switch (tag) { switch (tag) {
@ -923,33 +923,34 @@ class PackageWriter extends BandStructure {
} }
}); });
attrDefsWritten = new Attribute.Layout[numAttrDefs]; attrDefsWritten = new Attribute.Layout[numAttrDefs];
PrintStream dump = !optDumpBands ? null try (PrintStream dump = !optDumpBands ? null
: new PrintStream(getDumpStream(attr_definition_headers, ".def")); : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT); {
for (int i = 0; i < defs.length; i++) { int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT);
int header = ((Integer)defs[i][0]).intValue(); for (int i = 0; i < defs.length; i++) {
Attribute.Layout def = (Attribute.Layout) defs[i][1]; int header = ((Integer)defs[i][0]).intValue();
attrDefsWritten[i] = def; Attribute.Layout def = (Attribute.Layout) defs[i][1];
assert((header & ADH_CONTEXT_MASK) == def.ctype()); attrDefsWritten[i] = def;
attr_definition_headers.putByte(header); assert((header & ADH_CONTEXT_MASK) == def.ctype());
attr_definition_name.putRef(ConstantPool.getUtf8Entry(def.name())); attr_definition_headers.putByte(header);
String layout = def.layoutForPackageMajver(getPackageMajver()); attr_definition_name.putRef(ConstantPool.getUtf8Entry(def.name()));
attr_definition_layout.putRef(ConstantPool.getUtf8Entry(layout)); String layout = def.layoutForPackageMajver(getPackageMajver());
// Check that we are transmitting that correct attribute index: attr_definition_layout.putRef(ConstantPool.getUtf8Entry(layout));
boolean debug = false; // Check that we are transmitting that correct attribute index:
assert(debug = true); boolean debug = false;
if (debug) { assert(debug = true);
int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB; if (debug) {
if (hdrIndex < 0) hdrIndex = indexForDebug[def.ctype()]++; int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
int realIndex = (attrIndexTable.get(def)).intValue(); if (hdrIndex < 0) hdrIndex = indexForDebug[def.ctype()]++;
assert(hdrIndex == realIndex); int realIndex = (attrIndexTable.get(def)).intValue();
} assert(hdrIndex == realIndex);
if (dump != null) { }
int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB; if (dump != null) {
dump.println(index+" "+def); int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
dump.println(index+" "+def);
}
} }
} }
if (dump != null) dump.close();
} }
void writeAttrCounts() throws IOException { void writeAttrCounts() throws IOException {

View File

@ -122,26 +122,23 @@ final class PropMap implements SortedMap<Object, Object> {
// Define certain attribute layouts by default. // Define certain attribute layouts by default.
// Do this after the previous props are put in place, // Do this after the previous props are put in place,
// to allow override if necessary. // to allow override if necessary.
InputStream propStr = null; String propFile = "intrinsic.properties";
try {
String propFile = "intrinsic.properties"; try (InputStream propStr = PackerImpl.class.getResourceAsStream(propFile)) {
propStr = PackerImpl.class.getResourceAsStream(propFile); if (propStr == null) {
props.load(new BufferedInputStream(propStr)); throw new RuntimeException(propFile + " cannot be loaded");
for (Map.Entry<Object, Object> e : props.entrySet()) {
String key = (String) e.getKey();
String val = (String) e.getValue();
if (key.startsWith("attribute.")) {
e.setValue(Attribute.normalizeLayoutString(val));
}
} }
props.load(propStr);
} catch (IOException ee) { } catch (IOException ee) {
throw new RuntimeException(ee); throw new RuntimeException(ee);
} finally { }
try {
if (propStr != null) { for (Map.Entry<Object, Object> e : props.entrySet()) {
propStr.close(); String key = (String) e.getKey();
} String val = (String) e.getValue();
} catch (IOException ignore) {} if (key.startsWith("attribute.")) {
e.setValue(Attribute.normalizeLayoutString(val));
}
} }
defaultProps = (new HashMap<>(props)); // shrink to fit defaultProps = (new HashMap<>(props)); // shrink to fit

View File

@ -161,8 +161,9 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
} }
// Use the stream-based implementation. // Use the stream-based implementation.
// %%% Reconsider if native unpacker learns to memory-map the file. // %%% Reconsider if native unpacker learns to memory-map the file.
FileInputStream instr = new FileInputStream(in); try (FileInputStream instr = new FileInputStream(in)) {
unpack(instr, out); unpack(instr, out);
}
if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
in.delete(); in.delete();
} }

View File

@ -268,18 +268,18 @@ class Utils {
// 4947205 : Peformance is slow when using pack-effort=0 // 4947205 : Peformance is slow when using pack-effort=0
out = new BufferedOutputStream(out); out = new BufferedOutputStream(out);
out = new NonCloser(out); // protect from JarOutputStream.close() out = new NonCloser(out); // protect from JarOutputStream.close()
JarOutputStream jout = new JarOutputStream(out); try (JarOutputStream jout = new JarOutputStream(out)) {
copyJarFile(in, jout); copyJarFile(in, jout);
jout.close(); }
} }
static void copyJarFile(JarFile in, OutputStream out) throws IOException { static void copyJarFile(JarFile in, OutputStream out) throws IOException {
// 4947205 : Peformance is slow when using pack-effort=0 // 4947205 : Peformance is slow when using pack-effort=0
out = new BufferedOutputStream(out); out = new BufferedOutputStream(out);
out = new NonCloser(out); // protect from JarOutputStream.close() out = new NonCloser(out); // protect from JarOutputStream.close()
JarOutputStream jout = new JarOutputStream(out); try (JarOutputStream jout = new JarOutputStream(out)) {
copyJarFile(in, jout); copyJarFile(in, jout);
jout.close(); }
} }
// Wrapper to prevent closing of client-supplied stream. // Wrapper to prevent closing of client-supplied stream.
static private static private

View File

@ -210,6 +210,8 @@ public final class Transform extends SignatureElementProxy {
public static void init() { public static void init() {
if (!alreadyInitialized) { if (!alreadyInitialized) {
transformClassHash = new HashMap(10); transformClassHash = new HashMap(10);
// make sure builtin algorithms are all registered first
com.sun.org.apache.xml.internal.security.Init.init();
alreadyInitialized = true; alreadyInitialized = true;
} }
} }
@ -236,12 +238,7 @@ public final class Transform extends SignatureElementProxy {
"algorithm.alreadyRegistered", exArgs); "algorithm.alreadyRegistered", exArgs);
} }
ClassLoader cl = (ClassLoader) AccessController.doPrivileged( ClassLoader cl = Thread.currentThread().getContextClassLoader();
new PrivilegedAction() {
public Object run() {
return Thread.currentThread().getContextClassLoader();
}
});
try { try {
transformClassHash.put transformClassHash.put

View File

@ -115,6 +115,31 @@ public final class RhinoScriptEngine extends AbstractScriptEngine
//construct object used to implement getInterface //construct object used to implement getInterface
implementor = new InterfaceImplementor(this) { implementor = new InterfaceImplementor(this) {
protected boolean isImplemented(Object thiz, Class<?> iface) {
Context cx = enterContext();
try {
if (thiz != null && !(thiz instanceof Scriptable)) {
thiz = cx.toObject(thiz, topLevel);
}
Scriptable engineScope = getRuntimeScope(context);
Scriptable localScope = (thiz != null)? (Scriptable) thiz :
engineScope;
for (Method method : iface.getMethods()) {
// ignore methods of java.lang.Object class
if (method.getDeclaringClass() == Object.class) {
continue;
}
Object obj = ScriptableObject.getProperty(localScope, method.getName());
if (! (obj instanceof Function)) {
return false;
}
}
return true;
} finally {
cx.exit();
}
}
protected Object convertResult(Method method, Object res) protected Object convertResult(Method method, Object res)
throws ScriptException { throws ScriptException {
Class desiredType = method.getReturnType(); Class desiredType = method.getReturnType();

View File

@ -82,12 +82,19 @@ public class InterfaceImplementor {
if (iface == null || !iface.isInterface()) { if (iface == null || !iface.isInterface()) {
throw new IllegalArgumentException("interface Class expected"); throw new IllegalArgumentException("interface Class expected");
} }
if (! isImplemented(thiz, iface)) {
return null;
}
AccessControlContext accCtxt = AccessController.getContext(); AccessControlContext accCtxt = AccessController.getContext();
return iface.cast(Proxy.newProxyInstance(iface.getClassLoader(), return iface.cast(Proxy.newProxyInstance(iface.getClassLoader(),
new Class[]{iface}, new Class[]{iface},
new InterfaceImplementorInvocationHandler(thiz, accCtxt))); new InterfaceImplementorInvocationHandler(thiz, accCtxt)));
} }
protected boolean isImplemented(Object thiz, Class<?> iface) {
return true;
}
// called to convert method result after invoke // called to convert method result after invoke
protected Object convertResult(Method method, Object res) protected Object convertResult(Method method, Object res)
throws ScriptException { throws ScriptException {

View File

@ -33,6 +33,11 @@ import java.lang.reflect.Field;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.io.ObjectInputStream;
import java.io.IOException;
/** /**
* The root event class for all AWT events. * The root event class for all AWT events.
* This class and its subclasses supercede the original * This class and its subclasses supercede the original
@ -97,6 +102,22 @@ public abstract class AWTEvent extends EventObject {
*/ */
protected boolean consumed = false; protected boolean consumed = false;
/*
* The event's AccessControlContext.
*/
private transient volatile AccessControlContext acc =
AccessController.getContext();
/*
* Returns the acc this event was constructed with.
*/
final AccessControlContext getAccessControlContext() {
if (acc == null) {
throw new SecurityException("AWTEvent is missing AccessControlContext");
}
return acc;
}
transient boolean focusManagerIsDispatching = false; transient boolean focusManagerIsDispatching = false;
transient boolean isPosted; transient boolean isPosted;
@ -247,6 +268,10 @@ public abstract class AWTEvent extends EventObject {
public boolean isSystemGenerated(AWTEvent ev) { public boolean isSystemGenerated(AWTEvent ev) {
return ev.isSystemGenerated; return ev.isSystemGenerated;
} }
public AccessControlContext getAccessControlContext(AWTEvent ev) {
return ev.getAccessControlContext();
}
}); });
} }

View File

@ -59,6 +59,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.AccessControlContext;
import javax.accessibility.*; import javax.accessibility.*;
import java.applet.Applet; import java.applet.Applet;
@ -471,6 +472,12 @@ public abstract class Component implements ImageObserver, MenuContainer,
static final Object LOCK = new AWTTreeLock(); static final Object LOCK = new AWTTreeLock();
static class AWTTreeLock {} static class AWTTreeLock {}
/*
* The component's AccessControlContext.
*/
private transient volatile AccessControlContext acc =
AccessController.getContext();
/** /**
* Minimum size. * Minimum size.
* (This field perhaps should have been transient). * (This field perhaps should have been transient).
@ -671,6 +678,16 @@ public abstract class Component implements ImageObserver, MenuContainer,
return objectLock; return objectLock;
} }
/*
* Returns the acc this component was constructed with.
*/
final AccessControlContext getAccessControlContext() {
if (acc == null) {
throw new SecurityException("Component is missing AccessControlContext");
}
return acc;
}
boolean isPacked = false; boolean isPacked = false;
/** /**
@ -950,6 +967,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
public void processEvent(Component comp, AWTEvent e) { public void processEvent(Component comp, AWTEvent e) {
comp.processEvent(e); comp.processEvent(e);
} }
public AccessControlContext getAccessControlContext(Component comp) {
return comp.getAccessControlContext();
}
}); });
} }
@ -3873,6 +3894,11 @@ public abstract class Component implements ImageObserver, MenuContainer,
* supported or met * supported or met
* @exception ClassCastException if the component is not a canvas or * @exception ClassCastException if the component is not a canvas or
* window. * window.
* @exception IllegalStateException if the component has no peer
* @exception IllegalArgumentException if {@code numBuffers} is less than two,
* or if {@code BufferCapabilities.isPageFlipping} is not
* {@code true}.
* @see #createBuffers(int, BufferCapabilities)
*/ */
protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps) protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
throws AWTException throws AWTException
@ -8608,6 +8634,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
{ {
objectLock = new Object(); objectLock = new Object();
acc = AccessController.getContext();
s.defaultReadObject(); s.defaultReadObject();
appContext = AppContext.getAppContext(); appContext = AppContext.getAppContext();

View File

@ -48,6 +48,12 @@ import sun.awt.AWTAccessor;
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.security.AccessControlContext;
import java.security.ProtectionDomain;
import sun.misc.SharedSecrets;
import sun.misc.JavaSecurityAccess;
/** /**
* <code>EventQueue</code> is a platform-independent class * <code>EventQueue</code> is a platform-independent class
* that queues events, both from the underlying peer classes * that queues events, both from the underlying peer classes
@ -612,6 +618,9 @@ public class EventQueue {
return null; return null;
} }
private static final JavaSecurityAccess javaSecurityAccess =
SharedSecrets.getJavaSecurityAccess();
/** /**
* Dispatches an event. The manner in which the event is * Dispatches an event. The manner in which the event is
* dispatched depends upon the type of the event and the * dispatched depends upon the type of the event and the
@ -650,13 +659,49 @@ public class EventQueue {
* @throws NullPointerException if <code>event</code> is <code>null</code> * @throws NullPointerException if <code>event</code> is <code>null</code>
* @since 1.2 * @since 1.2
*/ */
protected void dispatchEvent(AWTEvent event) { protected void dispatchEvent(final AWTEvent event) {
final Object src = event.getSource();
final PrivilegedAction<Void> action = new PrivilegedAction<Void>() {
public Void run() {
dispatchEventImpl(event, src);
return null;
}
};
final AccessControlContext stack = AccessController.getContext();
final AccessControlContext srcAcc = getAccessControlContextFrom(src);
final AccessControlContext eventAcc = event.getAccessControlContext();
if (srcAcc == null) {
javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc);
} else {
javaSecurityAccess.doIntersectionPrivilege(
new PrivilegedAction<Void>() {
public Void run() {
javaSecurityAccess.doIntersectionPrivilege(action, eventAcc);
return null;
}
}, stack, srcAcc);
}
}
private static AccessControlContext getAccessControlContextFrom(Object src) {
return src instanceof Component ?
((Component)src).getAccessControlContext() :
src instanceof MenuComponent ?
((MenuComponent)src).getAccessControlContext() :
src instanceof TrayIcon ?
((TrayIcon)src).getAccessControlContext() :
null;
}
/**
* Called from dispatchEvent() under a correct AccessControlContext
*/
private void dispatchEventImpl(final AWTEvent event, final Object src) {
event.isPosted = true; event.isPosted = true;
Object src = event.getSource();
if (event instanceof ActiveEvent) { if (event instanceof ActiveEvent) {
// This could become the sole method of dispatching in time. // This could become the sole method of dispatching in time.
setCurrentEventAndMostRecentTimeImpl(event); setCurrentEventAndMostRecentTimeImpl(event);
((ActiveEvent)event).dispatch(); ((ActiveEvent)event).dispatch();
} else if (src instanceof Component) { } else if (src instanceof Component) {
((Component)src).dispatchEvent(event); ((Component)src).dispatchEvent(event);

View File

@ -57,8 +57,14 @@ import java.beans.ConstructorProperties;
* </pre> * </pre>
* *
* <p> * <p>
* The user may also select what action the {@code LinearGradientPaint} * The user may also select what action the {@code LinearGradientPaint} object
* should take when filling color outside the start and end points. * takes when it is filling the space outside the start and end points by
* setting {@code CycleMethod} to either {@code REFLECTION} or {@code REPEAT}.
* The distances between any two colors in any of the reflected or repeated
* copies of the gradient are the same as the distance between those same two
* colors between the start and end points.
* Note that some minor variations in distances may occur due to sampling at
* the granularity of a pixel.
* If no cycle method is specified, {@code NO_CYCLE} will be chosen by * If no cycle method is specified, {@code NO_CYCLE} will be chosen by
* default, which means the endpoint colors will be used to fill the * default, which means the endpoint colors will be used to fill the
* remaining area. * remaining area.

View File

@ -33,6 +33,9 @@ import sun.awt.SunToolkit;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
import javax.accessibility.*; import javax.accessibility.*;
import java.security.AccessControlContext;
import java.security.AccessController;
/** /**
* The abstract class <code>MenuComponent</code> is the superclass * The abstract class <code>MenuComponent</code> is the superclass
* of all menu-related components. In this respect, the class * of all menu-related components. In this respect, the class
@ -99,6 +102,23 @@ public abstract class MenuComponent implements java.io.Serializable {
*/ */
boolean newEventsOnly = false; boolean newEventsOnly = false;
/*
* The menu's AccessControlContext.
*/
private transient volatile AccessControlContext acc =
AccessController.getContext();
/*
* Returns the acc this menu component was constructed with.
*/
final AccessControlContext getAccessControlContext() {
if (acc == null) {
throw new SecurityException(
"MenuComponent is missing AccessControlContext");
}
return acc;
}
/* /*
* Internal constants for serialization. * Internal constants for serialization.
*/ */
@ -402,6 +422,9 @@ public abstract class MenuComponent implements java.io.Serializable {
throws ClassNotFoundException, IOException, HeadlessException throws ClassNotFoundException, IOException, HeadlessException
{ {
GraphicsEnvironment.checkHeadless(); GraphicsEnvironment.checkHeadless();
acc = AccessController.getContext();
s.defaultReadObject(); s.defaultReadObject();
appContext = AppContext.getAppContext(); appContext = AppContext.getAppContext();

View File

@ -286,6 +286,10 @@ public abstract class MultipleGradientPaint implements Paint {
/** /**
* Returns a copy of the transform applied to the gradient. * Returns a copy of the transform applied to the gradient.
* *
* <p>
* Note that if no transform is applied to the gradient
* when it is created, the identity transform is used.
*
* @return a copy of the transform applied to the gradient * @return a copy of the transform applied to the gradient
*/ */
public final AffineTransform getTransform() { public final AffineTransform getTransform() {
@ -293,10 +297,12 @@ public abstract class MultipleGradientPaint implements Paint {
} }
/** /**
* Returns the transparency mode for this Paint object. * Returns the transparency mode for this {@code Paint} object.
* *
* @return an integer value representing the transparency mode for * @return {@code OPAQUE} if all colors used by this
* this Paint object * {@code Paint} object are opaque,
* {@code TRANSLUCENT} if at least one of the
* colors used by this {@code Paint} object is not opaque.
* @see java.awt.Transparency * @see java.awt.Transparency
*/ */
public final int getTransparency() { public final int getTransparency() {

View File

@ -71,8 +71,24 @@ import java.beans.ConstructorProperties;
* </pre> * </pre>
* *
* <p> * <p>
* The user may also select what action the {@code RadialGradientPaint} * The user may also select what action the {@code RadialGradientPaint} object
* should take when filling color outside the bounds of the circle's radius. * takes when it is filling the space outside the circle's radius by
* setting {@code CycleMethod} to either {@code REFLECTION} or {@code REPEAT}.
* The gradient color proportions are equal for any particular line drawn
* from the focus point. The following figure shows that the distance AB
* is equal to the distance BC, and the distance AD is equal to the distance DE.
* <center>
* <img src = "doc-files/RadialGradientPaint-3.png">
* </center>
* If the gradient and graphics rendering transforms are uniformly scaled and
* the user sets the focus so that it coincides with the center of the circle,
* the gradient color proportions are equal for any line drawn from the center.
* The following figure shows the distances AB, BC, AD, and DE. They are all equal.
* <center>
* <img src = "doc-files/RadialGradientPaint-4.png">
* </center>
* Note that some minor variations in distances may occur due to sampling at
* the granularity of a pixel.
* If no cycle method is specified, {@code NO_CYCLE} will be chosen by * If no cycle method is specified, {@code NO_CYCLE} will be chosen by
* default, which means the the last keyframe color will be used to fill the * default, which means the the last keyframe color will be used to fill the
* remaining area. * remaining area.
@ -604,7 +620,7 @@ public final class RadialGradientPaint extends MultipleGradientPaint {
} }
/** /**
* Returns a copy of the end point of the gradient axis. * Returns a copy of the focus point of the radial gradient.
* *
* @return a {@code Point2D} object that is a copy of the focus point * @return a {@code Point2D} object that is a copy of the focus point
*/ */

View File

@ -40,6 +40,8 @@ import sun.awt.AppContext;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.awt.HeadlessToolkit; import sun.awt.HeadlessToolkit;
import java.util.EventObject; import java.util.EventObject;
import java.security.AccessControlContext;
import java.security.AccessController;
/** /**
* A <code>TrayIcon</code> object represents a tray icon that can be * A <code>TrayIcon</code> object represents a tray icon that can be
@ -90,6 +92,7 @@ import java.util.EventObject;
* @author Anton Tarasov * @author Anton Tarasov
*/ */
public class TrayIcon { public class TrayIcon {
private Image image; private Image image;
private String tooltip; private String tooltip;
private PopupMenu popup; private PopupMenu popup;
@ -103,6 +106,24 @@ public class TrayIcon {
transient MouseMotionListener mouseMotionListener; transient MouseMotionListener mouseMotionListener;
transient ActionListener actionListener; transient ActionListener actionListener;
/*
* The tray icon's AccessControlContext.
*
* Unlike the acc in Component, this field is made final
* because TrayIcon is not serializable.
*/
private final AccessControlContext acc = AccessController.getContext();
/*
* Returns the acc this tray icon was constructed with.
*/
final AccessControlContext getAccessControlContext() {
if (acc == null) {
throw new SecurityException("TrayIcon is missing AccessControlContext");
}
return acc;
}
static { static {
Toolkit.loadLibraries(); Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) { if (!GraphicsEnvironment.isHeadless()) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -343,8 +343,13 @@ public abstract class PackedColorModel extends ColorModel {
if (bitMasks.length != maskArray.length) { if (bitMasks.length != maskArray.length) {
return false; return false;
} }
/* compare 'effective' masks only, i.e. only part of the mask
* which fits the capacity of the transfer type.
*/
int maxMask = (int)((1L << DataBuffer.getDataTypeSize(transferType)) - 1);
for (int i=0; i < bitMasks.length; i++) { for (int i=0; i < bitMasks.length; i++) {
if (bitMasks[i] != maskArray[i]) { if ((maxMask & bitMasks[i]) != (maxMask & maskArray[i])) {
return false; return false;
} }
} }

View File

@ -35,7 +35,7 @@ import sun.reflect.misc.*;
* is the delegate used by default for classes about * is the delegate used by default for classes about
* which no information is available. The <code>DefaultPersistenceDelegate</code> * which no information is available. The <code>DefaultPersistenceDelegate</code>
* provides, version resilient, public API-based persistence for * provides, version resilient, public API-based persistence for
* classes that follow the JavaBeans conventions without any class specific * classes that follow the JavaBeans&trade; conventions without any class specific
* configuration. * configuration.
* <p> * <p>
* The key assumptions are that the class has a nullary constructor * The key assumptions are that the class has a nullary constructor

View File

@ -31,7 +31,7 @@ package java.beans;
* of java.beans.beancontext.BeanContext, in order to propagate to its nested hierarchy * of java.beans.beancontext.BeanContext, in order to propagate to its nested hierarchy
* of java.beans.beancontext.BeanContextChild instances, the current "designTime" property. * of java.beans.beancontext.BeanContextChild instances, the current "designTime" property.
* <p> * <p>
* The JavaBeans specification defines the notion of design time as is a * The JavaBeans&trade; specification defines the notion of design time as is a
* mode in which JavaBeans instances should function during their composition * mode in which JavaBeans instances should function during their composition
* and customization in a interactive design, composition or construction tool, * and customization in a interactive design, composition or construction tool,
* as opposed to runtime when the JavaBean is part of an applet, application, * as opposed to runtime when the JavaBean is part of an applet, application,

View File

@ -26,7 +26,7 @@ package java.beans;
/** /**
* An "IndexedPropertyChange" event gets delivered whenever a component that * An "IndexedPropertyChange" event gets delivered whenever a component that
* conforms to the JavaBeans<TM> specification (a "bean") changes a bound * conforms to the JavaBeans&trade; specification (a "bean") changes a bound
* indexed property. This class is an extension of <code>PropertyChangeEvent</code> * indexed property. This class is an extension of <code>PropertyChangeEvent</code>
* but contains the index of the property that has changed. * but contains the index of the property that has changed.
* <P> * <P>

View File

@ -87,7 +87,7 @@ import sun.reflect.misc.ReflectUtil;
* <p> * <p>
* For more information about introspection and design patterns, please * For more information about introspection and design patterns, please
* consult the * consult the
* <a href="http://java.sun.com/products/javabeans/docs/index.html">JavaBeans specification</a>. * <a href="http://java.sun.com/products/javabeans/docs/index.html">JavaBeans&trade; specification</a>.
*/ */
public class Introspector { public class Introspector {
@ -1245,7 +1245,7 @@ public class Introspector {
try { try {
type = ClassFinder.findClass(name, type.getClassLoader()); type = ClassFinder.findClass(name, type.getClassLoader());
// Each customizer should inherit java.awt.Component and implement java.beans.Customizer // Each customizer should inherit java.awt.Component and implement java.beans.Customizer
// according to the section 9.3 of JavaBeans specification // according to the section 9.3 of JavaBeans&trade; specification
if (Component.class.isAssignableFrom(type) && Customizer.class.isAssignableFrom(type)) { if (Component.class.isAssignableFrom(type) && Customizer.class.isAssignableFrom(type)) {
return type; return type;
} }

View File

@ -474,7 +474,7 @@ public class VetoableChangeSupport implements Serializable {
/** /**
* @serialField children Hashtable * @serialField children Hashtable
* @serialField source Object * @serialField source Object
* @serialField propertyChangeSupportSerializedDataVersion int * @serialField vetoableChangeSupportSerializedDataVersion int
*/ */
private static final ObjectStreamField[] serialPersistentFields = { private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("children", Hashtable.class), new ObjectStreamField("children", Hashtable.class),

View File

@ -29,7 +29,7 @@
Contains classes related to developing Contains classes related to developing
<em>beans</em> -- components <em>beans</em> -- components
based on the JavaBeans<sup><font size=-2>TM</font></sup> architecture. based on the JavaBeans&trade; architecture.
A few of the A few of the
classes are used by beans while they run in an application. classes are used by beans while they run in an application.
For example, the event classes are For example, the event classes are

View File

@ -1,125 +0,0 @@
/*
* Copyright (c) 2008, 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 java.dyn;
import java.dyn.MethodHandles.Lookup;
import java.util.WeakHashMap;
import sun.dyn.Access;
import sun.dyn.MethodHandleImpl;
import sun.dyn.util.VerifyAccess;
import sun.reflect.Reflection;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* <em>CLASS WILL BE REMOVED FOR PFD:</em>
* Static routines for controlling invokedynamic behavior.
* Replaced by non-static APIs.
* @author John Rose, JSR 292 EG
* @deprecated This class will be removed in the Public Final Draft.
*/
public class Linkage {
private static final Access IMPL_TOKEN = Access.getToken();
private Linkage() {} // do not instantiate
/**
* <em>METHOD WILL BE REMOVED FOR PFD:</em>
* Register a <em>bootstrap method</em> to use when linking dynamic call sites within
* a given caller class.
* @deprecated Use @{@link BootstrapMethod} annotations instead.
*/
public static
void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
Class callc = Reflection.getCallerClass(2);
if (callc != null && !VerifyAccess.isSamePackage(callerClass, callc))
throw new IllegalArgumentException("cannot set bootstrap method on "+callerClass);
MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
}
/**
* <em>METHOD WILL BE REMOVED FOR PFD:</em>
* Simplified version of {@code registerBootstrapMethod} for self-registration,
* to be called from a static initializer.
* @deprecated Use @{@link BootstrapMethod} annotations instead.
*/
public static
void registerBootstrapMethod(Class<?> runtime, String name) {
Class callerClass = Reflection.getCallerClass(2);
registerBootstrapMethodLookup(callerClass, runtime, name);
}
/**
* <em>METHOD WILL BE REMOVED FOR PFD:</em>
* Simplified version of {@code registerBootstrapMethod} for self-registration,
* @deprecated Use @{@link BootstrapMethod} annotations instead.
*/
public static
void registerBootstrapMethod(String name) {
Class callerClass = Reflection.getCallerClass(2);
registerBootstrapMethodLookup(callerClass, callerClass, name);
}
private static
void registerBootstrapMethodLookup(Class<?> callerClass, Class<?> runtime, String name) {
Lookup lookup = new Lookup(IMPL_TOKEN, callerClass);
MethodHandle bootstrapMethod;
try {
bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
} catch (ReflectiveOperationException ex) {
throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
}
MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
}
private static final MethodType BOOTSTRAP_METHOD_TYPE
= MethodType.methodType(CallSite.class,
Class.class, String.class, MethodType.class);
/**
* <em>METHOD WILL BE REMOVED FOR PFD:</em>
* Invalidate all <code>invokedynamic</code> call sites everywhere.
* @deprecated Use {@linkplain MutableCallSite#setTarget call site target setting},
* {@link MutableCallSite#syncAll call site update pushing},
* and {@link SwitchPoint#guardWithTest target switching} instead.
*/
public static
Object invalidateAll() {
throw new UnsupportedOperationException();
}
/**
* <em>METHOD WILL BE REMOVED FOR PFD:</em>
* Invalidate all {@code invokedynamic} call sites in the bytecodes
* of any methods of the given class.
* @deprecated Use {@linkplain MutableCallSite#setTarget call site target setting},
* {@link MutableCallSite#syncAll call site update pushing},
* and {@link SwitchPoint#guardWithTest target switching} instead.
*/
public static
Object invalidateCallerClass(Class<?> callerClass) {
throw new UnsupportedOperationException();
}
}

View File

@ -34,12 +34,27 @@ package java.lang;
public interface AutoCloseable { public interface AutoCloseable {
/** /**
* Closes this resource, relinquishing any underlying resources. * Closes this resource, relinquishing any underlying resources.
* This method is invoked automatically by the {@code * This method is invoked automatically on objects managed by the
* try}-with-resources statement. * {@code try}-with-resources statement.
* *
* <p>Classes implementing this method are strongly encouraged to * <p>While this interface method is declared to throw {@code
* be declared to throw more specific exceptions (or no exception * Exception}, implementers are <em>strongly</em> encouraged to
* at all, if the close cannot fail). * declare concrete implementations of the {@code close} method to
* throw more specific exceptions, or to throw no exception at all
* if the close operation cannot fail.
*
* <p><em>Implementers of this interface are also strongly advised
* to not have the {@code close} method throw {@link
* InterruptedException}.</em>
*
* This exception interacts with a thread's interrupted status,
* and runtime misbehavior is likely to occur if an {@code
* InterruptedException} is {@linkplain Throwable#addSuppressed
* suppressed}.
*
* More generally, if it would cause problems for an
* exception to be suppressed, the {@code AutoCloseable.close}
* method should not throw it.
* *
* <p>Note that unlike the {@link java.io.Closeable#close close} * <p>Note that unlike the {@link java.io.Closeable#close close}
* method of {@link java.io.Closeable}, this {@code close} method * method of {@link java.io.Closeable}, this {@code close} method
@ -48,9 +63,8 @@ public interface AutoCloseable {
* visible side effect, unlike {@code Closeable.close} which is * visible side effect, unlike {@code Closeable.close} which is
* required to have no effect if called more than once. * required to have no effect if called more than once.
* *
* However, while not required to be idempotent, implementers of * However, implementers of this interface are strongly encouraged
* this interface are strongly encouraged to make their {@code * to make their {@code close} methods idempotent.
* close} methods idempotent.
* *
* @throws Exception if this resource cannot be closed * @throws Exception if this resource cannot be closed
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,58 +23,56 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang;
/** /**
* Thrown to indicate that an {@code invokedynamic} instruction has * Thrown to indicate that an {@code invokedynamic} instruction has
* failed to find its * failed to find its bootstrap method,
* {@linkplain BootstrapMethod bootstrap method}, * or the bootstrap method has failed to provide a
* or the bootstrap method has * {@linkplain java.lang.invoke.CallSite call site} with a {@linkplain java.lang.invoke.CallSite#getTarget target}
* failed to provide a * of the correct {@linkplain java.lang.invoke.MethodHandle#type method type}.
* {@linkplain CallSite call site} with a {@linkplain CallSite#getTarget target}
* of the correct {@linkplain MethodHandle#type method type}.
* *
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
* @since 1.7 * @since 1.7
*/ */
public class InvokeDynamicBootstrapError extends LinkageError { public class BootstrapMethodError extends LinkageError {
private static final long serialVersionUID = 292L; private static final long serialVersionUID = 292L;
/** /**
* Constructs an {@code InvokeDynamicBootstrapError} with no detail message. * Constructs an {@code BootstrapMethodError} with no detail message.
*/ */
public InvokeDynamicBootstrapError() { public BootstrapMethodError() {
super(); super();
} }
/** /**
* Constructs an {@code InvokeDynamicBootstrapError} with the specified * Constructs an {@code BootstrapMethodError} with the specified
* detail message. * detail message.
* *
* @param s the detail message. * @param s the detail message.
*/ */
public InvokeDynamicBootstrapError(String s) { public BootstrapMethodError(String s) {
super(s); super(s);
} }
/** /**
* Constructs a {@code InvokeDynamicBootstrapError} with the specified * Constructs a {@code BootstrapMethodError} with the specified
* detail message and cause. * detail message and cause.
* *
* @param s the detail message. * @param s the detail message.
* @param cause the cause, may be {@code null}. * @param cause the cause, may be {@code null}.
*/ */
public InvokeDynamicBootstrapError(String s, Throwable cause) { public BootstrapMethodError(String s, Throwable cause) {
super(s, cause); super(s, cause);
} }
/** /**
* Constructs a {@code InvokeDynamicBootstrapError} with the specified * Constructs a {@code BootstrapMethodError} with the specified
* cause. * cause.
* *
* @param cause the cause, may be {@code null}. * @param cause the cause, may be {@code null}.
*/ */
public InvokeDynamicBootstrapError(Throwable cause) { public BootstrapMethodError(Throwable cause) {
// cf. Throwable(Throwable cause) constructor. // cf. Throwable(Throwable cause) constructor.
super(cause == null ? null : cause.toString()); super(cause == null ? null : cause.toString());
initCause(cause); initCause(cause);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1626,20 +1626,28 @@ public abstract class ClassLoader {
* @since 1.2 * @since 1.2
*/ */
protected Package getPackage(String name) { protected Package getPackage(String name) {
Package pkg;
synchronized (packages) { synchronized (packages) {
Package pkg = packages.get(name); pkg = packages.get(name);
if (pkg == null) { }
if (parent != null) { if (pkg == null) {
pkg = parent.getPackage(name); if (parent != null) {
} else { pkg = parent.getPackage(name);
pkg = Package.getSystemPackage(name); } else {
} pkg = Package.getSystemPackage(name);
if (pkg != null) { }
packages.put(name, pkg); if (pkg != null) {
synchronized (packages) {
Package pkg2 = packages.get(name);
if (pkg2 == null) {
packages.put(name, pkg);
} else {
pkg = pkg2;
}
} }
} }
return pkg;
} }
return pkg;
} }
/** /**

View File

@ -23,12 +23,10 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.lang.reflect.UndeclaredThrowableException;
/** /**
* Lazily associate a computed value with (potentially) every type. * Lazily associate a computed value with (potentially) every type.
@ -37,10 +35,11 @@ import java.lang.reflect.UndeclaredThrowableException;
* it can use a {@code ClassValue} to cache information needed to * it can use a {@code ClassValue} to cache information needed to
* perform the message send quickly, for each class encountered. * perform the message send quickly, for each class encountered.
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
* @since 1.7
*/ */
public abstract class ClassValue<T> { public abstract class ClassValue<T> {
/** /**
* Compute the given class's derived value for this {@code ClassValue}. * Computes the given class's derived value for this {@code ClassValue}.
* <p> * <p>
* This method will be invoked within the first thread that accesses * This method will be invoked within the first thread that accesses
* the value with the {@link #get get} method. * the value with the {@link #get get} method.
@ -159,13 +158,7 @@ public abstract class ClassValue<T> {
} }
/// Implementation... /// Implementation...
// FIXME: Use a data structure here similar that of ThreadLocal (7030453).
// The hash code for this type is based on the identity of the object,
// and is well-dispersed for power-of-two tables.
/** @deprecated This override, which is implementation-specific, will be removed for PFD. */
public final int hashCode() { return hashCode; }
private final int hashCode = HASH_CODES.getAndAdd(0x61c88647);
private static final AtomicInteger HASH_CODES = new AtomicInteger();
private static final AtomicInteger STORE_BARRIER = new AtomicInteger(); private static final AtomicInteger STORE_BARRIER = new AtomicInteger();

View File

@ -23,20 +23,19 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import sun.dyn.util.VerifyType; import sun.invoke.util.VerifyType;
import sun.dyn.util.Wrapper; import sun.invoke.util.Wrapper;
import java.dyn.*;
import java.util.Arrays; import java.util.Arrays;
import static sun.dyn.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static sun.dyn.MemberName.newIllegalArgumentException; import static java.lang.invoke.MethodHandleStatics.*;
/** /**
* This method handle performs simple conversion or checking of a single argument. * This method handle performs simple conversion or checking of a single argument.
* @author jrose * @author jrose
*/ */
public class AdapterMethodHandle extends BoundMethodHandle { class AdapterMethodHandle extends BoundMethodHandle {
//MethodHandle vmtarget; // next AMH or BMH in chain or final DMH //MethodHandle vmtarget; // next AMH or BMH in chain or final DMH
//Object argument; // parameter to the conversion if needed //Object argument; // parameter to the conversion if needed
@ -48,25 +47,21 @@ public class AdapterMethodHandle extends BoundMethodHandle {
long conv, Object convArg) { long conv, Object convArg) {
super(newType, convArg, newType.parameterSlotDepth(1+convArgPos(conv))); super(newType, convArg, newType.parameterSlotDepth(1+convArgPos(conv)));
this.conversion = convCode(conv); this.conversion = convCode(conv);
if (MethodHandleNatives.JVM_SUPPORT) { // JVM might update VM-specific bits of conversion (ignore)
// JVM might update VM-specific bits of conversion (ignore) MethodHandleNatives.init(this, target, convArgPos(conv));
MethodHandleNatives.init(this, target, convArgPos(conv));
}
} }
private AdapterMethodHandle(MethodHandle target, MethodType newType, private AdapterMethodHandle(MethodHandle target, MethodType newType,
long conv) { long conv) {
this(target, newType, conv, null); this(target, newType, conv, null);
} }
private static final Access IMPL_TOKEN = Access.getToken();
// TO DO: When adapting another MH with a null conversion, clone // TO DO: When adapting another MH with a null conversion, clone
// the target and change its type, instead of adding another layer. // the target and change its type, instead of adding another layer.
/** Can a JVM-level adapter directly implement the proposed /** Can a JVM-level adapter directly implement the proposed
* argument conversions, as if by MethodHandles.convertArguments? * argument conversions, as if by MethodHandles.convertArguments?
*/ */
public static boolean canPairwiseConvert(MethodType newType, MethodType oldType) { static boolean canPairwiseConvert(MethodType newType, MethodType oldType) {
// same number of args, of course // same number of args, of course
int len = newType.parameterCount(); int len = newType.parameterCount();
if (len != oldType.parameterCount()) if (len != oldType.parameterCount())
@ -92,7 +87,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Can a JVM-level adapter directly implement the proposed /** Can a JVM-level adapter directly implement the proposed
* argument conversion, as if by MethodHandles.convertArguments? * argument conversion, as if by MethodHandles.convertArguments?
*/ */
public static boolean canConvertArgument(Class<?> src, Class<?> dst) { static boolean canConvertArgument(Class<?> src, Class<?> dst) {
// ? Retool this logic to use RETYPE_ONLY, CHECK_CAST, etc., as opcodes, // ? Retool this logic to use RETYPE_ONLY, CHECK_CAST, etc., as opcodes,
// so we don't need to repeat so much decision making. // so we don't need to repeat so much decision making.
if (VerifyType.isNullConversion(src, dst)) { if (VerifyType.isNullConversion(src, dst)) {
@ -118,16 +113,13 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* the JVM supports ricochet adapters). * the JVM supports ricochet adapters).
* The argument conversions allowed are casting, unboxing, * The argument conversions allowed are casting, unboxing,
* integral widening or narrowing, and floating point widening or narrowing. * integral widening or narrowing, and floating point widening or narrowing.
* @param token access check
* @param newType required call type * @param newType required call type
* @param target original method handle * @param target original method handle
* @return an adapter to the original handle with the desired new type, * @return an adapter to the original handle with the desired new type,
* or the original target if the types are already identical * or the original target if the types are already identical
* or null if the adaptation cannot be made * or null if the adaptation cannot be made
*/ */
public static MethodHandle makePairwiseConvert(Access token, static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target) {
MethodType newType, MethodHandle target) {
Access.check(token);
MethodType oldType = target.type(); MethodType oldType = target.type();
if (newType == oldType) return target; if (newType == oldType) return target;
@ -170,9 +162,9 @@ public class AdapterMethodHandle extends BoundMethodHandle {
// It parallels canConvertArgument() above. // It parallels canConvertArgument() above.
if (src.isPrimitive()) { if (src.isPrimitive()) {
if (dst.isPrimitive()) { if (dst.isPrimitive()) {
adapter = makePrimCast(token, midType, adapter, i, dst); adapter = makePrimCast(midType, adapter, i, dst);
} else { } else {
adapter = makeBoxArgument(token, midType, adapter, i, dst); adapter = makeBoxArgument(midType, adapter, i, dst);
} }
} else { } else {
if (dst.isPrimitive()) { if (dst.isPrimitive()) {
@ -182,13 +174,13 @@ public class AdapterMethodHandle extends BoundMethodHandle {
// conversions supported by reflect.Method.invoke. // conversions supported by reflect.Method.invoke.
// Those conversions require a big nest of if/then/else logic, // Those conversions require a big nest of if/then/else logic,
// which we prefer to make a user responsibility. // which we prefer to make a user responsibility.
adapter = makeUnboxArgument(token, midType, adapter, i, dst); adapter = makeUnboxArgument(midType, adapter, i, dst);
} else { } else {
// Simple reference conversion. // Simple reference conversion.
// Note: Do not check for a class hierarchy relation // Note: Do not check for a class hierarchy relation
// between src and dst. In all cases a 'null' argument // between src and dst. In all cases a 'null' argument
// will pass the cast conversion. // will pass the cast conversion.
adapter = makeCheckCast(token, midType, adapter, i, dst); adapter = makeCheckCast(midType, adapter, i, dst);
} }
} }
assert(adapter != null); assert(adapter != null);
@ -196,7 +188,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
} }
if (adapter.type() != newType) { if (adapter.type() != newType) {
// Only trivial conversions remain. // Only trivial conversions remain.
adapter = makeRetypeOnly(IMPL_TOKEN, newType, adapter); adapter = makeRetypeOnly(newType, adapter);
assert(adapter != null); assert(adapter != null);
// Actually, that's because there were no non-trivial ones: // Actually, that's because there were no non-trivial ones:
assert(lastConv == -1); assert(lastConv == -1);
@ -208,7 +200,6 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** /**
* Create a JVM-level adapter method handle to permute the arguments * Create a JVM-level adapter method handle to permute the arguments
* of the given method. * of the given method.
* @param token access check
* @param newType required call type * @param newType required call type
* @param target original method handle * @param target original method handle
* @param argumentMap for each target argument, position of its source in newType * @param argumentMap for each target argument, position of its source in newType
@ -218,8 +209,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* @throws IllegalArgumentException if the adaptation cannot be made * @throws IllegalArgumentException if the adaptation cannot be made
* directly by a JVM-level adapter, without help from Java code * directly by a JVM-level adapter, without help from Java code
*/ */
public static MethodHandle makePermutation(Access token, static MethodHandle makePermutation(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int[] argumentMap) { int[] argumentMap) {
MethodType oldType = target.type(); MethodType oldType = target.type();
boolean nullPermutation = true; boolean nullPermutation = true;
@ -234,7 +224,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
if (argumentMap.length != oldType.parameterCount()) if (argumentMap.length != oldType.parameterCount())
throw newIllegalArgumentException("bad permutation: "+Arrays.toString(argumentMap)); throw newIllegalArgumentException("bad permutation: "+Arrays.toString(argumentMap));
if (nullPermutation) { if (nullPermutation) {
MethodHandle res = makePairwiseConvert(token, newType, target); MethodHandle res = makePairwiseConvert(newType, target);
// well, that was easy // well, that was easy
if (res == null) if (res == null)
throw newIllegalArgumentException("cannot convert pairwise: "+newType); throw newIllegalArgumentException("cannot convert pairwise: "+newType);
@ -435,7 +425,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
} }
/** Can a retyping adapter (alone) validly convert the target to newType? */ /** Can a retyping adapter (alone) validly convert the target to newType? */
public static boolean canRetypeOnly(MethodType newType, MethodType targetType) { static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
return canRetype(newType, targetType, false); return canRetype(newType, targetType, false);
} }
/** Can a retyping adapter (alone) convert the target to newType? /** Can a retyping adapter (alone) convert the target to newType?
@ -444,7 +434,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* reference conversions on return. This last feature requires that the * reference conversions on return. This last feature requires that the
* caller be trusted, and perform explicit cast conversions on return values. * caller be trusted, and perform explicit cast conversions on return values.
*/ */
public static boolean canRetypeRaw(MethodType newType, MethodType targetType) { static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
return canRetype(newType, targetType, true); return canRetype(newType, targetType, true);
} }
static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) { static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
@ -459,17 +449,13 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* Allows unchecked argument conversions pairwise, if they are safe. * Allows unchecked argument conversions pairwise, if they are safe.
* Returns null if not possible. * Returns null if not possible.
*/ */
public static MethodHandle makeRetypeOnly(Access token, static MethodHandle makeRetypeOnly(MethodType newType, MethodHandle target) {
MethodType newType, MethodHandle target) { return makeRetype(newType, target, false);
return makeRetype(token, newType, target, false);
} }
public static MethodHandle makeRetypeRaw(Access token, static MethodHandle makeRetypeRaw(MethodType newType, MethodHandle target) {
MethodType newType, MethodHandle target) { return makeRetype(newType, target, true);
return makeRetype(token, newType, target, true);
} }
static MethodHandle makeRetype(Access token, static MethodHandle makeRetype(MethodType newType, MethodHandle target, boolean raw) {
MethodType newType, MethodHandle target, boolean raw) {
Access.check(token);
MethodType oldType = target.type(); MethodType oldType = target.type();
if (oldType == newType) return target; if (oldType == newType) return target;
if (!canRetype(newType, oldType, raw)) if (!canRetype(newType, oldType, raw))
@ -478,9 +464,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY)); return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
} }
static MethodHandle makeVarargsCollector(Access token, static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
MethodHandle target, Class<?> arrayType) {
Access.check(token);
return new AsVarargsCollector(target, arrayType); return new AsVarargsCollector(target, arrayType);
} }
@ -526,6 +510,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return collector.asType(newType); return collector.asType(newType);
} }
@Override
public MethodHandle asVarargsCollector(Class<?> arrayType) { public MethodHandle asVarargsCollector(Class<?> arrayType) {
MethodType type = this.type(); MethodType type = this.type();
if (type.parameterType(type.parameterCount()-1) == arrayType) if (type.parameterType(type.parameterCount()-1) == arrayType)
@ -537,7 +522,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Can a checkcast adapter validly convert the target to newType? /** Can a checkcast adapter validly convert the target to newType?
* The JVM supports all kind of reference casts, even silly ones. * The JVM supports all kind of reference casts, even silly ones.
*/ */
public static boolean canCheckCast(MethodType newType, MethodType targetType, static boolean canCheckCast(MethodType newType, MethodType targetType,
int arg, Class<?> castType) { int arg, Class<?> castType) {
if (!convOpSupported(OP_CHECK_CAST)) return false; if (!convOpSupported(OP_CHECK_CAST)) return false;
Class<?> src = newType.parameterType(arg); Class<?> src = newType.parameterType(arg);
@ -549,7 +534,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return (diff == arg+1); // arg is sole non-trivial diff return (diff == arg+1); // arg is sole non-trivial diff
} }
/** Can an primitive conversion adapter validly convert src to dst? */ /** Can an primitive conversion adapter validly convert src to dst? */
public static boolean canCheckCast(Class<?> src, Class<?> dst) { static boolean canCheckCast(Class<?> src, Class<?> dst) {
return (!src.isPrimitive() && !dst.isPrimitive()); return (!src.isPrimitive() && !dst.isPrimitive());
} }
@ -558,10 +543,8 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* with a null conversion to the corresponding target parameter. * with a null conversion to the corresponding target parameter.
* Return null if this cannot be done. * Return null if this cannot be done.
*/ */
public static MethodHandle makeCheckCast(Access token, static MethodHandle makeCheckCast(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int arg, Class<?> castType) { int arg, Class<?> castType) {
Access.check(token);
if (!canCheckCast(newType, target.type(), arg, castType)) if (!canCheckCast(newType, target.type(), arg, castType))
return null; return null;
long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT); long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT);
@ -572,7 +555,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* The JVM currently supports all conversions except those between * The JVM currently supports all conversions except those between
* floating and integral types. * floating and integral types.
*/ */
public static boolean canPrimCast(MethodType newType, MethodType targetType, static boolean canPrimCast(MethodType newType, MethodType targetType,
int arg, Class<?> convType) { int arg, Class<?> convType) {
if (!convOpSupported(OP_PRIM_TO_PRIM)) return false; if (!convOpSupported(OP_PRIM_TO_PRIM)) return false;
Class<?> src = newType.parameterType(arg); Class<?> src = newType.parameterType(arg);
@ -584,7 +567,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return (diff == arg+1); // arg is sole non-trivial diff return (diff == arg+1); // arg is sole non-trivial diff
} }
/** Can an primitive conversion adapter validly convert src to dst? */ /** Can an primitive conversion adapter validly convert src to dst? */
public static boolean canPrimCast(Class<?> src, Class<?> dst) { static boolean canPrimCast(Class<?> src, Class<?> dst) {
if (src == dst || !src.isPrimitive() || !dst.isPrimitive()) { if (src == dst || !src.isPrimitive() || !dst.isPrimitive()) {
return false; return false;
} else if (Wrapper.forPrimitiveType(dst).isFloating()) { } else if (Wrapper.forPrimitiveType(dst).isFloating()) {
@ -604,10 +587,8 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* with a null conversion to the corresponding target parameter. * with a null conversion to the corresponding target parameter.
* Return null if this cannot be done. * Return null if this cannot be done.
*/ */
public static MethodHandle makePrimCast(Access token, static MethodHandle makePrimCast(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int arg, Class<?> convType) { int arg, Class<?> convType) {
Access.check(token);
MethodType oldType = target.type(); MethodType oldType = target.type();
if (!canPrimCast(newType, oldType, arg, convType)) if (!canPrimCast(newType, oldType, arg, convType))
return null; return null;
@ -620,7 +601,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* The JVM currently supports all kinds of casting and unboxing. * The JVM currently supports all kinds of casting and unboxing.
* The convType is the unboxed type; it can be either a primitive or wrapper. * The convType is the unboxed type; it can be either a primitive or wrapper.
*/ */
public static boolean canUnboxArgument(MethodType newType, MethodType targetType, static boolean canUnboxArgument(MethodType newType, MethodType targetType,
int arg, Class<?> convType) { int arg, Class<?> convType) {
if (!convOpSupported(OP_REF_TO_PRIM)) return false; if (!convOpSupported(OP_REF_TO_PRIM)) return false;
Class<?> src = newType.parameterType(arg); Class<?> src = newType.parameterType(arg);
@ -635,15 +616,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return (diff == arg+1); // arg is sole non-trivial diff return (diff == arg+1); // arg is sole non-trivial diff
} }
/** Can an primitive unboxing adapter validly convert src to dst? */ /** Can an primitive unboxing adapter validly convert src to dst? */
public static boolean canUnboxArgument(Class<?> src, Class<?> dst) { static boolean canUnboxArgument(Class<?> src, Class<?> dst) {
return (!src.isPrimitive() && Wrapper.asPrimitiveType(dst).isPrimitive()); return (!src.isPrimitive() && Wrapper.asPrimitiveType(dst).isPrimitive());
} }
/** Factory method: Unbox the given argument. /** Factory method: Unbox the given argument.
* Return null if this cannot be done. * Return null if this cannot be done.
*/ */
public static MethodHandle makeUnboxArgument(Access token, static MethodHandle makeUnboxArgument(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int arg, Class<?> convType) { int arg, Class<?> convType) {
MethodType oldType = target.type(); MethodType oldType = target.type();
Class<?> src = newType.parameterType(arg); Class<?> src = newType.parameterType(arg);
@ -659,11 +639,11 @@ public class AdapterMethodHandle extends BoundMethodHandle {
MethodHandle adapter = new AdapterMethodHandle(target, castDone, conv, boxType); MethodHandle adapter = new AdapterMethodHandle(target, castDone, conv, boxType);
if (castDone == newType) if (castDone == newType)
return adapter; return adapter;
return makeCheckCast(token, newType, adapter, arg, boxType); return makeCheckCast(newType, adapter, arg, boxType);
} }
/** Can an primitive boxing adapter validly convert src to dst? */ /** Can an primitive boxing adapter validly convert src to dst? */
public static boolean canBoxArgument(Class<?> src, Class<?> dst) { static boolean canBoxArgument(Class<?> src, Class<?> dst) {
if (!convOpSupported(OP_PRIM_TO_REF)) return false; if (!convOpSupported(OP_PRIM_TO_REF)) return false;
throw new UnsupportedOperationException("NYI"); throw new UnsupportedOperationException("NYI");
} }
@ -671,15 +651,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Factory method: Unbox the given argument. /** Factory method: Unbox the given argument.
* Return null if this cannot be done. * Return null if this cannot be done.
*/ */
public static MethodHandle makeBoxArgument(Access token, static MethodHandle makeBoxArgument(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int arg, Class<?> convType) { int arg, Class<?> convType) {
// this is difficult to do in the JVM because it must GC // this is difficult to do in the JVM because it must GC
return null; return null;
} }
/** Can an adapter simply drop arguments to convert the target to newType? */ /** Can an adapter simply drop arguments to convert the target to newType? */
public static boolean canDropArguments(MethodType newType, MethodType targetType, static boolean canDropArguments(MethodType newType, MethodType targetType,
int dropArgPos, int dropArgCount) { int dropArgPos, int dropArgCount) {
if (dropArgCount == 0) if (dropArgCount == 0)
return canRetypeOnly(newType, targetType); return canRetypeOnly(newType, targetType);
@ -706,12 +685,10 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* Allow unchecked retyping of remaining arguments, pairwise. * Allow unchecked retyping of remaining arguments, pairwise.
* Return null if this is not possible. * Return null if this is not possible.
*/ */
public static MethodHandle makeDropArguments(Access token, static MethodHandle makeDropArguments(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int dropArgPos, int dropArgCount) { int dropArgPos, int dropArgCount) {
Access.check(token);
if (dropArgCount == 0) if (dropArgCount == 0)
return makeRetypeOnly(IMPL_TOKEN, newType, target); return makeRetypeOnly(newType, target);
if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount)) if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount))
return null; return null;
// in arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ] // in arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
@ -727,7 +704,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
} }
/** Can an adapter duplicate an argument to convert the target to newType? */ /** Can an adapter duplicate an argument to convert the target to newType? */
public static boolean canDupArguments(MethodType newType, MethodType targetType, static boolean canDupArguments(MethodType newType, MethodType targetType,
int dupArgPos, int dupArgCount) { int dupArgPos, int dupArgCount) {
if (!convOpSupported(OP_DUP_ARGS)) return false; if (!convOpSupported(OP_DUP_ARGS)) return false;
if (diffReturnTypes(newType, targetType, false) != 0) if (diffReturnTypes(newType, targetType, false) != 0)
@ -749,10 +726,8 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Factory method: Duplicate the selected argument. /** Factory method: Duplicate the selected argument.
* Return null if this is not possible. * Return null if this is not possible.
*/ */
public static MethodHandle makeDupArguments(Access token, static MethodHandle makeDupArguments(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int dupArgPos, int dupArgCount) { int dupArgPos, int dupArgCount) {
Access.check(token);
if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount)) if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount))
return null; return null;
if (dupArgCount == 0) if (dupArgCount == 0)
@ -769,7 +744,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
} }
/** Can an adapter swap two arguments to convert the target to newType? */ /** Can an adapter swap two arguments to convert the target to newType? */
public static boolean canSwapArguments(MethodType newType, MethodType targetType, static boolean canSwapArguments(MethodType newType, MethodType targetType,
int swapArg1, int swapArg2) { int swapArg1, int swapArg2) {
if (!convOpSupported(OP_SWAP_ARGS)) return false; if (!convOpSupported(OP_SWAP_ARGS)) return false;
if (diffReturnTypes(newType, targetType, false) != 0) if (diffReturnTypes(newType, targetType, false) != 0)
@ -796,10 +771,8 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Factory method: Swap the selected arguments. /** Factory method: Swap the selected arguments.
* Return null if this is not possible. * Return null if this is not possible.
*/ */
public static MethodHandle makeSwapArguments(Access token, static MethodHandle makeSwapArguments(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int swapArg1, int swapArg2) { int swapArg1, int swapArg2) {
Access.check(token);
if (swapArg1 == swapArg2) if (swapArg1 == swapArg2)
return target; return target;
if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; } if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; }
@ -829,7 +802,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
final static int MAX_ARG_ROTATION = 1; final static int MAX_ARG_ROTATION = 1;
/** Can an adapter rotate arguments to convert the target to newType? */ /** Can an adapter rotate arguments to convert the target to newType? */
public static boolean canRotateArguments(MethodType newType, MethodType targetType, static boolean canRotateArguments(MethodType newType, MethodType targetType,
int firstArg, int argCount, int rotateBy) { int firstArg, int argCount, int rotateBy) {
if (!convOpSupported(OP_ROT_ARGS)) return false; if (!convOpSupported(OP_ROT_ARGS)) return false;
if (argCount <= 2) return false; // must be a swap, not a rotate if (argCount <= 2) return false; // must be a swap, not a rotate
@ -861,10 +834,8 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Factory method: Rotate the selected argument range. /** Factory method: Rotate the selected argument range.
* Return null if this is not possible. * Return null if this is not possible.
*/ */
public static MethodHandle makeRotateArguments(Access token, static MethodHandle makeRotateArguments(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
int firstArg, int argCount, int rotateBy) { int firstArg, int argCount, int rotateBy) {
Access.check(token);
rotateBy = positiveRotation(argCount, rotateBy); rotateBy = positiveRotation(argCount, rotateBy);
if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy)) if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
return null; return null;
@ -904,7 +875,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
} }
/** Can an adapter spread an argument to convert the target to newType? */ /** Can an adapter spread an argument to convert the target to newType? */
public static boolean canSpreadArguments(MethodType newType, MethodType targetType, static boolean canSpreadArguments(MethodType newType, MethodType targetType,
Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) { Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
if (!convOpSupported(OP_SPREAD_ARGS)) return false; if (!convOpSupported(OP_SPREAD_ARGS)) return false;
if (diffReturnTypes(newType, targetType, false) != 0) if (diffReturnTypes(newType, targetType, false) != 0)
@ -937,10 +908,8 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Factory method: Spread selected argument. */ /** Factory method: Spread selected argument. */
public static MethodHandle makeSpreadArguments(Access token, static MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target,
MethodType newType, MethodHandle target,
Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) { Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
Access.check(token);
MethodType targetType = target.type(); MethodType targetType = target.type();
if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount)) if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
return null; return null;
@ -962,7 +931,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
@Override @Override
public String toString() { public String toString() {
return MethodHandleImpl.getNameString(IMPL_TOKEN, nonAdapter((MethodHandle)vmtarget), this); return getNameString(nonAdapter((MethodHandle)vmtarget), this);
} }
private static MethodHandle nonAdapter(MethodHandle mh) { private static MethodHandle nonAdapter(MethodHandle mh) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,15 +23,11 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import sun.dyn.util.VerifyType; import sun.invoke.util.VerifyType;
import sun.dyn.util.Wrapper; import sun.invoke.util.Wrapper;
import java.dyn.*; import static java.lang.invoke.MethodHandleStatics.*;
import java.util.List;
import sun.dyn.MethodHandleNatives.Constants;
import static sun.dyn.MethodHandleImpl.IMPL_LOOKUP;
import static sun.dyn.MemberName.newIllegalArgumentException;
/** /**
* The flavor of method handle which emulates an invoke instruction * The flavor of method handle which emulates an invoke instruction
@ -39,37 +35,29 @@ import static sun.dyn.MemberName.newIllegalArgumentException;
* when the handle is created, not when it is invoked. * when the handle is created, not when it is invoked.
* @author jrose * @author jrose
*/ */
public class BoundMethodHandle extends MethodHandle { class BoundMethodHandle extends MethodHandle {
//MethodHandle vmtarget; // next BMH or final DMH or methodOop //MethodHandle vmtarget; // next BMH or final DMH or methodOop
private final Object argument; // argument to insert private final Object argument; // argument to insert
private final int vmargslot; // position at which it is inserted private final int vmargslot; // position at which it is inserted
private static final Access IMPL_TOKEN = Access.getToken();
private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
// Constructors in this class *must* be package scoped or private. // Constructors in this class *must* be package scoped or private.
/** Bind a direct MH to its receiver (or first ref. argument). /** Bind a direct MH to its receiver (or first ref. argument).
* The JVM will pre-dispatch the MH if it is not already static. * The JVM will pre-dispatch the MH if it is not already static.
*/ */
BoundMethodHandle(DirectMethodHandle mh, Object argument) { /*non-public*/ BoundMethodHandle(DirectMethodHandle mh, Object argument) {
super(Access.TOKEN, mh.type().dropParameterTypes(0, 1)); super(mh.type().dropParameterTypes(0, 1));
// check the type now, once for all: // check the type now, once for all:
this.argument = checkReferenceArgument(argument, mh, 0); this.argument = checkReferenceArgument(argument, mh, 0);
this.vmargslot = this.type().parameterSlotCount(); this.vmargslot = this.type().parameterSlotCount();
if (MethodHandleNatives.JVM_SUPPORT) { initTarget(mh, 0);
this.vmtarget = null; // maybe updated by JVM
MethodHandleNatives.init(this, mh, 0);
} else {
this.vmtarget = mh;
}
} }
/** Insert an argument into an arbitrary method handle. /** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc. * If argnum is zero, inserts the first argument, etc.
* The argument type must be a reference. * The argument type must be a reference.
*/ */
BoundMethodHandle(MethodHandle mh, Object argument, int argnum) { /*non-public*/ BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
this(mh.type().dropParameterTypes(argnum, argnum+1), this(mh.type().dropParameterTypes(argnum, argnum+1),
mh, argument, argnum); mh, argument, argnum);
} }
@ -77,8 +65,8 @@ public class BoundMethodHandle extends MethodHandle {
/** Insert an argument into an arbitrary method handle. /** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc. * If argnum is zero, inserts the first argument, etc.
*/ */
BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) { /*non-public*/ BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) {
super(Access.TOKEN, type); super(type);
if (mh.type().parameterType(argnum).isPrimitive()) if (mh.type().parameterType(argnum).isPrimitive())
this.argument = bindPrimitiveArgument(argument, mh, argnum); this.argument = bindPrimitiveArgument(argument, mh, argnum);
else { else {
@ -89,18 +77,14 @@ public class BoundMethodHandle extends MethodHandle {
} }
private void initTarget(MethodHandle mh, int argnum) { private void initTarget(MethodHandle mh, int argnum) {
if (MethodHandleNatives.JVM_SUPPORT) { //this.vmtarget = mh; // maybe updated by JVM
this.vmtarget = null; // maybe updated by JVM MethodHandleNatives.init(this, mh, argnum);
MethodHandleNatives.init(this, mh, argnum);
} else {
this.vmtarget = mh;
}
} }
/** For the AdapterMethodHandle subclass. /** For the AdapterMethodHandle subclass.
*/ */
BoundMethodHandle(MethodType type, Object argument, int vmargslot) { /*non-public*/ BoundMethodHandle(MethodType type, Object argument, int vmargslot) {
super(Access.TOKEN, type); super(type);
this.argument = argument; this.argument = argument;
this.vmargslot = vmargslot; this.vmargslot = vmargslot;
assert(this instanceof AdapterMethodHandle); assert(this instanceof AdapterMethodHandle);
@ -112,8 +96,8 @@ public class BoundMethodHandle extends MethodHandle {
* same as {@code entryPoint}, except that the first argument * same as {@code entryPoint}, except that the first argument
* type will be dropped. * type will be dropped.
*/ */
protected BoundMethodHandle(Access token, MethodHandle entryPoint) { /*non-public*/ BoundMethodHandle(MethodHandle entryPoint) {
super(token, entryPoint.type().dropParameterTypes(0, 1)); super(entryPoint.type().dropParameterTypes(0, 1));
this.argument = this; // kludge; get rid of this.argument = this; // kludge; get rid of
this.vmargslot = this.type().parameterSlotDepth(0); this.vmargslot = this.type().parameterSlotDepth(0);
initTarget(entryPoint, 0); initTarget(entryPoint, 0);
@ -172,7 +156,7 @@ public class BoundMethodHandle extends MethodHandle {
@Override @Override
public String toString() { public String toString() {
return MethodHandleImpl.addTypeString(baseName(), this); return addTypeString(baseName(), this);
} }
/** Component of toString() before the type string. */ /** Component of toString() before the type string. */

View File

@ -23,12 +23,12 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
import sun.dyn.*; import sun.invoke.empty.Empty;
import sun.dyn.empty.Empty;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import java.util.Collection; import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* A {@code CallSite} is a holder for a variable {@link MethodHandle}, * A {@code CallSite} is a holder for a variable {@link MethodHandle},
@ -85,7 +85,6 @@ private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String nam
*/ */
abstract abstract
public class CallSite { public class CallSite {
private static final Access IMPL_TOKEN = Access.getToken();
static { MethodHandleImpl.initStatics(); } static { MethodHandleImpl.initStatics(); }
// Fields used only by the JVM. Do not use or change. // Fields used only by the JVM. Do not use or change.
@ -96,9 +95,6 @@ public class CallSite {
/*package-private*/ /*package-private*/
MethodHandle target; MethodHandle target;
// Remove this field for PFD and delete deprecated methods:
private MemberName calleeNameRemoveForPFD;
/** /**
* Make a blank call site object with the given method type. * Make a blank call site object with the given method type.
* An initial target method is supplied which will throw * An initial target method is supplied which will throw
@ -111,7 +107,7 @@ public class CallSite {
*/ */
/*package-private*/ /*package-private*/
CallSite(MethodType type) { CallSite(MethodType type) {
target = MethodHandles.invokers(type).uninitializedCallSite(); target = type.invokers().uninitializedCallSite();
} }
/** /**
@ -145,7 +141,7 @@ public class CallSite {
int callerBCI) { int callerBCI) {
if (this.vmmethod != null) { if (this.vmmethod != null) {
// FIXME // FIXME
throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction"); throw new BootstrapMethodError("call site has already been linked to an invokedynamic instruction");
} }
if (!this.type().equals(type)) { if (!this.type().equals(type)) {
throw wrongTargetType(target, type); throw wrongTargetType(target, type);
@ -202,7 +198,7 @@ public class CallSite {
} }
/** /**
* Produce a method handle equivalent to an invokedynamic instruction * Produces a method handle equivalent to an invokedynamic instruction
* which has been linked to this call site. * which has been linked to this call site.
* <p> * <p>
* This method is equivalent to the following code: * This method is equivalent to the following code:
@ -218,7 +214,7 @@ public class CallSite {
public abstract MethodHandle dynamicInvoker(); public abstract MethodHandle dynamicInvoker();
/*non-public*/ MethodHandle makeDynamicInvoker() { /*non-public*/ MethodHandle makeDynamicInvoker() {
MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, GET_TARGET, this); MethodHandle getTarget = MethodHandleImpl.bindReceiver(GET_TARGET, this);
MethodHandle invoker = MethodHandles.exactInvoker(this.type()); MethodHandle invoker = MethodHandles.exactInvoker(this.type());
return MethodHandles.foldArguments(invoker, getTarget); return MethodHandles.foldArguments(invoker, getTarget);
} }
@ -226,7 +222,7 @@ public class CallSite {
private static final MethodHandle GET_TARGET; private static final MethodHandle GET_TARGET;
static { static {
try { try {
GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP. GET_TARGET = IMPL_LOOKUP.
findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class)); findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
} catch (ReflectiveOperationException ignore) { } catch (ReflectiveOperationException ignore) {
throw new InternalError(); throw new InternalError();
@ -252,7 +248,6 @@ public class CallSite {
/*package-private*/ /*package-private*/
void setTargetNormal(MethodHandle newTarget) { void setTargetNormal(MethodHandle newTarget) {
target = newTarget; target = newTarget;
//CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
} }
/*package-private*/ /*package-private*/
MethodHandle getTargetVolatile() { MethodHandle getTargetVolatile() {
@ -261,6 +256,68 @@ public class CallSite {
/*package-private*/ /*package-private*/
void setTargetVolatile(MethodHandle newTarget) { void setTargetVolatile(MethodHandle newTarget) {
unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget); unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget);
//CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget); }
// this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
static CallSite makeSite(MethodHandle bootstrapMethod,
// Callee information:
String name, MethodType type,
// Extra arguments for BSM, if any:
Object info,
// Caller information:
MemberName callerMethod, int callerBCI) {
Class<?> callerClass = callerMethod.getDeclaringClass();
Object caller = IMPL_LOOKUP.in(callerClass);
CallSite site;
try {
Object binding;
info = maybeReBox(info);
if (info == null) {
binding = bootstrapMethod.invokeGeneric(caller, name, type);
} else if (!info.getClass().isArray()) {
binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
} else {
Object[] argv = (Object[]) info;
maybeReBoxElements(argv);
if (3 + argv.length > 255)
throw new BootstrapMethodError("too many bootstrap method arguments");
MethodType bsmType = bootstrapMethod.type();
if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
binding = bootstrapMethod.invokeGeneric(caller, name, type, argv);
else
binding = MethodHandles.spreadInvoker(bsmType, 3)
.invokeGeneric(bootstrapMethod, caller, name, type, argv);
}
//System.out.println("BSM for "+name+type+" => "+binding);
if (binding instanceof CallSite) {
site = (CallSite) binding;
} else {
throw new ClassCastException("bootstrap method failed to produce a CallSite");
}
assert(site.getTarget() != null);
assert(site.getTarget().type().equals(type));
} catch (Throwable ex) {
BootstrapMethodError bex;
if (ex instanceof BootstrapMethodError)
bex = (BootstrapMethodError) ex;
else
bex = new BootstrapMethodError("call site initialization exception", ex);
throw bex;
}
return site;
}
private static Object maybeReBox(Object x) {
if (x instanceof Integer) {
int xi = (int) x;
if (xi == (byte) xi)
x = xi; // must rebox; see JLS 5.1.7
}
return x;
}
private static void maybeReBoxElements(Object[] xa) {
for (int i = 0; i < xa.length; i++) {
xa[i] = maybeReBox(xa[i]);
}
} }
} }

View File

@ -23,7 +23,7 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
/** /**
* A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed. * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,10 +23,9 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static sun.dyn.MethodHandleNatives.Constants.*;
/** /**
* The flavor of method handle which emulates invokespecial or invokestatic. * The flavor of method handle which emulates invokespecial or invokestatic.
@ -39,7 +38,7 @@ class DirectMethodHandle extends MethodHandle {
// Constructors in this class *must* be package scoped or private. // Constructors in this class *must* be package scoped or private.
DirectMethodHandle(MethodType mtype, MemberName m, boolean doDispatch, Class<?> lookupClass) { DirectMethodHandle(MethodType mtype, MemberName m, boolean doDispatch, Class<?> lookupClass) {
super(Access.TOKEN, mtype); super(mtype);
assert(m.isMethod() || !doDispatch && m.isConstructor()); assert(m.isMethod() || !doDispatch && m.isConstructor());
if (!m.isResolved()) if (!m.isResolved())

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,11 +23,11 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import static sun.dyn.MemberName.newIllegalArgumentException; import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* These adapters apply arbitrary conversions to arguments * These adapters apply arbitrary conversions to arguments
@ -123,7 +123,7 @@ class FilterGeneric {
MethodType entryType = entryType(kind, pos, filterType, targetType); MethodType entryType = entryType(kind, pos, filterType, targetType);
if (entryType.generic() != entryType) if (entryType.generic() != entryType)
throw newIllegalArgumentException("must be generic: "+entryType); throw newIllegalArgumentException("must be generic: "+entryType);
MethodTypeImpl form = MethodTypeImpl.of(entryType); MethodTypeForm form = entryType.form();
FilterGeneric filterGen = form.filterGeneric; FilterGeneric filterGen = form.filterGeneric;
if (filterGen == null) if (filterGen == null)
form.filterGeneric = filterGen = new FilterGeneric(entryType); form.filterGeneric = filterGen = new FilterGeneric(entryType);
@ -186,7 +186,7 @@ class FilterGeneric {
// see if it has the required invoke method // see if it has the required invoke method
MethodHandle entryPoint = null; MethodHandle entryPoint = null;
try { try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls); entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
} }
if (entryPoint == null) continue; if (entryPoint == null) continue;
@ -231,7 +231,7 @@ class FilterGeneric {
@Override @Override
public String toString() { public String toString() {
return MethodHandleImpl.addTypeString(target, this); return addTypeString(target, this);
} }
protected boolean isPrototype() { return target == null; } protected boolean isPrototype() { return target == null; }
@ -246,7 +246,7 @@ class FilterGeneric {
protected Adapter(MethodHandle entryPoint, protected Adapter(MethodHandle entryPoint,
MethodHandle filter, MethodHandle target) { MethodHandle filter, MethodHandle target) {
super(Access.TOKEN, entryPoint); super(entryPoint);
this.filter = filter; this.filter = filter;
this.target = target; this.target = target;
} }
@ -256,7 +256,7 @@ class FilterGeneric {
MethodHandle filter, MethodHandle target); MethodHandle filter, MethodHandle target);
// { return new ThisType(entryPoint, filter, target); } // { return new ThisType(entryPoint, filter, target); }
static private final String CLASS_PREFIX; // "sun.dyn.FilterGeneric$" static private final String CLASS_PREFIX; // "java.lang.invoke.FilterGeneric$"
static { static {
String aname = Adapter.class.getName(); String aname = Adapter.class.getName();
String sname = Adapter.class.getSimpleName(); String sname = Adapter.class.getSimpleName();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,10 +23,10 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import static java.lang.invoke.MethodHandleStatics.*;
import static sun.dyn.MemberName.uncaughtException; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* Unary function composition, useful for many small plumbing jobs. * Unary function composition, useful for many small plumbing jobs.
@ -36,7 +36,7 @@ import static sun.dyn.MemberName.uncaughtException;
* final method type is the responsibility of a JVM-level adapter. * final method type is the responsibility of a JVM-level adapter.
* @author jrose * @author jrose
*/ */
public class FilterOneArgument extends BoundMethodHandle { class FilterOneArgument extends BoundMethodHandle {
protected final MethodHandle filter; // Object -> Object protected final MethodHandle filter; // Object -> Object
protected final MethodHandle target; // Object -> Object protected final MethodHandle target; // Object -> Object
@ -54,15 +54,15 @@ public class FilterOneArgument extends BoundMethodHandle {
static { static {
try { try {
INVOKE = INVOKE =
MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke", IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
MethodType.genericMethodType(1)); MethodType.genericMethodType(1));
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
throw uncaughtException(ex); throw uncaughtException(ex);
} }
} }
protected FilterOneArgument(MethodHandle filter, MethodHandle target) { protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
super(Access.TOKEN, INVOKE); super(INVOKE);
this.filter = filter; this.filter = filter;
this.target = target; this.target = target;
} }

View File

@ -23,12 +23,13 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import sun.invoke.util.ValueConversions;
import sun.invoke.util.Wrapper;
import java.lang.reflect.*; import java.lang.reflect.*;
import sun.dyn.util.*; import static java.lang.invoke.MethodHandleStatics.*;
import static sun.dyn.MethodTypeImpl.invokers; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* Adapters which mediate between incoming calls which are generic * Adapters which mediate between incoming calls which are generic
@ -82,8 +83,8 @@ class FromGeneric {
} }
// outgoing primitive arguments will be wrapped; unwrap them // outgoing primitive arguments will be wrapped; unwrap them
MethodType primsAsObj = MethodTypeImpl.of(targetType).primArgsAsBoxes(); MethodType primsAsObj = targetType.form().primArgsAsBoxes();
MethodType objArgsRawRet = MethodTypeImpl.of(primsAsObj).primsAsInts(); MethodType objArgsRawRet = primsAsObj.form().primsAsInts();
if (objArgsRawRet != targetType) if (objArgsRawRet != targetType)
ad = findAdapter(internalType0 = objArgsRawRet); ad = findAdapter(internalType0 = objArgsRawRet);
if (ad == null) { if (ad == null) {
@ -129,16 +130,16 @@ class FromGeneric {
MethodType targetType, MethodType internalType) { MethodType targetType, MethodType internalType) {
// All the adapters we have here have reference-untyped internal calls. // All the adapters we have here have reference-untyped internal calls.
assert(internalType == internalType.erase()); assert(internalType == internalType.erase());
MethodHandle invoker = invokers(targetType).exactInvoker(); MethodHandle invoker = targetType.invokers().exactInvoker();
// cast all narrow reference types, unbox all primitive arguments: // cast all narrow reference types, unbox all primitive arguments:
MethodType fixArgsType = internalType.changeReturnType(targetType.returnType()); MethodType fixArgsType = internalType.changeReturnType(targetType.returnType());
MethodHandle fixArgs = AdapterMethodHandle.convertArguments(Access.TOKEN, MethodHandle fixArgs = MethodHandleImpl.convertArguments(
invoker, Invokers.invokerType(fixArgsType), invoker, Invokers.invokerType(fixArgsType),
invoker.type(), null); invoker.type(), null);
if (fixArgs == null) if (fixArgs == null)
throw new InternalError("bad fixArgs"); throw new InternalError("bad fixArgs");
// reinterpret the calling sequence as raw: // reinterpret the calling sequence as raw:
MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(
Invokers.invokerType(internalType), fixArgs); Invokers.invokerType(internalType), fixArgs);
if (retyper == null) if (retyper == null)
throw new InternalError("bad retyper"); throw new InternalError("bad retyper");
@ -171,7 +172,7 @@ class FromGeneric {
/** Return the adapter information for this type's erasure. */ /** Return the adapter information for this type's erasure. */
static FromGeneric of(MethodType type) { static FromGeneric of(MethodType type) {
MethodTypeImpl form = MethodTypeImpl.of(type); MethodTypeForm form = type.form();
FromGeneric fromGen = form.fromGeneric; FromGeneric fromGen = form.fromGeneric;
if (fromGen == null) if (fromGen == null)
form.fromGeneric = fromGen = new FromGeneric(form.erasedType()); form.fromGeneric = fromGen = new FromGeneric(form.erasedType());
@ -185,7 +186,7 @@ class FromGeneric {
/* Create an adapter that handles spreading calls for the given type. */ /* Create an adapter that handles spreading calls for the given type. */
static Adapter findAdapter(MethodType internalType) { static Adapter findAdapter(MethodType internalType) {
MethodType entryType = internalType.generic(); MethodType entryType = internalType.generic();
MethodTypeImpl form = MethodTypeImpl.of(internalType); MethodTypeForm form = internalType.form();
Class<?> rtype = internalType.returnType(); Class<?> rtype = internalType.returnType();
int argc = form.parameterCount(); int argc = form.parameterCount();
int lac = form.longPrimitiveParameterCount(); int lac = form.longPrimitiveParameterCount();
@ -203,7 +204,7 @@ class FromGeneric {
// see if it has the required invoke method // see if it has the required invoke method
MethodHandle entryPoint = null; MethodHandle entryPoint = null;
try { try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls); entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
} }
if (entryPoint == null) continue; if (entryPoint == null) continue;
@ -257,7 +258,7 @@ class FromGeneric {
@Override @Override
public String toString() { public String toString() {
return MethodHandleImpl.addTypeString(target, this); return addTypeString(target, this);
} }
protected boolean isPrototype() { return target == null; } protected boolean isPrototype() { return target == null; }
@ -272,7 +273,7 @@ class FromGeneric {
protected Adapter(MethodHandle entryPoint, protected Adapter(MethodHandle entryPoint,
MethodHandle invoker, MethodHandle convert, MethodHandle target) { MethodHandle invoker, MethodHandle convert, MethodHandle target) {
super(Access.TOKEN, entryPoint); super(entryPoint);
this.invoker = invoker; this.invoker = invoker;
this.convert = convert; this.convert = convert;
this.target = target; this.target = target;
@ -290,7 +291,7 @@ class FromGeneric {
protected Object convert_F(float result) throws Throwable { return convert.invokeExact(result); } protected Object convert_F(float result) throws Throwable { return convert.invokeExact(result); }
protected Object convert_D(double result) throws Throwable { return convert.invokeExact(result); } protected Object convert_D(double result) throws Throwable { return convert.invokeExact(result); }
static private final String CLASS_PREFIX; // "sun.dyn.FromGeneric$" static private final String CLASS_PREFIX; // "java.lang.invoke.FromGeneric$"
static { static {
String aname = Adapter.class.getName(); String aname = Adapter.class.getName();
String sname = Adapter.class.getSimpleName(); String sname = Adapter.class.getSimpleName();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
/** /**
* This is a place-holder class. Some HotSpot implementations need to see it. * This is a place-holder class. Some HotSpot implementations need to see it.

View File

@ -23,15 +23,13 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import sun.invoke.util.*;
import java.lang.reflect.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
import sun.dyn.util.*;
import static sun.dyn.MethodTypeImpl.invokers;
/** /**
* Adapters which manage MethodHanndle.invokeGeneric calls. * Adapters which manage MethodHandle.invokeGeneric calls.
* The JVM calls one of these when the exact type match fails. * The JVM calls one of these when the exact type match fails.
* @author jrose * @author jrose
*/ */
@ -44,7 +42,8 @@ class InvokeGeneric {
/** Compute and cache information for this adapter, so that it can /** Compute and cache information for this adapter, so that it can
* call out to targets of the erasure-family of the given erased type. * call out to targets of the erasure-family of the given erased type.
*/ */
private InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException { /*non-public*/ InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException {
assert(erasedCallerType.equals(erasedCallerType.erase()));
this.erasedCallerType = erasedCallerType; this.erasedCallerType = erasedCallerType;
this.initialInvoker = makeInitialInvoker(); this.initialInvoker = makeInitialInvoker();
assert initialInvoker.type().equals(erasedCallerType assert initialInvoker.type().equals(erasedCallerType
@ -53,22 +52,13 @@ class InvokeGeneric {
} }
private static MethodHandles.Lookup lookup() { private static MethodHandles.Lookup lookup() {
return MethodHandleImpl.IMPL_LOOKUP; return IMPL_LOOKUP;
} }
/** Return the adapter information for this type's erasure. */ /** Return the adapter information for this type's erasure. */
static MethodHandle genericInvokerOf(MethodType type) { /*non-public*/ static MethodHandle genericInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException {
MethodTypeImpl form = MethodTypeImpl.of(type); InvokeGeneric gen = new InvokeGeneric(erasedCallerType);
MethodHandle genericInvoker = form.genericInvoker; return gen.initialInvoker;
if (genericInvoker == null) {
try {
InvokeGeneric gen = new InvokeGeneric(form.erasedType());
form.genericInvoker = genericInvoker = gen.initialInvoker;
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
return genericInvoker;
} }
private MethodHandle makeInitialInvoker() throws ReflectiveOperationException { private MethodHandle makeInitialInvoker() throws ReflectiveOperationException {
@ -88,7 +78,7 @@ class InvokeGeneric {
private MethodHandle makePostDispatchInvoker() { private MethodHandle makePostDispatchInvoker() {
// Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...). // Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...).
MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS); MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS);
return invokers(invokerType).exactInvoker(); return invokerType.invokers().exactInvoker();
} }
private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) { private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) {
assert(targetInvoker.type().parameterType(0) == MethodHandle.class); assert(targetInvoker.type().parameterType(0) == MethodHandle.class);
@ -112,7 +102,7 @@ class InvokeGeneric {
if (USE_AS_TYPE_PATH || target.isVarargsCollector()) { if (USE_AS_TYPE_PATH || target.isVarargsCollector()) {
MethodHandle newTarget = target.asType(callerType); MethodHandle newTarget = target.asType(callerType);
targetType = callerType; targetType = callerType;
Invokers invokers = MethodTypeImpl.invokers(Access.TOKEN, targetType); Invokers invokers = targetType.invokers();
MethodHandle invoker = invokers.erasedInvokerWithDrops; MethodHandle invoker = invokers.erasedInvokerWithDrops;
if (invoker == null) { if (invoker == null) {
invokers.erasedInvokerWithDrops = invoker = invokers.erasedInvokerWithDrops = invoker =

View File

@ -23,16 +23,16 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import sun.invoke.empty.Empty;
import sun.dyn.empty.Empty; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* Construction and caching of often-used invokers. * Construction and caching of often-used invokers.
* @author jrose * @author jrose
*/ */
public class Invokers { class Invokers {
// exact type (sans leading taget MH) for the outgoing call // exact type (sans leading taget MH) for the outgoing call
private final MethodType targetType; private final MethodType targetType;
@ -60,15 +60,15 @@ public class Invokers {
this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1]; this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
} }
public static MethodType invokerType(MethodType targetType) { /*non-public*/ static MethodType invokerType(MethodType targetType) {
return targetType.insertParameterTypes(0, MethodHandle.class); return targetType.insertParameterTypes(0, MethodHandle.class);
} }
public MethodHandle exactInvoker() { /*non-public*/ MethodHandle exactInvoker() {
MethodHandle invoker = exactInvoker; MethodHandle invoker = exactInvoker;
if (invoker != null) return invoker; if (invoker != null) return invoker;
try { try {
invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invokeExact", targetType); invoker = IMPL_LOOKUP.findVirtual(MethodHandle.class, "invokeExact", targetType);
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
throw new InternalError("JVM cannot find invoker for "+targetType); throw new InternalError("JVM cannot find invoker for "+targetType);
} }
@ -77,7 +77,7 @@ public class Invokers {
return invoker; return invoker;
} }
public MethodHandle genericInvoker() { /*non-public*/ MethodHandle genericInvoker() {
MethodHandle invoker1 = exactInvoker(); MethodHandle invoker1 = exactInvoker();
MethodHandle invoker = genericInvoker; MethodHandle invoker = genericInvoker;
if (invoker != null) return invoker; if (invoker != null) return invoker;
@ -87,7 +87,7 @@ public class Invokers {
return invoker; return invoker;
} }
public MethodHandle erasedInvoker() { /*non-public*/ MethodHandle erasedInvoker() {
MethodHandle invoker1 = exactInvoker(); MethodHandle invoker1 = exactInvoker();
MethodHandle invoker = erasedInvoker; MethodHandle invoker = erasedInvoker;
if (invoker != null) return invoker; if (invoker != null) return invoker;
@ -100,7 +100,7 @@ public class Invokers {
return invoker; return invoker;
} }
public MethodHandle spreadInvoker(int objectArgCount) { /*non-public*/ MethodHandle spreadInvoker(int objectArgCount) {
MethodHandle vaInvoker = spreadInvokers[objectArgCount]; MethodHandle vaInvoker = spreadInvokers[objectArgCount];
if (vaInvoker != null) return vaInvoker; if (vaInvoker != null) return vaInvoker;
MethodHandle gInvoker = genericInvoker(); MethodHandle gInvoker = genericInvoker();
@ -111,12 +111,12 @@ public class Invokers {
private static MethodHandle THROW_UCS = null; private static MethodHandle THROW_UCS = null;
public MethodHandle uninitializedCallSite() { /*non-public*/ MethodHandle uninitializedCallSite() {
MethodHandle invoker = uninitializedCallSite; MethodHandle invoker = uninitializedCallSite;
if (invoker != null) return invoker; if (invoker != null) return invoker;
if (targetType.parameterCount() > 0) { if (targetType.parameterCount() > 0) {
MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount()); MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount());
Invokers invokers0 = MethodTypeImpl.invokers(type0); Invokers invokers0 = type0.invokers();
invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(), invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(),
0, targetType.parameterList()); 0, targetType.parameterList());
assert(invoker.type().equals(targetType)); assert(invoker.type().equals(targetType));
@ -125,14 +125,14 @@ public class Invokers {
} }
if (THROW_UCS == null) { if (THROW_UCS == null) {
try { try {
THROW_UCS = MethodHandleImpl.IMPL_LOOKUP THROW_UCS = IMPL_LOOKUP
.findStatic(CallSite.class, "uninitializedCallSite", .findStatic(CallSite.class, "uninitializedCallSite",
MethodType.methodType(Empty.class)); MethodType.methodType(Empty.class));
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }
invoker = AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, targetType, THROW_UCS); invoker = AdapterMethodHandle.makeRetypeRaw(targetType, THROW_UCS);
assert(invoker.type().equals(targetType)); assert(invoker.type().equals(targetType));
uninitializedCallSite = invoker; uninitializedCallSite = invoker;
return invoker; return invoker;

View File

@ -23,10 +23,9 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import sun.dyn.util.BytecodeDescriptor; import sun.invoke.util.BytecodeDescriptor;
import java.dyn.*;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -37,7 +36,8 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import static sun.dyn.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.*;
/** /**
* A {@code MemberName} is a compact symbolic datum which fully characterizes * A {@code MemberName} is a compact symbolic datum which fully characterizes
@ -66,7 +66,7 @@ import static sun.dyn.MethodHandleNatives.Constants.*;
* and those seven fields omit much of the information in Method. * and those seven fields omit much of the information in Method.
* @author jrose * @author jrose
*/ */
public final class MemberName implements Member, Cloneable { /*non-public*/ final class MemberName implements Member, Cloneable {
private Class<?> clazz; // class in which the method is defined private Class<?> clazz; // class in which the method is defined
private String name; // may be null if not yet materialized private String name; // may be null if not yet materialized
private Object type; // may be null if not yet materialized private Object type; // may be null if not yet materialized
@ -435,7 +435,7 @@ public final class MemberName implements Member, Cloneable {
/** Query whether this member name is resolved to a non-static, non-final method. /** Query whether this member name is resolved to a non-static, non-final method.
*/ */
public boolean hasReceiverTypeDispatch() { public boolean hasReceiverTypeDispatch() {
return (isMethod() && getVMIndex(Access.TOKEN) >= 0); return (isMethod() && getVMIndex() >= 0);
} }
/** Produce a string form of this member name. /** Produce a string form of this member name.
@ -490,59 +490,38 @@ public final class MemberName implements Member, Cloneable {
// Queries to the JVM: // Queries to the JVM:
/** Document? */ /** Document? */
public int getVMIndex(Access token) { /*non-public*/ int getVMIndex() {
Access.check(token);
if (!isResolved()) if (!isResolved())
throw newIllegalStateException("not resolved"); throw newIllegalStateException("not resolved", this);
return vmindex; return vmindex;
} }
// public Object getVMTarget(Access token) { // /*non-public*/ Object getVMTarget() {
// Access.check(token);
// if (!isResolved()) // if (!isResolved())
// throw newIllegalStateException("not resolved"); // throw newIllegalStateException("not resolved", this);
// return vmtarget; // return vmtarget;
// } // }
private RuntimeException newIllegalStateException(String message) {
return new IllegalStateException(message+": "+this);
}
// handy shared exception makers (they simplify the common case code) public IllegalAccessException makeAccessException(String message, Object from) {
public static RuntimeException newIllegalArgumentException(String message) { message = message + ": "+ toString();
return new IllegalArgumentException(message);
}
public static IllegalAccessException newNoAccessException(MemberName name, Object from) {
return newNoAccessException("cannot access", name, from);
}
public static IllegalAccessException newNoAccessException(String message,
MemberName name, Object from) {
message += ": " + name;
if (from != null) message += ", from " + from; if (from != null) message += ", from " + from;
return new IllegalAccessException(message); return new IllegalAccessException(message);
} }
public static ReflectiveOperationException newNoAccessException(MemberName name) { public ReflectiveOperationException makeAccessException(String message) {
if (name.isResolved()) message = message + ": "+ toString();
return new IllegalAccessException(name.toString()); if (isResolved())
else if (name.isConstructor()) return new IllegalAccessException(message);
return new NoSuchMethodException(name.toString()); else if (isConstructor())
else if (name.isMethod()) return new NoSuchMethodException(message);
return new NoSuchMethodException(name.toString()); else if (isMethod())
return new NoSuchMethodException(message);
else else
return new NoSuchFieldException(name.toString()); return new NoSuchFieldException(message);
}
public static Error uncaughtException(Exception ex) {
Error err = new InternalError("uncaught exception");
err.initCause(ex);
return err;
} }
/** Actually making a query requires an access check. */ /** Actually making a query requires an access check. */
public static Factory getFactory(Access token) { /*non-public*/ static Factory getFactory() {
Access.check(token);
return Factory.INSTANCE; return Factory.INSTANCE;
} }
public static Factory getFactory() {
return getFactory(Access.getToken());
}
/** A factory type for resolving member names with the help of the VM. /** A factory type for resolving member names with the help of the VM.
* TBD: Define access-safe public constructors for this factory. * TBD: Define access-safe public constructors for this factory.
*/ */
@ -662,7 +641,7 @@ public final class MemberName implements Member, Cloneable {
MemberName result = resolveOrNull(m, searchSupers, lookupClass); MemberName result = resolveOrNull(m, searchSupers, lookupClass);
if (result != null) if (result != null)
return result; return result;
ReflectiveOperationException ex = newNoAccessException(m); ReflectiveOperationException ex = m.makeAccessException("no access");
if (ex instanceof IllegalAccessException) throw (IllegalAccessException) ex; if (ex instanceof IllegalAccessException) throw (IllegalAccessException) ex;
throw nsmClass.cast(ex); throw nsmClass.cast(ex);
} }

View File

@ -23,15 +23,10 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
//import sun.dyn.*;
import sun.dyn.Access; import static java.lang.invoke.MethodHandleStatics.*;
import sun.dyn.MethodHandleImpl;
import static java.dyn.MethodHandles.invokers; // package-private API
import static sun.dyn.MemberName.newIllegalArgumentException; // utility
/** /**
* A method handle is a typed, directly executable reference to an underlying method, * A method handle is a typed, directly executable reference to an underlying method,
@ -40,14 +35,8 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* These transformations are quite general, and include such patterns as * These transformations are quite general, and include such patterns as
* {@linkplain #asType conversion}, * {@linkplain #asType conversion},
* {@linkplain #bindTo insertion}, * {@linkplain #bindTo insertion},
* {@linkplain java.dyn.MethodHandles#dropArguments deletion}, * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
* and {@linkplain java.dyn.MethodHandles#filterArguments substitution}. * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
* <p>
* <em>Note: The super-class of MethodHandle is Object.
* Any other super-class visible in the Reference Implementation
* will be removed before the Proposed Final Draft.
* Also, the final version will not include any public or
* protected constructors.</em>
* *
* <h3>Method handle contents</h3> * <h3>Method handle contents</h3>
* Method handles are dynamically and strongly typed according to type descriptor. * Method handles are dynamically and strongly typed according to type descriptor.
@ -56,7 +45,7 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* the method handle's own {@linkplain #type method type}. * the method handle's own {@linkplain #type method type}.
* <p> * <p>
* Every method handle reports its type via the {@link #type type} accessor. * Every method handle reports its type via the {@link #type type} accessor.
* This type descriptor is a {@link java.dyn.MethodType MethodType} object, * This type descriptor is a {@link java.lang.invoke.MethodType MethodType} object,
* whose structure is a series of classes, one of which is * whose structure is a series of classes, one of which is
* the return type of the method (or {@code void.class} if none). * the return type of the method (or {@code void.class} if none).
* <p> * <p>
@ -156,7 +145,7 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* This allows a more powerful negotiation of method type * This allows a more powerful negotiation of method type
* between caller and callee. * between caller and callee.
* <p> * <p>
* (Note: The adjusted method handle {@code M2} is not directly observable, * (<em>Note:</em> The adjusted method handle {@code M2} is not directly observable,
* and implementations are therefore not required to materialize it.) * and implementations are therefore not required to materialize it.)
* *
* <h3>Invocation checking</h3> * <h3>Invocation checking</h3>
@ -204,11 +193,11 @@ import static sun.dyn.MemberName.newIllegalArgumentException; // utility
* Java code can create a method handle that directly accesses * Java code can create a method handle that directly accesses
* any method, constructor, or field that is accessible to that code. * any method, constructor, or field that is accessible to that code.
* This is done via a reflective, capability-based API called * This is done via a reflective, capability-based API called
* {@link java.dyn.MethodHandles.Lookup MethodHandles.Lookup} * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
* For example, a static method handle can be obtained * For example, a static method handle can be obtained
* from {@link java.dyn.MethodHandles.Lookup#findStatic Lookup.findStatic}. * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
* There are also conversion methods from Core Reflection API objects, * There are also conversion methods from Core Reflection API objects,
* such as {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}. * such as {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
* <p> * <p>
* Like classes and strings, method handles that correspond to accessible * Like classes and strings, method handles that correspond to accessible
* fields, methods, and constructors can also be represented directly * fields, methods, and constructors can also be represented directly
@ -269,7 +258,7 @@ mh = mh.asType(mt);
x = mh.invokeExact((Object)1, (Object)2, (Object)3); x = mh.invokeExact((Object)1, (Object)2, (Object)3);
// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; // invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
assert(x.equals(java.util.Arrays.asList(1,2,3))); assert(x.equals(java.util.Arrays.asList(1,2,3)));
// mt is { =&gt; int} // mt is int()
mt = MethodType.methodType(int.class); mt = MethodType.methodType(int.class);
mh = lookup.findVirtual(java.util.List.class, "size", mt); mh = lookup.findVirtual(java.util.List.class, "size", mt);
i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3)); i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
@ -325,15 +314,15 @@ mh.invokeExact(System.out, "Hello, world.");
* <p> * <p>
* For the sake of tools (but not as a programming API), the signature polymorphic * For the sake of tools (but not as a programming API), the signature polymorphic
* methods are marked with a private yet standard annotation, * methods are marked with a private yet standard annotation,
* {@code @java.dyn.MethodHandle.PolymorphicSignature}. * {@code @java.lang.invoke.MethodHandle.PolymorphicSignature}.
* The annotation's retention is {@code RUNTIME}, so that all tools can see it. * The annotation's retention is {@code RUNTIME}, so that all tools can see it.
* *
* <h3>Formal rules for processing signature polymorphic methods</h3> * <h3>Formal rules for processing signature polymorphic methods</h3>
* <p> * <p>
* The following methods (and no others) are signature polymorphic: * The following methods (and no others) are signature polymorphic:
* <ul> * <ul>
* <li>{@link java.dyn.MethodHandle#invokeExact MethodHandle.invokeExact} * <li>{@link java.lang.invoke.MethodHandle#invokeExact MethodHandle.invokeExact}
* <li>{@link java.dyn.MethodHandle#invokeGeneric MethodHandle.invokeGeneric} * <li>{@link java.lang.invoke.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
* </ul> * </ul>
* <p> * <p>
* A signature polymorphic method will be declared with the following properties: * A signature polymorphic method will be declared with the following properties:
@ -341,7 +330,7 @@ mh.invokeExact(System.out, "Hello, world.");
* <li>It must be native. * <li>It must be native.
* <li>It must take a single varargs parameter of the form {@code Object...}. * <li>It must take a single varargs parameter of the form {@code Object...}.
* <li>It must produce a return value of type {@code Object}. * <li>It must produce a return value of type {@code Object}.
* <li>It must be contained within the {@code java.dyn} package. * <li>It must be contained within the {@code java.lang.invoke} package.
* </ul> * </ul>
* Because of these requirements, a signature polymorphic method is able to accept * Because of these requirements, a signature polymorphic method is able to accept
* any number and type of actual arguments, and can, with a cast, produce a value of any type. * any number and type of actual arguments, and can, with a cast, produce a value of any type.
@ -354,7 +343,7 @@ mh.invokeExact(System.out, "Hello, world.");
* <p> * <p>
* In an argument position of a method invocation on a signature polymorphic method, * In an argument position of a method invocation on a signature polymorphic method,
* a null literal has type {@code java.lang.Void}, unless cast to a reference type. * a null literal has type {@code java.lang.Void}, unless cast to a reference type.
* (Note: This typing rule allows the null type to have its own encoding in linkage information * (<em>Note:</em> This typing rule allows the null type to have its own encoding in linkage information
* distinct from other types. * distinct from other types.
* <p> * <p>
* The linkage information for the return type is derived from a context-dependent target typing convention. * The linkage information for the return type is derived from a context-dependent target typing convention.
@ -374,12 +363,12 @@ mh.invokeExact(System.out, "Hello, world.");
* and without implicit boxing or unboxing. * and without implicit boxing or unboxing.
* *
* <h3>Interoperation between method handles and the Core Reflection API</h3> * <h3>Interoperation between method handles and the Core Reflection API</h3>
* Using factory methods in the {@link java.dyn.MethodHandles.Lookup Lookup} API, * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup Lookup} API,
* any class member represented by a Core Reflection API object * any class member represented by a Core Reflection API object
* can be converted to a behaviorally equivalent method handle. * can be converted to a behaviorally equivalent method handle.
* For example, a reflective {@link java.lang.reflect.Method Method} can * For example, a reflective {@link java.lang.reflect.Method Method} can
* be converted to a method handle using * be converted to a method handle using
* {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}. * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
* The resulting method handles generally provide more direct and efficient * The resulting method handles generally provide more direct and efficient
* access to the underlying class members. * access to the underlying class members.
* <p> * <p>
@ -398,9 +387,9 @@ mh.invokeExact(System.out, "Hello, world.");
* they will throw {@code UnsupportedOperationException}. * they will throw {@code UnsupportedOperationException}.
* <p> * <p>
* In order to obtain an invoker method for a particular type descriptor, * In order to obtain an invoker method for a particular type descriptor,
* use {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker}, * use {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker},
* or {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker}. * or {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}.
* The {@link java.dyn.MethodHandles.Lookup#findVirtual Lookup.findVirtual} * The {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
* API is also able to return a method handle * API is also able to return a method handle
* to call {@code invokeExact} or {@code invokeGeneric}, * to call {@code invokeExact} or {@code invokeGeneric},
* for any specified type descriptor . * for any specified type descriptor .
@ -436,12 +425,35 @@ mh.invokeExact(System.out, "Hello, world.");
* @see MethodHandles * @see MethodHandles
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
*/ */
public abstract class MethodHandle public abstract class MethodHandle {
// Note: This is an implementation inheritance hack, and will be removed // { JVM internals:
// with a JVM change which moves the required hidden state onto this class.
extends MethodHandleImpl private byte vmentry; // adapter stub or method entry point
{ //private int vmslots; // optionally, hoist type.form.vmslots
private static Access IMPL_TOKEN = Access.getToken(); /*non-public*/ Object vmtarget; // VM-specific, class-specific target value
// TO DO: vmtarget should be invisible to Java, since the JVM puts internal
// managed pointers into it. Making it visible exposes it to debuggers,
// which can cause errors when they treat the pointer as an Object.
// These two dummy fields are present to force 'I' and 'J' signatures
// into this class's constant pool, so they can be transferred
// to vmentry when this class is loaded.
static final int INT_FIELD = 0;
static final long LONG_FIELD = 0;
// vmentry (a void* field) is used *only* by the JVM.
// The JVM adjusts its type to int or long depending on system wordsize.
// Since it is statically typed as neither int nor long, it is impossible
// to use this field from Java bytecode. (Please don't try to, either.)
// The vmentry is an assembly-language stub which is jumped to
// immediately after the method type is verified.
// For a direct MH, this stub loads the vmtarget's entry point
// and jumps to it.
// } End of JVM internals.
static { MethodHandleImpl.initStatics(); } static { MethodHandleImpl.initStatics(); }
// interface MethodHandle<R throws X extends Exception,A...> // interface MethodHandle<R throws X extends Exception,A...>
@ -458,7 +470,7 @@ public abstract class MethodHandle
private MethodType type; private MethodType type;
/** /**
* Report the type of this method handle. * Reports the type of this method handle.
* Every invocation of this method handle via {@code invokeExact} must exactly match this type. * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
* @return the method handle type * @return the method handle type
*/ */
@ -467,39 +479,18 @@ public abstract class MethodHandle
} }
/** /**
* <em>CONSTRUCTOR WILL BE REMOVED FOR PFD:</em> * Package-private constructor for the method handle implementation hierarchy.
* Temporary constructor in early versions of the Reference Implementation. * Method handle inheritance will be contained completely within
* Method handle inheritance (if any) will be contained completely within * the {@code java.lang.invoke} package.
* the {@code java.dyn} package.
*/ */
// The constructor for MethodHandle may only be called by privileged code.
// Subclasses may be in other packages, but must possess
// a token which they obtained from MH with a security check.
// @param token non-null object which proves access permission
// @param type type (permanently assigned) of the new method handle // @param type type (permanently assigned) of the new method handle
protected MethodHandle(Access token, MethodType type) { /*non-public*/ MethodHandle(MethodType type) {
super(token);
Access.check(token);
this.type = type;
}
private void initType(MethodType type) {
type.getClass(); // elicit NPE type.getClass(); // elicit NPE
if (this.type != null) throw new InternalError();
this.type = type; this.type = type;
} }
static {
// This hack allows the implementation package special access to
// the internals of MethodHandle. In particular, the MTImpl has all sorts
// of cached information useful to the implementation code.
MethodHandleImpl.setMethodHandleFriend(IMPL_TOKEN, new MethodHandleImpl.MethodHandleFriend() {
public void initType(MethodHandle mh, MethodType type) { mh.initType(type); }
});
}
/** /**
* Invoke the method handle, allowing any caller type descriptor, but requiring an exact type match. * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
* The type descriptor at the call site of {@code invokeExact} must * The type descriptor at the call site of {@code invokeExact} must
* exactly match this method handle's {@link #type type}. * exactly match this method handle's {@link #type type}.
* No conversions are allowed on arguments or return values. * No conversions are allowed on arguments or return values.
@ -508,7 +499,7 @@ public abstract class MethodHandle
* it will appear as a single native method, taking an object array and returning an object. * it will appear as a single native method, taking an object array and returning an object.
* If this native method is invoked directly via * If this native method is invoked directly via
* {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI, * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
* or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}, * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
* it will throw an {@code UnsupportedOperationException}. * it will throw an {@code UnsupportedOperationException}.
* @throws WrongMethodTypeException if the target's type is not identical with the caller's type descriptor * @throws WrongMethodTypeException if the target's type is not identical with the caller's type descriptor
* @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
@ -516,7 +507,7 @@ public abstract class MethodHandle
public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable; public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
/** /**
* Invoke the method handle, allowing any caller type descriptor, * Invokes the method handle, allowing any caller type descriptor,
* and optionally performing conversions on arguments and return values. * and optionally performing conversions on arguments and return values.
* <p> * <p>
* If the call site type descriptor exactly matches this method handle's {@link #type type}, * If the call site type descriptor exactly matches this method handle's {@link #type type},
@ -542,7 +533,7 @@ public abstract class MethodHandle
* it will appear as a single native method, taking an object array and returning an object. * it will appear as a single native method, taking an object array and returning an object.
* If this native method is invoked directly via * If this native method is invoked directly via
* {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI, * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
* or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}, * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
* it will throw an {@code UnsupportedOperationException}. * it will throw an {@code UnsupportedOperationException}.
* @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's type descriptor * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's type descriptor
* @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
@ -551,7 +542,7 @@ public abstract class MethodHandle
public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable; public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable;
/** /**
* Perform a varargs invocation, passing the arguments in the given array * Performs a varargs invocation, passing the arguments in the given array
* to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
* which mentions only the type {@code Object}, and whose arity is the length * which mentions only the type {@code Object}, and whose arity is the length
* of the argument array. * of the argument array.
@ -608,7 +599,7 @@ public abstract class MethodHandle
return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments); return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
} }
if (argc <= 10) { if (argc <= 10) {
MethodHandle invoker = invokers(type).genericInvoker(); MethodHandle invoker = type.invokers().genericInvoker();
switch (argc) { switch (argc) {
case 0: return invoker.invokeExact(this); case 0: return invoker.invokeExact(this);
case 1: return invoker.invokeExact(this, case 1: return invoker.invokeExact(this,
@ -647,17 +638,34 @@ public abstract class MethodHandle
} }
// more than ten arguments get boxed in a varargs list: // more than ten arguments get boxed in a varargs list:
MethodHandle invoker = invokers(type).spreadInvoker(0); MethodHandle invoker = type.invokers().spreadInvoker(0);
return invoker.invokeExact(this, arguments); return invoker.invokeExact(this, arguments);
} }
/** Equivalent to {@code invokeWithArguments(arguments.toArray())}. */
/**
* Performs a varargs invocation, passing the arguments in the given array
* to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
* which mentions only the type {@code Object}, and whose arity is the length
* of the argument array.
* <p>
* This method is also equivalent to the following code:
* <p><blockquote><pre>
* {@link #invokeWithArguments(Object...) invokeWithArguments}(arguments.toArray())
* </pre></blockquote>
*
* @param arguments the arguments to pass to the target
* @return the result returned by the target
* @throws ClassCastException if an argument cannot be converted by reference casting
* @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
* @throws Throwable anything thrown by the target method invocation
*/
public Object invokeWithArguments(java.util.List<?> arguments) throws Throwable { public Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
return invokeWithArguments(arguments.toArray()); return invokeWithArguments(arguments.toArray());
} }
/** /**
* Produce an adapter method handle which adapts the type of the * Produces an adapter method handle which adapts the type of the
* current method handle to a new type * current method handle to a new type.
* The resulting method handle is guaranteed to report a type * The resulting method handle is guaranteed to report a type
* which is equal to the desired new type. * which is equal to the desired new type.
* <p> * <p>
@ -685,7 +693,7 @@ public abstract class MethodHandle
} }
/** /**
* Make an adapter which accepts a trailing array argument * Makes an adapter which accepts a trailing array argument
* and spreads its elements as positional arguments. * and spreads its elements as positional arguments.
* The new method handle adapts, as its <i>target</i>, * The new method handle adapts, as its <i>target</i>,
* the current method handle. The type of the adapter will be * the current method handle. The type of the adapter will be
@ -733,7 +741,7 @@ public abstract class MethodHandle
} }
/** /**
* Make an adapter which accepts a given number of trailing * Makes an adapter which accepts a given number of trailing
* positional arguments and collects them into an array argument. * positional arguments and collects them into an array argument.
* The new method handle adapts, as its <i>target</i>, * The new method handle adapts, as its <i>target</i>,
* the current method handle. The type of the adapter will be * the current method handle. The type of the adapter will be
@ -784,7 +792,7 @@ public abstract class MethodHandle
} }
/** /**
* Make a <em>variable arity</em> adapter which is able to accept * Makes a <em>variable arity</em> adapter which is able to accept
* any number of trailing positional arguments and collect them * any number of trailing positional arguments and collect them
* into an array argument. * into an array argument.
* <p> * <p>
@ -942,12 +950,12 @@ assert(failed);
} }
/** /**
* Determine if this method handle * Determines if this method handle
* supports {@linkplain #asVarargsCollector variable arity} calls. * supports {@linkplain #asVarargsCollector variable arity} calls.
* Such method handles arise from the following sources: * Such method handles arise from the following sources:
* <ul> * <ul>
* <li>a call to {@linkplain #asVarargsCollector asVarargsCollector} * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
* <li>a call to a {@linkplain java.dyn.MethodHandles.Lookup lookup method} * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
* which resolves to a variable arity Java method or constructor * which resolves to a variable arity Java method or constructor
* <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle} * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
* which resolves to a variable arity Java method or constructor * which resolves to a variable arity Java method or constructor
@ -960,9 +968,9 @@ assert(failed);
} }
/** /**
* Bind a value {@code x} to the first argument of a method handle, without invoking it. * Binds a value {@code x} to the first argument of a method handle, without invoking it.
* The new method handle adapts, as its <i>target</i>, * The new method handle adapts, as its <i>target</i>,
* to the current method handle. * the current method handle by binding it to the given argument.
* The type of the bound handle will be * The type of the bound handle will be
* the same as the type of the target, except that a single leading * the same as the type of the target, except that a single leading
* reference parameter will be omitted. * reference parameter will be omitted.
@ -974,9 +982,12 @@ assert(failed);
* <p> * <p>
* The reference {@code x} must be convertible to the first parameter * The reference {@code x} must be convertible to the first parameter
* type of the target. * type of the target.
* <p>
* (<em>Note:</em> Because method handles are immutable, the target method handle
* retains its original type and behavior.)
* @param x the value to bind to the first argument of the target * @param x the value to bind to the first argument of the target
* @return a new method handle which collects some trailing argument * @return a new method handle which prepends the given value to the incoming
* into an array, before calling the original method handle * argument list, before calling the original method handle
* @throws IllegalArgumentException if the target does not have a * @throws IllegalArgumentException if the target does not have a
* leading parameter type that is a reference type * leading parameter type that is a reference type
* @throws ClassCastException if {@code x} cannot be converted * @throws ClassCastException if {@code x} cannot be converted
@ -984,7 +995,15 @@ assert(failed);
* @see MethodHandles#insertArguments * @see MethodHandles#insertArguments
*/ */
public MethodHandle bindTo(Object x) { public MethodHandle bindTo(Object x) {
return MethodHandles.insertArguments(this, 0, x); Class<?> ptype;
if (type().parameterCount() == 0 ||
(ptype = type().parameterType(0)).isPrimitive())
throw newIllegalArgumentException("no leading reference parameter", x);
x = MethodHandles.checkValue(ptype, x);
// Cf. MethodHandles.insertArguments for the following logic:
MethodHandle bmh = MethodHandleImpl.bindReceiver(this, x);
if (bmh != null) return bmh;
return MethodHandleImpl.bindArgument(this, 0, x);
} }
/** /**
@ -996,14 +1015,14 @@ assert(failed);
* "MethodHandle" + type().toString() * "MethodHandle" + type().toString()
* </pre></blockquote> * </pre></blockquote>
* <p> * <p>
* Note: Future releases of this API may add further information * (<em>Note:</em> Future releases of this API may add further information
* to the string representation. * to the string representation.
* Therefore, the present syntax should not be parsed by applications. * Therefore, the present syntax should not be parsed by applications.)
* *
* @return a string representation of the method handle * @return a string representation of the method handle
*/ */
@Override @Override
public String toString() { public String toString() {
return MethodHandleImpl.getNameString(IMPL_TOKEN, this); return getNameString(this);
} }
} }

View File

@ -23,136 +23,36 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import sun.invoke.util.VerifyType;
import java.dyn.MethodHandles.Lookup;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.dyn.util.VerifyType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import sun.dyn.empty.Empty; import sun.invoke.empty.Empty;
import sun.dyn.util.ValueConversions; import sun.invoke.util.ValueConversions;
import sun.dyn.util.Wrapper; import sun.invoke.util.Wrapper;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import static sun.dyn.MemberName.newIllegalArgumentException; import static java.lang.invoke.MethodHandleStatics.*;
import static sun.dyn.MemberName.newNoAccessException; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
import static sun.dyn.MemberName.uncaughtException;
/** /**
* Base class for method handles, containing JVM-specific fields and logic. * Trusted implementation code for MethodHandle.
* TO DO: It should not be a base class.
* @author jrose * @author jrose
*/ */
public abstract class MethodHandleImpl { /*non-public*/ abstract class MethodHandleImpl {
// Fields which really belong in MethodHandle:
private byte vmentry; // adapter stub or method entry point
//private int vmslots; // optionally, hoist type.form.vmslots
protected Object vmtarget; // VM-specific, class-specific target value
//MethodType type; // defined in MethodHandle
// TO DO: vmtarget should be invisible to Java, since the JVM puts internal
// managed pointers into it. Making it visible exposes it to debuggers,
// which can cause errors when they treat the pointer as an Object.
// These two dummy fields are present to force 'I' and 'J' signatures
// into this class's constant pool, so they can be transferred
// to vmentry when this class is loaded.
static final int INT_FIELD = 0;
static final long LONG_FIELD = 0;
/** Access methods for the internals of MethodHandle, supplied to
* MethodHandleImpl as a trusted agent.
*/
static public interface MethodHandleFriend {
void initType(MethodHandle mh, MethodType type);
}
public static void setMethodHandleFriend(Access token, MethodHandleFriend am) {
Access.check(token);
if (METHOD_HANDLE_FRIEND != null)
throw new InternalError(); // just once
METHOD_HANDLE_FRIEND = am;
}
static private MethodHandleFriend METHOD_HANDLE_FRIEND;
// NOT public
static void initType(MethodHandle mh, MethodType type) {
METHOD_HANDLE_FRIEND.initType(mh, type);
}
// type is defined in java.dyn.MethodHandle, which is platform-independent
// vmentry (a void* field) is used *only* by by the JVM.
// The JVM adjusts its type to int or long depending on system wordsize.
// Since it is statically typed as neither int nor long, it is impossible
// to use this field from Java bytecode. (Please don't try to, either.)
// The vmentry is an assembly-language stub which is jumped to
// immediately after the method type is verified.
// For a direct MH, this stub loads the vmtarget's entry point
// and jumps to it.
/**
* VM-based method handles must have a security token.
* This security token can only be obtained by trusted code.
* Do not create method handles directly; use factory methods.
*/
public MethodHandleImpl(Access token) {
Access.check(token);
}
/** Initialize the method type form to participate in JVM calls.
* This is done once for each erased type.
*/
public static void init(Access token, MethodType self) {
Access.check(token);
if (MethodHandleNatives.JVM_SUPPORT)
MethodHandleNatives.init(self);
}
/// Factory methods to create method handles: /// Factory methods to create method handles:
private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE; private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE;
static private Lookup IMPL_LOOKUP_INIT; static void initStatics() {
public static void initLookup(Access token, Lookup lookup) {
Access.check(token);
if (IMPL_LOOKUP_INIT != null)
throw new InternalError();
IMPL_LOOKUP_INIT = lookup;
}
public static Lookup getLookup(Access token) {
Access.check(token);
return IMPL_LOOKUP;
}
static {
if (!MethodHandleNatives.JVM_SUPPORT) // force init of native API
throw new InternalError("No JVM support for JSR 292");
// Force initialization of Lookup, so it calls us back as initLookup:
MethodHandles.publicLookup();
if (IMPL_LOOKUP_INIT == null)
throw new InternalError();
}
public static void initStatics() {
// Trigger preceding sequence. // Trigger preceding sequence.
} }
/** Shared secret with MethodHandles.Lookup, a copy of Lookup.IMPL_LOOKUP. */
static final Lookup IMPL_LOOKUP = IMPL_LOOKUP_INIT;
/** Look up a given method. /** Look up a given method.
* Callable only from java.dyn and related packages. * Callable only from sun.invoke and related packages.
* <p> * <p>
* The resulting method handle type will be of the given type, * The resulting method handle type will be of the given type,
* with a receiver type {@code rcvc} prepended if the member is not static. * with a receiver type {@code rcvc} prepended if the member is not static.
@ -170,10 +70,9 @@ public abstract class MethodHandleImpl {
* @return a direct handle to the matching method * @return a direct handle to the matching method
* @throws IllegalAccessException if the given method cannot be accessed by the lookup class * @throws IllegalAccessException if the given method cannot be accessed by the lookup class
*/ */
public static static
MethodHandle findMethod(Access token, MemberName method, MethodHandle findMethod(MemberName method,
boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException { boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException {
Access.check(token); // only trusted calls
MethodType mtype = method.getMethodType(); MethodType mtype = method.getMethodType();
if (!method.isStatic()) { if (!method.isStatic()) {
// adjust the advertised receiver type to be exactly the one requested // adjust the advertised receiver type to be exactly the one requested
@ -183,7 +82,7 @@ public abstract class MethodHandleImpl {
} }
DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass); DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass);
if (!mh.isValid()) if (!mh.isValid())
throw newNoAccessException(method, lookupClass); throw method.makeAccessException("no access", lookupClass);
assert(mh.type() == mtype); assert(mh.type() == mtype);
if (!method.isVarargs()) if (!method.isVarargs())
return mh; return mh;
@ -191,13 +90,12 @@ public abstract class MethodHandleImpl {
return mh.asVarargsCollector(mtype.parameterType(mtype.parameterCount()-1)); return mh.asVarargsCollector(mtype.parameterType(mtype.parameterCount()-1));
} }
public static static
MethodHandle makeAllocator(Access token, MethodHandle rawConstructor) { MethodHandle makeAllocator(MethodHandle rawConstructor) {
Access.check(token);
MethodType rawConType = rawConstructor.type(); MethodType rawConType = rawConstructor.type();
// Wrap the raw (unsafe) constructor with the allocation of a suitable object. // Wrap the raw (unsafe) constructor with the allocation of a suitable object.
MethodHandle allocator MethodHandle allocator
= AllocateObject.make(token, rawConType.parameterType(0), rawConstructor); = AllocateObject.make(rawConType.parameterType(0), rawConstructor);
assert(allocator.type() assert(allocator.type()
.equals(rawConType.dropParameterTypes(0, 1).changeReturnType(rawConType.parameterType(0)))); .equals(rawConType.dropParameterTypes(0, 1).changeReturnType(rawConType.parameterType(0))));
return allocator; return allocator;
@ -211,13 +109,11 @@ public abstract class MethodHandleImpl {
private AllocateObject(MethodHandle invoker, private AllocateObject(MethodHandle invoker,
Class<C> allocateClass, MethodHandle rawConstructor) { Class<C> allocateClass, MethodHandle rawConstructor) {
super(Access.TOKEN, invoker); super(invoker);
this.allocateClass = allocateClass; this.allocateClass = allocateClass;
this.rawConstructor = rawConstructor; this.rawConstructor = rawConstructor;
} }
static MethodHandle make(Access token, static MethodHandle make(Class<?> allocateClass, MethodHandle rawConstructor) {
Class<?> allocateClass, MethodHandle rawConstructor) {
Access.check(token);
MethodType rawConType = rawConstructor.type(); MethodType rawConType = rawConstructor.type();
assert(rawConType.parameterType(0) == allocateClass); assert(rawConType.parameterType(0) == allocateClass);
MethodType newType = rawConType.dropParameterTypes(0, 1).changeReturnType(allocateClass); MethodType newType = rawConType.dropParameterTypes(0, 1).changeReturnType(allocateClass);
@ -225,18 +121,18 @@ public abstract class MethodHandleImpl {
if (nargs < INVOKES.length) { if (nargs < INVOKES.length) {
MethodHandle invoke = INVOKES[nargs]; MethodHandle invoke = INVOKES[nargs];
MethodType conType = CON_TYPES[nargs]; MethodType conType = CON_TYPES[nargs];
MethodHandle gcon = convertArguments(token, rawConstructor, conType, rawConType, null); MethodHandle gcon = convertArguments(rawConstructor, conType, rawConType, null);
if (gcon == null) return null; if (gcon == null) return null;
MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon); MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
assert(galloc.type() == newType.generic()); assert(galloc.type() == newType.generic());
return convertArguments(token, galloc, newType, galloc.type(), null); return convertArguments(galloc, newType, galloc.type(), null);
} else { } else {
MethodHandle invoke = VARARGS_INVOKE; MethodHandle invoke = VARARGS_INVOKE;
MethodType conType = CON_TYPES[nargs]; MethodType conType = CON_TYPES[nargs];
MethodHandle gcon = spreadArguments(token, rawConstructor, conType, 1); MethodHandle gcon = spreadArguments(rawConstructor, conType, 1);
if (gcon == null) return null; if (gcon == null) return null;
MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon); MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
return collectArguments(token, galloc, newType, 1, null); return collectArguments(galloc, newType, 1, null);
} }
} }
@Override @Override
@ -338,20 +234,16 @@ public abstract class MethodHandleImpl {
} }
} }
public static static
MethodHandle accessField(Access token, MethodHandle accessField(MemberName member, boolean isSetter,
MemberName member, boolean isSetter,
Class<?> lookupClass) { Class<?> lookupClass) {
Access.check(token);
// Use sun. misc.Unsafe to dig up the dirt on the field. // Use sun. misc.Unsafe to dig up the dirt on the field.
MethodHandle mh = new FieldAccessor(token, member, isSetter); MethodHandle mh = new FieldAccessor(member, isSetter);
return mh; return mh;
} }
public static static
MethodHandle accessArrayElement(Access token, MethodHandle accessArrayElement(Class<?> arrayClass, boolean isSetter) {
Class<?> arrayClass, boolean isSetter) {
Access.check(token);
if (!arrayClass.isArray()) if (!arrayClass.isArray())
throw newIllegalArgumentException("not an array: "+arrayClass); throw newIllegalArgumentException("not an array: "+arrayClass);
Class<?> elemClass = arrayClass.getComponentType(); Class<?> elemClass = arrayClass.getComponentType();
@ -379,12 +271,13 @@ public abstract class MethodHandleImpl {
final long offset; final long offset;
final String name; final String name;
public FieldAccessor(Access token, MemberName field, boolean isSetter) { FieldAccessor(MemberName field, boolean isSetter) {
super(Access.TOKEN, fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic())); super(fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic()));
this.offset = (long) field.getVMIndex(token); this.offset = (long) field.getVMIndex();
this.name = field.getName(); this.name = field.getName();
this.base = staticBase(field); this.base = staticBase(field);
} }
@Override
public String toString() { return addTypeString(name, this); } public String toString() { return addTypeString(name, this); }
int getFieldI(C obj) { return unsafe.getInt(obj, offset); } int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
@ -560,10 +453,8 @@ public abstract class MethodHandleImpl {
* @param receiver Receiver (or first static method argument) to pre-bind. * @param receiver Receiver (or first static method argument) to pre-bind.
* @return a BoundMethodHandle for the given DirectMethodHandle, or null if it does not exist * @return a BoundMethodHandle for the given DirectMethodHandle, or null if it does not exist
*/ */
public static static
MethodHandle bindReceiver(Access token, MethodHandle bindReceiver(MethodHandle target, Object receiver) {
MethodHandle target, Object receiver) {
Access.check(token);
if (target instanceof AdapterMethodHandle && if (target instanceof AdapterMethodHandle &&
((AdapterMethodHandle)target).conversionOp() == MethodHandleNatives.Constants.OP_RETYPE_ONLY ((AdapterMethodHandle)target).conversionOp() == MethodHandleNatives.Constants.OP_RETYPE_ONLY
) { ) {
@ -574,7 +465,7 @@ public abstract class MethodHandleImpl {
dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) { dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) {
MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0); MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0);
MethodType newType = target.type().dropParameterTypes(0, 1); MethodType newType = target.type().dropParameterTypes(0, 1);
return convertArguments(token, bmh, newType, bmh.type(), null); return convertArguments(bmh, newType, bmh.type(), null);
} }
} }
} }
@ -590,19 +481,15 @@ public abstract class MethodHandleImpl {
* @param receiver Argument (which can be a boxed primitive) to pre-bind. * @param receiver Argument (which can be a boxed primitive) to pre-bind.
* @return a suitable BoundMethodHandle * @return a suitable BoundMethodHandle
*/ */
public static static
MethodHandle bindArgument(Access token, MethodHandle bindArgument(MethodHandle target, int argnum, Object receiver) {
MethodHandle target, int argnum, Object receiver) {
Access.check(token);
return new BoundMethodHandle(target, receiver, argnum); return new BoundMethodHandle(target, receiver, argnum);
} }
public static MethodHandle convertArguments(Access token, static MethodHandle convertArguments(MethodHandle target,
MethodHandle target,
MethodType newType, MethodType newType,
MethodType oldType, MethodType oldType,
int[] permutationOrNull) { int[] permutationOrNull) {
Access.check(token);
assert(oldType.parameterCount() == target.type().parameterCount()); assert(oldType.parameterCount() == target.type().parameterCount());
if (permutationOrNull != null) { if (permutationOrNull != null) {
int outargs = oldType.parameterCount(), inargs = newType.parameterCount(); int outargs = oldType.parameterCount(), inargs = newType.parameterCount();
@ -613,7 +500,7 @@ public abstract class MethodHandleImpl {
for (int i = 0; i < outargs; i++) for (int i = 0; i < outargs; i++)
callTypeArgs[i] = newType.parameterType(permutationOrNull[i]); callTypeArgs[i] = newType.parameterType(permutationOrNull[i]);
MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs); MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs);
target = convertArguments(token, target, callType, oldType, null); target = convertArguments(target, callType, oldType, null);
assert(target != null); assert(target != null);
oldType = target.type(); oldType = target.type();
List<Integer> goal = new ArrayList<Integer>(); // i*TOKEN List<Integer> goal = new ArrayList<Integer>(); // i*TOKEN
@ -710,7 +597,7 @@ public abstract class MethodHandleImpl {
Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy); Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes); MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes);
MethodHandle nextTarget MethodHandle nextTarget
= AdapterMethodHandle.makeRotateArguments(token, rotType, target, = AdapterMethodHandle.makeRotateArguments(rotType, target,
rotBeg, rotSpan.size(), rotBy); rotBeg, rotSpan.size(), rotBy);
if (nextTarget != null) { if (nextTarget != null) {
//System.out.println("Rot: "+rotSpan+" by "+rotBy); //System.out.println("Rot: "+rotSpan+" by "+rotBy);
@ -733,7 +620,7 @@ public abstract class MethodHandleImpl {
int j = state.indexOf(arg); int j = state.indexOf(arg);
Collections.swap(ptypes, i, j); Collections.swap(ptypes, i, j);
MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes); MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes);
target = AdapterMethodHandle.makeSwapArguments(token, swapType, target, i, j); target = AdapterMethodHandle.makeSwapArguments(swapType, target, i, j);
if (target == null) throw newIllegalArgumentException("cannot swap"); if (target == null) throw newIllegalArgumentException("cannot swap");
assert(target.type() == swapType); assert(target.type() == swapType);
oldType = swapType; oldType = swapType;
@ -760,7 +647,7 @@ public abstract class MethodHandleImpl {
List<Class<?>> ptypes = oldType.parameterList(); List<Class<?>> ptypes = oldType.parameterList();
ptypes = ptypes.subList(0, ptypes.size() - dupArgCount); ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes); MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes);
target = AdapterMethodHandle.makeDupArguments(token, dupType, target, dupArgPos, dupArgCount); target = AdapterMethodHandle.makeDupArguments(dupType, target, dupArgPos, dupArgCount);
if (target == null) if (target == null)
throw newIllegalArgumentException("cannot dup"); throw newIllegalArgumentException("cannot dup");
oldType = target.type(); oldType = target.type();
@ -778,7 +665,7 @@ public abstract class MethodHandleImpl {
List<Class<?>> dropTypes = newType.parameterList() List<Class<?>> dropTypes = newType.parameterList()
.subList(dropArgPos, dropArgPos + dropArgCount); .subList(dropArgPos, dropArgPos + dropArgCount);
MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes); MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes);
target = AdapterMethodHandle.makeDropArguments(token, dropType, target, dropArgPos, dropArgCount); target = AdapterMethodHandle.makeDropArguments(dropType, target, dropArgPos, dropArgCount);
if (target == null) throw newIllegalArgumentException("cannot drop"); if (target == null) throw newIllegalArgumentException("cannot drop");
oldType = target.type(); oldType = target.type();
} }
@ -787,7 +674,7 @@ public abstract class MethodHandleImpl {
return target; return target;
if (oldType.parameterCount() != newType.parameterCount()) if (oldType.parameterCount() != newType.parameterCount())
throw newIllegalArgumentException("mismatched parameter count"); throw newIllegalArgumentException("mismatched parameter count");
MethodHandle res = AdapterMethodHandle.makePairwiseConvert(token, newType, target); MethodHandle res = AdapterMethodHandle.makePairwiseConvert(newType, target);
if (res != null) if (res != null)
return res; return res;
int argc = oldType.parameterCount(); int argc = oldType.parameterCount();
@ -797,26 +684,24 @@ public abstract class MethodHandleImpl {
// then back to the desired types. We might have to use Java-based // then back to the desired types. We might have to use Java-based
// method handles to do this. // method handles to do this.
MethodType objType = MethodType.genericMethodType(argc); MethodType objType = MethodType.genericMethodType(argc);
MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(token, objType, target); MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(objType, target);
if (objTarget == null) if (objTarget == null)
objTarget = FromGeneric.make(target); objTarget = FromGeneric.make(target);
res = AdapterMethodHandle.makePairwiseConvert(token, newType, objTarget); res = AdapterMethodHandle.makePairwiseConvert(newType, objTarget);
if (res != null) if (res != null)
return res; return res;
return ToGeneric.make(newType, objTarget); return ToGeneric.make(newType, objTarget);
} }
public static MethodHandle spreadArguments(Access token, static MethodHandle spreadArguments(MethodHandle target,
MethodHandle target,
MethodType newType, MethodType newType,
int spreadArg) { int spreadArg) {
Access.check(token);
// TO DO: maybe allow the restarg to be Object and implicitly cast to Object[] // TO DO: maybe allow the restarg to be Object and implicitly cast to Object[]
MethodType oldType = target.type(); MethodType oldType = target.type();
// spread the last argument of newType to oldType // spread the last argument of newType to oldType
int spreadCount = oldType.parameterCount() - spreadArg; int spreadCount = oldType.parameterCount() - spreadArg;
Class<Object[]> spreadArgType = Object[].class; Class<Object[]> spreadArgType = Object[].class;
MethodHandle res = AdapterMethodHandle.makeSpreadArguments(token, newType, target, spreadArgType, spreadArg, spreadCount); MethodHandle res = AdapterMethodHandle.makeSpreadArguments(newType, target, spreadArgType, spreadArg, spreadCount);
if (res != null) if (res != null)
return res; return res;
// try an intermediate adapter // try an intermediate adapter
@ -829,20 +714,19 @@ public abstract class MethodHandleImpl {
ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i); ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i);
MethodType midType = MethodType.methodType(newType.returnType(), ptypes); MethodType midType = MethodType.methodType(newType.returnType(), ptypes);
// after spreading, some arguments may need further conversion // after spreading, some arguments may need further conversion
MethodHandle target2 = convertArguments(token, target, midType, oldType, null); MethodHandle target2 = convertArguments(target, midType, oldType, null);
if (target2 == null) if (target2 == null)
throw new UnsupportedOperationException("NYI: convert "+midType+" =calls=> "+oldType); throw new UnsupportedOperationException("NYI: convert "+midType+" =calls=> "+oldType);
res = AdapterMethodHandle.makeSpreadArguments(token, newType, target2, spreadArgType, spreadArg, spreadCount); res = AdapterMethodHandle.makeSpreadArguments(newType, target2, spreadArgType, spreadArg, spreadCount);
if (res != null) if (res != null)
return res; return res;
res = SpreadGeneric.make(target2, spreadCount); res = SpreadGeneric.make(target2, spreadCount);
if (res != null) if (res != null)
res = convertArguments(token, res, newType, res.type(), null); res = convertArguments(res, newType, res.type(), null);
return res; return res;
} }
public static MethodHandle collectArguments(Access token, static MethodHandle collectArguments(MethodHandle target,
MethodHandle target,
MethodType newType, MethodType newType,
int collectArg, int collectArg,
MethodHandle collector) { MethodHandle collector) {
@ -856,29 +740,27 @@ public abstract class MethodHandleImpl {
// oldType // (a..., b...)=>r // oldType // (a..., b...)=>r
assert(newType.parameterCount() == collectArg + colType.parameterCount()); assert(newType.parameterCount() == collectArg + colType.parameterCount());
assert(oldType.parameterCount() == collectArg + 1); assert(oldType.parameterCount() == collectArg + 1);
MethodHandle gtarget = convertArguments(token, target, oldType.generic(), oldType, null); MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null);
MethodHandle gcollector = convertArguments(token, collector, colType.generic(), colType, null); MethodHandle gcollector = convertArguments(collector, colType.generic(), colType, null);
if (gtarget == null || gcollector == null) return null; if (gtarget == null || gcollector == null) return null;
MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget); MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget);
MethodHandle result = convertArguments(token, gresult, newType, gresult.type(), null); MethodHandle result = convertArguments(gresult, newType, gresult.type(), null);
return result; return result;
} }
public static MethodHandle filterArgument(Access token, static MethodHandle filterArgument(MethodHandle target,
MethodHandle target,
int pos, int pos,
MethodHandle filter) { MethodHandle filter) {
Access.check(token);
MethodType ttype = target.type(), gttype = ttype.generic(); MethodType ttype = target.type(), gttype = ttype.generic();
if (ttype != gttype) { if (ttype != gttype) {
target = convertArguments(token, target, gttype, ttype, null); target = convertArguments(target, gttype, ttype, null);
ttype = gttype; ttype = gttype;
} }
MethodType ftype = filter.type(), gftype = ftype.generic(); MethodType ftype = filter.type(), gftype = ftype.generic();
if (ftype.parameterCount() != 1) if (ftype.parameterCount() != 1)
throw new InternalError(); throw new InternalError();
if (ftype != gftype) { if (ftype != gftype) {
filter = convertArguments(token, filter, gftype, ftype, null); filter = convertArguments(filter, gftype, ftype, null);
ftype = gftype; ftype = gftype;
} }
if (ftype == ttype) { if (ftype == ttype) {
@ -888,27 +770,24 @@ public abstract class MethodHandleImpl {
return FilterGeneric.makeArgumentFilter(pos, filter, target); return FilterGeneric.makeArgumentFilter(pos, filter, target);
} }
public static MethodHandle foldArguments(Access token, static MethodHandle foldArguments(MethodHandle target,
MethodHandle target,
MethodType newType, MethodType newType,
MethodHandle combiner) { MethodHandle combiner) {
Access.check(token);
MethodType oldType = target.type(); MethodType oldType = target.type();
MethodType ctype = combiner.type(); MethodType ctype = combiner.type();
MethodHandle gtarget = convertArguments(token, target, oldType.generic(), oldType, null); MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null);
MethodHandle gcombiner = convertArguments(token, combiner, ctype.generic(), ctype, null); MethodHandle gcombiner = convertArguments(combiner, ctype.generic(), ctype, null);
if (gtarget == null || gcombiner == null) return null; if (gtarget == null || gcombiner == null) return null;
MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget); MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget);
MethodHandle result = convertArguments(token, gresult, newType, gresult.type(), null); MethodHandle result = convertArguments(gresult, newType, gresult.type(), null);
return result; return result;
} }
public static static
MethodHandle dropArguments(Access token, MethodHandle target, MethodHandle dropArguments(MethodHandle target,
MethodType newType, int argnum) { MethodType newType, int argnum) {
Access.check(token);
int drops = newType.parameterCount() - target.type().parameterCount(); int drops = newType.parameterCount() - target.type().parameterCount();
MethodHandle res = AdapterMethodHandle.makeDropArguments(token, newType, target, argnum, drops); MethodHandle res = AdapterMethodHandle.makeDropArguments(newType, target, argnum, drops);
if (res != null) if (res != null)
return res; return res;
throw new UnsupportedOperationException("NYI"); throw new UnsupportedOperationException("NYI");
@ -918,36 +797,34 @@ public abstract class MethodHandleImpl {
private final MethodHandle test, target, fallback; private final MethodHandle test, target, fallback;
private GuardWithTest(MethodHandle invoker, private GuardWithTest(MethodHandle invoker,
MethodHandle test, MethodHandle target, MethodHandle fallback) { MethodHandle test, MethodHandle target, MethodHandle fallback) {
super(Access.TOKEN, invoker); super(invoker);
this.test = test; this.test = test;
this.target = target; this.target = target;
this.fallback = fallback; this.fallback = fallback;
} }
static MethodHandle make(Access token, static MethodHandle make(MethodHandle test, MethodHandle target, MethodHandle fallback) {
MethodHandle test, MethodHandle target, MethodHandle fallback) {
Access.check(token);
MethodType type = target.type(); MethodType type = target.type();
int nargs = type.parameterCount(); int nargs = type.parameterCount();
if (nargs < INVOKES.length) { if (nargs < INVOKES.length) {
MethodHandle invoke = INVOKES[nargs]; MethodHandle invoke = INVOKES[nargs];
MethodType gtype = type.generic(); MethodType gtype = type.generic();
assert(invoke.type().dropParameterTypes(0,1) == gtype); assert(invoke.type().dropParameterTypes(0,1) == gtype);
MethodHandle gtest = convertArguments(token, test, gtype.changeReturnType(boolean.class), test.type(), null); MethodHandle gtest = convertArguments(test, gtype.changeReturnType(boolean.class), test.type(), null);
MethodHandle gtarget = convertArguments(token, target, gtype, type, null); MethodHandle gtarget = convertArguments(target, gtype, type, null);
MethodHandle gfallback = convertArguments(token, fallback, gtype, type, null); MethodHandle gfallback = convertArguments(fallback, gtype, type, null);
if (gtest == null || gtarget == null || gfallback == null) return null; if (gtest == null || gtarget == null || gfallback == null) return null;
MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback); MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback);
return convertArguments(token, gguard, type, gtype, null); return convertArguments(gguard, type, gtype, null);
} else { } else {
MethodHandle invoke = VARARGS_INVOKE; MethodHandle invoke = VARARGS_INVOKE;
MethodType gtype = MethodType.genericMethodType(1); MethodType gtype = MethodType.genericMethodType(1);
assert(invoke.type().dropParameterTypes(0,1) == gtype); assert(invoke.type().dropParameterTypes(0,1) == gtype);
MethodHandle gtest = spreadArguments(token, test, gtype.changeReturnType(boolean.class), 0); MethodHandle gtest = spreadArguments(test, gtype.changeReturnType(boolean.class), 0);
MethodHandle gtarget = spreadArguments(token, target, gtype, 0); MethodHandle gtarget = spreadArguments(target, gtype, 0);
MethodHandle gfallback = spreadArguments(token, fallback, gtype, 0); MethodHandle gfallback = spreadArguments(fallback, gtype, 0);
MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback); MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback);
if (gtest == null || gtarget == null || gfallback == null) return null; if (gtest == null || gtarget == null || gfallback == null) return null;
return collectArguments(token, gguard, type, 0, null); return collectArguments(gguard, type, 0, null);
} }
} }
@Override @Override
@ -1034,24 +911,23 @@ public abstract class MethodHandleImpl {
} }
} }
public static static
MethodHandle makeGuardWithTest(Access token, MethodHandle makeGuardWithTest(MethodHandle test,
MethodHandle test,
MethodHandle target, MethodHandle target,
MethodHandle fallback) { MethodHandle fallback) {
return GuardWithTest.make(token, test, target, fallback); return GuardWithTest.make(test, target, fallback);
} }
private static class GuardWithCatch extends BoundMethodHandle { private static class GuardWithCatch extends BoundMethodHandle {
private final MethodHandle target; private final MethodHandle target;
private final Class<? extends Throwable> exType; private final Class<? extends Throwable> exType;
private final MethodHandle catcher; private final MethodHandle catcher;
public GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
this(INVOKES[target.type().parameterCount()], target, exType, catcher); this(INVOKES[target.type().parameterCount()], target, exType, catcher);
} }
public GuardWithCatch(MethodHandle invoker, GuardWithCatch(MethodHandle invoker,
MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
super(Access.TOKEN, invoker); super(invoker);
this.target = target; this.target = target;
this.exType = exType; this.exType = exType;
this.catcher = catcher; this.catcher = catcher;
@ -1171,42 +1047,40 @@ public abstract class MethodHandleImpl {
} }
public static static
MethodHandle makeGuardWithCatch(Access token, MethodHandle makeGuardWithCatch(MethodHandle target,
MethodHandle target,
Class<? extends Throwable> exType, Class<? extends Throwable> exType,
MethodHandle catcher) { MethodHandle catcher) {
Access.check(token);
MethodType type = target.type(); MethodType type = target.type();
MethodType ctype = catcher.type(); MethodType ctype = catcher.type();
int nargs = type.parameterCount(); int nargs = type.parameterCount();
if (nargs < GuardWithCatch.INVOKES.length) { if (nargs < GuardWithCatch.INVOKES.length) {
MethodType gtype = type.generic(); MethodType gtype = type.generic();
MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class); MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
MethodHandle gtarget = convertArguments(token, target, gtype, type, null); MethodHandle gtarget = convertArguments(target, gtype, type, null);
MethodHandle gcatcher = convertArguments(token, catcher, gcatchType, ctype, null); MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, null);
MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher); MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher);
if (gtarget == null || gcatcher == null || gguard == null) return null; if (gtarget == null || gcatcher == null || gguard == null) return null;
return convertArguments(token, gguard, type, gtype, null); return convertArguments(gguard, type, gtype, null);
} else { } else {
MethodType gtype = MethodType.genericMethodType(0, true); MethodType gtype = MethodType.genericMethodType(0, true);
MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class); MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
MethodHandle gtarget = spreadArguments(token, target, gtype, 0); MethodHandle gtarget = spreadArguments(target, gtype, 0);
MethodHandle gcatcher = spreadArguments(token, catcher, gcatchType, 1); MethodHandle gcatcher = spreadArguments(catcher, gcatchType, 1);
MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher); MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher);
if (gtarget == null || gcatcher == null || gguard == null) return null; if (gtarget == null || gcatcher == null || gguard == null) return null;
return collectArguments(token, gguard, type, 0, null); return collectArguments(gguard, type, 0, null);
} }
} }
public static static
MethodHandle throwException(Access token, MethodType type) { MethodHandle throwException(MethodType type) {
Access.check(token); return AdapterMethodHandle.makeRetypeRaw(type, throwException());
return AdapterMethodHandle.makeRetypeRaw(token, type, THROW_EXCEPTION);
} }
static final MethodHandle THROW_EXCEPTION; static MethodHandle THROW_EXCEPTION;
static { static MethodHandle throwException() {
if (THROW_EXCEPTION != null) return THROW_EXCEPTION;
try { try {
THROW_EXCEPTION THROW_EXCEPTION
= IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException", = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
@ -1214,71 +1088,19 @@ public abstract class MethodHandleImpl {
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
return THROW_EXCEPTION;
} }
static <T extends Throwable> Empty throwException(T t) throws T { throw t; } static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
public static String getNameString(Access token, MethodHandle target, Object type) {
Access.check(token);
if (!(type instanceof MethodType)) {
if (type == null)
type = target.type();
else if (type instanceof MethodHandle)
type = ((MethodHandle)type).type();
}
MemberName name = null;
if (target != null)
name = MethodHandleNatives.getMethodName(target);
if (name == null)
return "invoke" + type;
return name.getName() + type;
}
public static String getNameString(Access token, MethodHandle target) {
return getNameString(token, target, null);
}
static String addTypeString(Object obj, MethodHandle target) {
String str = String.valueOf(obj);
if (target == null) return str;
int paren = str.indexOf('(');
if (paren >= 0) str = str.substring(0, paren);
return str + target.type();
}
static void checkSpreadArgument(Object av, int n) {
if (av == null ? n != 0 : ((Object[])av).length != n)
throw newIllegalArgumentException("Array is not of length "+n);
}
static void raiseException(int code, Object actual, Object required) {
String message;
// disregard the identity of the actual object, if it is not a class:
if (!(actual instanceof Class) && !(actual instanceof MethodType))
actual = actual.getClass();
if (actual != null)
message = "required "+required+" but encountered "+actual;
else
message = "required "+required;
switch (code) {
case 192: // checkcast
throw new ClassCastException(message);
default:
throw new InternalError("unexpected code "+code+": "+message);
}
}
// Linkage support: // Linkage support:
public static void registerBootstrap(Access token, Class<?> callerClass, MethodHandle bootstrapMethod) { static void registerBootstrap(Class<?> callerClass, MethodHandle bootstrapMethod) {
Access.check(token);
MethodHandleNatives.registerBootstrap(callerClass, bootstrapMethod); MethodHandleNatives.registerBootstrap(callerClass, bootstrapMethod);
} }
public static MethodHandle getBootstrap(Access token, Class<?> callerClass) { static MethodHandle getBootstrap(Class<?> callerClass) {
Access.check(token);
return MethodHandleNatives.getBootstrap(callerClass); return MethodHandleNatives.getBootstrap(callerClass);
} }
public static MethodHandle asVarargsCollector(Access token, MethodHandle target, Class<?> arrayType) { static MethodHandle asVarargsCollector(MethodHandle target, Class<?> arrayType) {
Access.check(token); return AdapterMethodHandle.makeVarargsCollector(target, arrayType);
return AdapterMethodHandle.makeVarargsCollector(token, target, arrayType);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,14 +23,13 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import java.lang.invoke.MethodHandles.Lookup;
import java.dyn.MethodHandles.Lookup;
import java.lang.reflect.AccessibleObject; import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import static sun.dyn.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static sun.dyn.MethodHandleImpl.IMPL_LOOKUP; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* The JVM interface for the method handles package is all here. * The JVM interface for the method handles package is all here.
@ -81,14 +80,12 @@ class MethodHandleNatives {
* This routine is for debugging and reflection. * This routine is for debugging and reflection.
*/ */
static MemberName getMethodName(MethodHandle self) { static MemberName getMethodName(MethodHandle self) {
if (!JVM_SUPPORT) return null;
return (MemberName) getTarget(self, ETF_METHOD_NAME); return (MemberName) getTarget(self, ETF_METHOD_NAME);
} }
/** Fetch the reflective version of the handled method, if available. /** Fetch the reflective version of the handled method, if available.
*/ */
static AccessibleObject getTargetMethod(MethodHandle self) { static AccessibleObject getTargetMethod(MethodHandle self) {
if (!JVM_SUPPORT) return null;
return (AccessibleObject) getTarget(self, ETF_REFLECT_METHOD); return (AccessibleObject) getTarget(self, ETF_REFLECT_METHOD);
} }
@ -97,7 +94,6 @@ class MethodHandleNatives {
* If it is chained to another method handle, return that handle. * If it is chained to another method handle, return that handle.
*/ */
static Object getTargetInfo(MethodHandle self) { static Object getTargetInfo(MethodHandle self) {
if (!JVM_SUPPORT) return null;
return getTarget(self, ETF_HANDLE_OR_METHOD_NAME); return getTarget(self, ETF_HANDLE_OR_METHOD_NAME);
} }
@ -111,11 +107,6 @@ class MethodHandleNatives {
*/ */
static native int getConstant(int which); static native int getConstant(int which);
/** True iff this HotSpot JVM has built-in support for method handles.
* If false, some test cases might run, but functionality will be missing.
*/
public static final boolean JVM_SUPPORT;
/** Java copy of MethodHandlePushLimit in range 2..255. */ /** Java copy of MethodHandlePushLimit in range 2..255. */
static final int JVM_PUSH_LIMIT; static final int JVM_PUSH_LIMIT;
/** JVM stack motion (in words) after one slot is pushed, usually -1. /** JVM stack motion (in words) after one slot is pushed, usually -1.
@ -127,31 +118,24 @@ class MethodHandleNatives {
private static native void registerNatives(); private static native void registerNatives();
static { static {
boolean JVM_SUPPORT_;
int JVM_PUSH_LIMIT_; int JVM_PUSH_LIMIT_;
int JVM_STACK_MOVE_UNIT_; int JVM_STACK_MOVE_UNIT_;
int CONV_OP_IMPLEMENTED_MASK_; int CONV_OP_IMPLEMENTED_MASK_;
try { try {
registerNatives(); registerNatives();
JVM_SUPPORT_ = true;
JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT); JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT);
JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT); JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT);
CONV_OP_IMPLEMENTED_MASK_ = getConstant(Constants.GC_CONV_OP_IMPLEMENTED_MASK); CONV_OP_IMPLEMENTED_MASK_ = getConstant(Constants.GC_CONV_OP_IMPLEMENTED_MASK);
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init"); //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
} catch (UnsatisfiedLinkError ee) { } catch (UnsatisfiedLinkError ee) {
// ignore; if we use init() methods later we'll see linkage errors // ignore; if we use init() methods later we'll see linkage errors
JVM_SUPPORT_ = false;
JVM_PUSH_LIMIT_ = 3; // arbitrary JVM_PUSH_LIMIT_ = 3; // arbitrary
JVM_STACK_MOVE_UNIT_ = -1; // arbitrary JVM_STACK_MOVE_UNIT_ = -1; // arbitrary
CONV_OP_IMPLEMENTED_MASK_ = 0; CONV_OP_IMPLEMENTED_MASK_ = 0;
//System.out.println("Warning: Running with JVM_SUPPORT=false");
//System.out.println(ee);
JVM_SUPPORT = JVM_SUPPORT_;
JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_; JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_;
JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_; JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_;
throw ee; // just die; hopeless to try to run with an older JVM throw ee; // just die; hopeless to try to run with an older JVM
} }
JVM_SUPPORT = JVM_SUPPORT_;
JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_; JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_;
JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_; JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_;
if (CONV_OP_IMPLEMENTED_MASK_ == 0) if (CONV_OP_IMPLEMENTED_MASK_ == 0)
@ -189,9 +173,15 @@ class MethodHandleNatives {
MN_SEARCH_INTERFACES = 0x00200000, // for MHN.getMembers MN_SEARCH_INTERFACES = 0x00200000, // for MHN.getMembers
VM_INDEX_UNINITIALIZED = -99; VM_INDEX_UNINITIALIZED = -99;
// BoundMethodHandle
/** Constants for decoding the vmargslot field, which contains 2 values. */
static final int
ARG_SLOT_PUSH_SHIFT = 16,
ARG_SLOT_MASK = (1<<ARG_SLOT_PUSH_SHIFT)-1;
// AdapterMethodHandle // AdapterMethodHandle
/** Conversions recognized by the JVM. /** Conversions recognized by the JVM.
* They must align with the constants in sun.dyn_AdapterMethodHandle, * They must align with the constants in java.lang.invoke.AdapterMethodHandle,
* in the JVM file hotspot/src/share/vm/classfile/javaClasses.hpp. * in the JVM file hotspot/src/share/vm/classfile/javaClasses.hpp.
*/ */
static final int static final int
@ -292,7 +282,7 @@ class MethodHandleNatives {
return true; return true;
} }
static { static {
if (JVM_SUPPORT) verifyConstants(); verifyConstants();
} }
// Up-calls from the JVM. // Up-calls from the JVM.
@ -305,28 +295,47 @@ class MethodHandleNatives {
String name, MethodType type, String name, MethodType type,
Object info, Object info,
MemberName callerMethod, int callerBCI) { MemberName callerMethod, int callerBCI) {
return CallSiteImpl.makeSite(bootstrapMethod, name, type, info, callerMethod, callerBCI); return CallSite.makeSite(bootstrapMethod, name, type, info, callerMethod, callerBCI);
}
/**
* Called by the JVM to check the length of a spread array.
*/
static void checkSpreadArgument(Object av, int n) {
MethodHandleStatics.checkSpreadArgument(av, n);
} }
/** /**
* The JVM wants a pointer to a MethodType. Oblige it by finding or creating one. * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
*/ */
static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) { static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
MethodType.genericMethodType(0); // trigger initialization return MethodType.makeImpl(rtype, ptypes, true);
return MethodTypeImpl.makeImpl(Access.TOKEN, rtype, ptypes, true);
} }
/** /**
* The JVM wants to use a MethodType with invokeGeneric. Give the runtime fair warning. * The JVM wants to use a MethodType with invokeGeneric. Give the runtime fair warning.
*/ */
static void notifyGenericMethodType(MethodType type) { static void notifyGenericMethodType(MethodType type) {
try { type.form().notifyGenericMethodType();
// Trigger adapter creation. }
InvokeGeneric.genericInvokerOf(type);
} catch (Exception ex) { /**
Error err = new InternalError("Exception while resolving invokeGeneric"); * The JVM wants to raise an exception. Here's the path.
err.initCause(ex); */
throw err; static void raiseException(int code, Object actual, Object required) {
String message;
// disregard the identity of the actual object, if it is not a class:
if (!(actual instanceof Class) && !(actual instanceof MethodType))
actual = actual.getClass();
if (actual != null)
message = "required "+required+" but encountered "+actual;
else
message = "required "+required;
switch (code) {
case 192: // checkcast
throw new ClassCastException(message);
default:
throw new InternalError("unexpected code "+code+": "+message);
} }
} }

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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 java.lang.invoke;
/**
* This class consists exclusively of static names internal to the
* method handle implementation.
* Usage: {@code import static java.lang.invoke.MethodHandleStatics.*}
* @author John Rose, JSR 292 EG
*/
/*non-public*/ class MethodHandleStatics {
private MethodHandleStatics() { } // do not instantiate
/*non-public*/ static String getNameString(MethodHandle target, MethodType type) {
if (type == null)
type = target.type();
MemberName name = null;
if (target != null)
name = MethodHandleNatives.getMethodName(target);
if (name == null)
return "invoke" + type;
return name.getName() + type;
}
/*non-public*/ static String getNameString(MethodHandle target, MethodHandle typeHolder) {
return getNameString(target, typeHolder == null ? (MethodType) null : typeHolder.type());
}
/*non-public*/ static String getNameString(MethodHandle target) {
return getNameString(target, (MethodType) null);
}
/*non-public*/ static String addTypeString(Object obj, MethodHandle target) {
String str = String.valueOf(obj);
if (target == null) return str;
int paren = str.indexOf('(');
if (paren >= 0) str = str.substring(0, paren);
return str + target.type();
}
static void checkSpreadArgument(Object av, int n) {
if (av == null ? n != 0 : ((Object[])av).length != n)
throw newIllegalArgumentException("Array is not of length "+n);
}
// handy shared exception makers (they simplify the common case code)
/*non-public*/ static RuntimeException newIllegalStateException(String message) {
return new IllegalStateException(message);
}
/*non-public*/ static RuntimeException newIllegalStateException(String message, Object obj) {
return new IllegalStateException(message(message, obj));
}
/*non-public*/ static RuntimeException newIllegalArgumentException(String message) {
return new IllegalArgumentException(message);
}
/*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj) {
return new IllegalArgumentException(message(message, obj));
}
/*non-public*/ static Error uncaughtException(Exception ex) {
Error err = new InternalError("uncaught exception");
err.initCause(ex);
return err;
}
private static String message(String message, Object obj) {
if (obj != null) message = message + ": " + obj;
return message;
}
}

View File

@ -23,24 +23,18 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
import java.lang.reflect.*; import java.lang.reflect.*;
import sun.dyn.Access; import sun.invoke.WrapperInstance;
import sun.dyn.MemberName; import sun.invoke.util.ValueConversions;
import sun.dyn.MethodHandleImpl; import sun.invoke.util.VerifyAccess;
import sun.dyn.WrapperInstance; import sun.invoke.util.Wrapper;
import sun.dyn.util.ValueConversions;
import sun.dyn.util.VerifyAccess;
import sun.dyn.util.Wrapper;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import sun.dyn.Invokers;
import sun.dyn.MethodTypeImpl;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import static sun.dyn.MemberName.newIllegalArgumentException; import static java.lang.invoke.MethodHandleStatics.*;
import static sun.dyn.MemberName.newNoAccessException;
/** /**
* This class consists exclusively of static methods that operate on or return * This class consists exclusively of static methods that operate on or return
@ -49,7 +43,7 @@ import static sun.dyn.MemberName.newNoAccessException;
* <li>Lookup methods which help create method handles for methods and fields. * <li>Lookup methods which help create method handles for methods and fields.
* <li>Combinator methods, which combine or transform pre-existing method handles into new ones. * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
* <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns. * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
* <li>Wrapper methods which can convert between method handles and other function-like "SAM types". * <li>Wrapper methods which can convert between method handles and interface types.
* </ul> * </ul>
* <p> * <p>
* @author John Rose, JSR 292 EG * @author John Rose, JSR 292 EG
@ -58,15 +52,14 @@ public class MethodHandles {
private MethodHandles() { } // do not instantiate private MethodHandles() { } // do not instantiate
private static final Access IMPL_TOKEN = Access.getToken(); private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
static { MethodHandleImpl.initStatics(); } static { MethodHandleImpl.initStatics(); }
// See IMPL_LOOKUP below. // See IMPL_LOOKUP below.
//// Method handle creation from ordinary methods. //// Method handle creation from ordinary methods.
/** /**
* Return a {@link Lookup lookup object} on the caller, * Returns a {@link Lookup lookup object} on the caller,
* which has the capability to access any method handle that the caller has access to, * which has the capability to access any method handle that the caller has access to,
* including direct method handles to private fields and methods. * including direct method handles to private fields and methods.
* This lookup object is a <em>capability</em> which may be delegated to trusted agents. * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
@ -77,7 +70,7 @@ public class MethodHandles {
} }
/** /**
* Return a {@link Lookup lookup object} which is trusted minimally. * Returns a {@link Lookup lookup object} which is trusted minimally.
* It can only be used to create method handles to * It can only be used to create method handles to
* publicly accessible fields and methods. * publicly accessible fields and methods.
* <p> * <p>
@ -120,55 +113,55 @@ public class MethodHandles {
* <table border=1 cellpadding=5 summary="lookup method behaviors"> * <table border=1 cellpadding=5 summary="lookup method behaviors">
* <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr> * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
* <td>FT f;</td><td>(T) this.f;</td> * <td>FT f;</td><td>(T) this.f;</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
* <td>static<br>FT f;</td><td>(T) C.f;</td> * <td>static<br>FT f;</td><td>(T) C.f;</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
* <td>FT f;</td><td>this.f = x;</td> * <td>FT f;</td><td>this.f = x;</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
* <td>static<br>FT f;</td><td>C.f = arg;</td> * <td>static<br>FT f;</td><td>C.f = arg;</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
* <td>T m(A*);</td><td>(T) this.m(arg*);</td> * <td>T m(A*);</td><td>(T) this.m(arg*);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
* <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td> * <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
* <td>T m(A*);</td><td>(T) super.m(arg*);</td> * <td>T m(A*);</td><td>(T) super.m(arg*);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
* <td>C(A*);</td><td>(T) new C(arg*);</td> * <td>C(A*);</td><td>(T) new C(arg*);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
* <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td> * <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
* <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td> * <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
* <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td> * <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
* <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td> * <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td> * <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
* <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td> * <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
* </tr> * </tr>
* </table> * </table>
@ -383,10 +376,10 @@ public class MethodHandles {
* and {@linkplain #PACKAGE PACKAGE (0x08)}. * and {@linkplain #PACKAGE PACKAGE (0x08)}.
* <p> * <p>
* A freshly-created lookup object * A freshly-created lookup object
* on the {@linkplain java.dyn.MethodHandles#lookup() caller's class} * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
* has all possible bits set, since the caller class can access all its own members. * has all possible bits set, since the caller class can access all its own members.
* A lookup object on a new lookup class * A lookup object on a new lookup class
* {@linkplain java.dyn.MethodHandles.Lookup#in created from a previous lookup object} * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
* may have some mode bits set to zero. * may have some mode bits set to zero.
* The purpose of this is to restrict access via the new lookup object, * The purpose of this is to restrict access via the new lookup object,
* so that it can access only names which can be reached by the original * so that it can access only names which can be reached by the original
@ -410,9 +403,8 @@ public class MethodHandles {
checkUnprivilegedlookupClass(lookupClass); checkUnprivilegedlookupClass(lookupClass);
} }
Lookup(Access token, Class<?> lookupClass) { Lookup(Class<?> lookupClass) {
this(lookupClass, ALL_MODES); this(lookupClass, ALL_MODES);
Access.check(token);
} }
private Lookup(Class<?> lookupClass, int allowedModes) { private Lookup(Class<?> lookupClass, int allowedModes) {
@ -471,7 +463,7 @@ public class MethodHandles {
} }
// Make sure outer class is initialized first. // Make sure outer class is initialized first.
static { IMPL_TOKEN.getClass(); } static { IMPL_NAMES.getClass(); }
/** Version of lookup which is trusted minimally. /** Version of lookup which is trusted minimally.
* It can only be used to create method handles to * It can only be used to create method handles to
@ -481,11 +473,10 @@ public class MethodHandles {
/** Package-private version of lookup which is trusted. */ /** Package-private version of lookup which is trusted. */
static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED); static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
static { MethodHandleImpl.initLookup(IMPL_TOKEN, IMPL_LOOKUP); }
private static void checkUnprivilegedlookupClass(Class<?> lookupClass) { private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
String name = lookupClass.getName(); String name = lookupClass.getName();
if (name.startsWith("java.dyn.") || name.startsWith("sun.dyn.")) if (name.startsWith("java.lang.invoke."))
throw newIllegalArgumentException("illegal lookupClass: "+lookupClass); throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
} }
@ -506,8 +497,8 @@ public class MethodHandles {
* access (public, package, private, and protected) is allowed. * access (public, package, private, and protected) is allowed.
* In this case, no suffix is added. * In this case, no suffix is added.
* This is true only of an object obtained originally from * This is true only of an object obtained originally from
* {@link java.dyn.MethodHandles#lookup MethodHandles.lookup}. * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
* Objects created by {@link java.dyn.MethodHandles.Lookup#in Lookup.in} * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
* always have restricted access, and will display a suffix. * always have restricted access, and will display a suffix.
* <p> * <p>
* (It may seem strange that protected access should be * (It may seem strange that protected access should be
@ -577,7 +568,7 @@ public class MethodHandles {
MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(refc, name, type, true); MemberName method = resolveOrFail(refc, name, type, true);
checkMethod(refc, method, true); checkMethod(refc, method, true);
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull()); return MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
} }
/** /**
@ -601,8 +592,8 @@ public class MethodHandles {
* if the class is {@code MethodHandle} and the name string is * if the class is {@code MethodHandle} and the name string is
* {@code invokeExact} or {@code invokeGeneric}, the resulting * {@code invokeExact} or {@code invokeGeneric}, the resulting
* method handle is equivalent to one produced by * method handle is equivalent to one produced by
* {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker} or * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
* {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker} * {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}
* with the same {@code type} argument. * with the same {@code type} argument.
* *
* @param refc the class or interface from which the method is accessed * @param refc the class or interface from which the method is accessed
@ -618,7 +609,7 @@ public class MethodHandles {
public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(refc, name, type, false); MemberName method = resolveOrFail(refc, name, type, false);
checkMethod(refc, method, false); checkMethod(refc, method, false);
MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull()); MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
return restrictProtectedReceiver(method, mh); return restrictProtectedReceiver(method, mh);
} }
@ -651,8 +642,8 @@ public class MethodHandles {
MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull()); MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
assert(ctor.isConstructor()); assert(ctor.isConstructor());
checkAccess(refc, ctor); checkAccess(refc, ctor);
MethodHandle rawMH = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull()); MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
MethodHandle allocMH = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawMH); MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
return fixVarargs(allocMH, rawMH); return fixVarargs(allocMH, rawMH);
} }
@ -708,7 +699,7 @@ public class MethodHandles {
checkSpecialCaller(specialCaller); checkSpecialCaller(specialCaller);
MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller); MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
checkMethod(refc, method, false); checkMethod(refc, method, false);
MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, specialCaller); MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller);
return restrictReceiver(method, mh, specialCaller); return restrictReceiver(method, mh, specialCaller);
} }
@ -839,17 +830,17 @@ return mh1;
Class<? extends Object> refc = receiver.getClass(); // may get NPE Class<? extends Object> refc = receiver.getClass(); // may get NPE
MemberName method = resolveOrFail(refc, name, type, false); MemberName method = resolveOrFail(refc, name, type, false);
checkMethod(refc, method, false); checkMethod(refc, method, false);
MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull()); MethodHandle dmh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, dmh, receiver); MethodHandle bmh = MethodHandleImpl.bindReceiver(dmh, receiver);
if (bmh == null) if (bmh == null)
throw newNoAccessException(method, this); throw method.makeAccessException("no access", this);
if (dmh.type().parameterCount() == 0) if (dmh.type().parameterCount() == 0)
return dmh; // bound the trailing parameter; no varargs possible return dmh; // bound the trailing parameter; no varargs possible
return fixVarargs(bmh, dmh); return fixVarargs(bmh, dmh);
} }
/** /**
* Make a direct method handle to <i>m</i>, if the lookup class has permission. * Makes a direct method handle to <i>m</i>, if the lookup class has permission.
* If <i>m</i> is non-static, the receiver argument is treated as an initial argument. * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
* If <i>m</i> is virtual, overriding is respected on every call. * If <i>m</i> is virtual, overriding is respected on every call.
* Unlike the Core Reflection API, exceptions are <em>not</em> wrapped. * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
@ -871,7 +862,7 @@ return mh1;
MemberName method = new MemberName(m); MemberName method = new MemberName(m);
assert(method.isMethod()); assert(method.isMethod());
if (!m.isAccessible()) checkMethod(method.getDeclaringClass(), method, method.isStatic()); if (!m.isAccessible()) checkMethod(method.getDeclaringClass(), method, method.isStatic());
MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull()); MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
if (!m.isAccessible()) mh = restrictProtectedReceiver(method, mh); if (!m.isAccessible()) mh = restrictProtectedReceiver(method, mh);
return mh; return mh;
} }
@ -901,7 +892,7 @@ return mh1;
assert(method.isMethod()); assert(method.isMethod());
// ignore m.isAccessible: this is a new kind of access // ignore m.isAccessible: this is a new kind of access
checkMethod(m.getDeclaringClass(), method, false); checkMethod(m.getDeclaringClass(), method, false);
MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull()); MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
return restrictReceiver(method, mh, specialCaller); return restrictReceiver(method, mh, specialCaller);
} }
@ -928,8 +919,8 @@ return mh1;
MemberName ctor = new MemberName(c); MemberName ctor = new MemberName(c);
assert(ctor.isConstructor()); assert(ctor.isConstructor());
if (!c.isAccessible()) checkAccess(c.getDeclaringClass(), ctor); if (!c.isAccessible()) checkAccess(c.getDeclaringClass(), ctor);
MethodHandle rawCtor = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull()); MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
MethodHandle allocator = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawCtor); MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
return fixVarargs(allocator, rawCtor); return fixVarargs(allocator, rawCtor);
} }
@ -940,7 +931,7 @@ return mh1;
* If the field is static, the method handle will take no arguments. * If the field is static, the method handle will take no arguments.
* Otherwise, its single argument will be the instance containing * Otherwise, its single argument will be the instance containing
* the field. * the field.
* If the method's {@code accessible} flag is not set, * If the field's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class. * access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field * @param f the reflected field
* @return a method handle which can load values from the reflected field * @return a method handle which can load values from the reflected field
@ -958,7 +949,7 @@ return mh1;
* argument, of the field's value type, the value to be stored. * argument, of the field's value type, the value to be stored.
* Otherwise, the two arguments will be the instance containing * Otherwise, the two arguments will be the instance containing
* the field, and the value to be stored. * the field, and the value to be stored.
* If the method's {@code accessible} flag is not set, * If the field's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class. * access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field * @param f the reflected field
* @return a method handle which can store values into the reflected field * @return a method handle which can store values into the reflected field
@ -999,7 +990,7 @@ return mh1;
void checkSymbolicClass(Class<?> refc) throws IllegalAccessException { void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
Class<?> caller = lookupClassOrNull(); Class<?> caller = lookupClassOrNull();
if (caller != null && !VerifyAccess.isClassAccessible(refc, caller)) if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), this); throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
} }
void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException { void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
@ -1012,7 +1003,7 @@ return mh1;
message = wantStatic ? "expected a static method" : "expected a non-static method"; message = wantStatic ? "expected a static method" : "expected a non-static method";
else else
{ checkAccess(refc, m); return; } { checkAccess(refc, m); return; }
throw newNoAccessException(message, m, this); throw m.makeAccessException(message, this);
} }
void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException { void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
@ -1030,7 +1021,7 @@ return mh1;
&& VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass())) && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
// Protected members can also be checked as if they were package-private. // Protected members can also be checked as if they were package-private.
return; return;
throw newNoAccessException(accessFailedMessage(refc, m), m, this); throw m.makeAccessException(accessFailedMessage(refc, m), this);
} }
String accessFailedMessage(Class<?> refc, MemberName m) { String accessFailedMessage(Class<?> refc, MemberName m) {
@ -1064,8 +1055,8 @@ return mh1;
|| (specialCaller != lookupClass() || (specialCaller != lookupClass()
&& !(ALLOW_NESTMATE_ACCESS && && !(ALLOW_NESTMATE_ACCESS &&
VerifyAccess.isSamePackageMember(specialCaller, lookupClass())))) VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
throw newNoAccessException("no private access for invokespecial", throw new MemberName(specialCaller).
new MemberName(specialCaller), this); makeAccessException("no private access for invokespecial", this);
} }
MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException { MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
@ -1084,12 +1075,12 @@ return mh1;
assert(!method.isStatic()); assert(!method.isStatic());
Class<?> defc = method.getDeclaringClass(); // receiver type of mh is too wide Class<?> defc = method.getDeclaringClass(); // receiver type of mh is too wide
if (defc.isInterface() || !defc.isAssignableFrom(caller)) { if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
throw newNoAccessException("caller class must be a subclass below the method", method, caller); throw method.makeAccessException("caller class must be a subclass below the method", caller);
} }
MethodType rawType = mh.type(); MethodType rawType = mh.type();
if (rawType.parameterType(0) == caller) return mh; if (rawType.parameterType(0) == caller) return mh;
MethodType narrowType = rawType.changeParameterType(0, caller); MethodType narrowType = rawType.changeParameterType(0, caller);
MethodHandle narrowMH = MethodHandleImpl.convertArguments(IMPL_TOKEN, mh, narrowType, rawType, null); MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, null);
return fixVarargs(narrowMH, mh); return fixVarargs(narrowMH, mh);
} }
@ -1097,10 +1088,9 @@ return mh1;
boolean isStatic, boolean isSetter) throws NoSuchFieldException, IllegalAccessException { boolean isStatic, boolean isSetter) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(refc, name, type, isStatic); MemberName field = resolveOrFail(refc, name, type, isStatic);
if (isStatic != field.isStatic()) if (isStatic != field.isStatic())
throw newNoAccessException(isStatic throw field.makeAccessException(isStatic
? "expected a static field" ? "expected a static field"
: "expected a non-static field", : "expected a non-static field", this);
field, this);
return makeAccessor(refc, field, false, isSetter); return makeAccessor(refc, field, false, isSetter);
} }
@ -1108,9 +1098,9 @@ return mh1;
boolean trusted, boolean isSetter) throws IllegalAccessException { boolean trusted, boolean isSetter) throws IllegalAccessException {
assert(field.isField()); assert(field.isField());
if (trusted) if (trusted)
return MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull()); return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
checkAccess(refc, field); checkAccess(refc, field);
MethodHandle mh = MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull()); MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
return restrictProtectedReceiver(field, mh); return restrictProtectedReceiver(field, mh);
} }
} }
@ -1127,7 +1117,7 @@ return mh1;
*/ */
public static public static
MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException { MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, false); return MethodHandleImpl.accessArrayElement(arrayClass, false);
} }
/** /**
@ -1141,7 +1131,7 @@ return mh1;
*/ */
public static public static
MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException { MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, true); return MethodHandleImpl.accessArrayElement(arrayClass, true);
} }
/// method handle invocation (reflective style) /// method handle invocation (reflective style)
@ -1191,7 +1181,7 @@ return invoker;
MethodHandle spreadInvoker(MethodType type, int objectArgCount) { MethodHandle spreadInvoker(MethodType type, int objectArgCount) {
if (objectArgCount < 0 || objectArgCount > type.parameterCount()) if (objectArgCount < 0 || objectArgCount > type.parameterCount())
throw new IllegalArgumentException("bad argument count "+objectArgCount); throw new IllegalArgumentException("bad argument count "+objectArgCount);
return invokers(type).spreadInvoker(objectArgCount); return type.invokers().spreadInvoker(objectArgCount);
} }
/** /**
@ -1231,7 +1221,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
*/ */
static public static public
MethodHandle exactInvoker(MethodType type) { MethodHandle exactInvoker(MethodType type) {
return invokers(type).exactInvoker(); return type.invokers().exactInvoker();
} }
/** /**
@ -1258,11 +1248,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
*/ */
static public static public
MethodHandle genericInvoker(MethodType type) { MethodHandle genericInvoker(MethodType type) {
return invokers(type).genericInvoker(); return type.invokers().genericInvoker();
}
static Invokers invokers(MethodType type) {
return MethodTypeImpl.invokers(IMPL_TOKEN, type);
} }
/** /**
@ -1387,7 +1373,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
return target; return target;
MethodHandle res = null; MethodHandle res = null;
try { try {
res = MethodHandleImpl.convertArguments(IMPL_TOKEN, target, res = MethodHandleImpl.convertArguments(target,
newType, oldType, null); newType, oldType, null);
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
} }
@ -1531,7 +1517,7 @@ assert((int)twice.invokeExact(21) == 42);
MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) { MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
MethodType oldType = target.type(); MethodType oldType = target.type();
checkReorder(reorder, newType, oldType); checkReorder(reorder, newType, oldType);
return MethodHandleImpl.convertArguments(IMPL_TOKEN, target, return MethodHandleImpl.convertArguments(target,
newType, oldType, newType, oldType,
reorder); reorder);
} }
@ -1574,7 +1560,7 @@ assert((int)twice.invokeExact(21) == 42);
int numSpread = (outargs - spreadPos); int numSpread = (outargs - spreadPos);
MethodHandle res = null; MethodHandle res = null;
if (spreadPos >= 0 && numSpread >= 0) { if (spreadPos >= 0 && numSpread >= 0) {
res = MethodHandleImpl.spreadArguments(IMPL_TOKEN, target, newType, spreadPos); res = MethodHandleImpl.spreadArguments(target, newType, spreadPos);
} }
if (res == null) { if (res == null) {
throw newIllegalArgumentException("cannot spread "+newType+" to " +oldType); throw newIllegalArgumentException("cannot spread "+newType+" to " +oldType);
@ -1607,7 +1593,7 @@ assert((int)twice.invokeExact(21) == 42);
int numCollect = (inargs - collectPos); int numCollect = (inargs - collectPos);
if (collectPos < 0 || numCollect < 0) if (collectPos < 0 || numCollect < 0)
throw newIllegalArgumentException("wrong number of arguments"); throw newIllegalArgumentException("wrong number of arguments");
MethodHandle res = MethodHandleImpl.collectArguments(IMPL_TOKEN, target, newType, collectPos, null); MethodHandle res = MethodHandleImpl.collectArguments(target, newType, collectPos, null);
if (res == null) { if (res == null) {
throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType); throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType);
} }
@ -1654,7 +1640,13 @@ assert((int)twice.invokeExact(21) == 42);
MethodHandle identity(Class<?> type) { MethodHandle identity(Class<?> type) {
if (type == void.class) if (type == void.class)
throw newIllegalArgumentException("void type"); throw newIllegalArgumentException("void type");
return ValueConversions.identity(type); else if (type == Object.class)
return ValueConversions.identity();
else if (type.isPrimitive())
return ValueConversions.identity(Wrapper.forPrimitiveType(type));
else
return AdapterMethodHandle.makeRetypeRaw(
MethodType.methodType(type, type), ValueConversions.identity());
} }
/** /**
@ -1686,8 +1678,6 @@ assert((int)twice.invokeExact(21) == 42);
MethodHandle insertArguments(MethodHandle target, int pos, Object... values) { MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
int insCount = values.length; int insCount = values.length;
MethodType oldType = target.type(); MethodType oldType = target.type();
ArrayList<Class<?>> ptypes =
new ArrayList<Class<?>>(oldType.parameterList());
int outargs = oldType.parameterCount(); int outargs = oldType.parameterCount();
int inargs = outargs - insCount; int inargs = outargs - insCount;
if (inargs < 0) if (inargs < 0)
@ -1701,14 +1691,14 @@ assert((int)twice.invokeExact(21) == 42);
value = checkValue(valueType, value); value = checkValue(valueType, value);
if (pos == 0 && !valueType.isPrimitive()) { if (pos == 0 && !valueType.isPrimitive()) {
// At least for now, make bound method handles a special case. // At least for now, make bound method handles a special case.
MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, result, value); MethodHandle bmh = MethodHandleImpl.bindReceiver(result, value);
if (bmh != null) { if (bmh != null) {
result = bmh; result = bmh;
continue; continue;
} }
// else fall through to general adapter machinery // else fall through to general adapter machinery
} }
result = MethodHandleImpl.bindArgument(IMPL_TOKEN, result, pos, value); result = MethodHandleImpl.bindArgument(result, pos, value);
} }
return result; return result;
} }
@ -1726,20 +1716,21 @@ assert((int)twice.invokeExact(21) == 42);
* <p> * <p>
* <b>Example:</b> * <b>Example:</b>
* <p><blockquote><pre> * <p><blockquote><pre>
import static java.dyn.MethodHandles.*; import static java.lang.invoke.MethodHandles.*;
import static java.dyn.MethodType.*; import static java.lang.invoke.MethodType.*;
... ...
MethodHandle cat = lookup().findVirtual(String.class, MethodHandle cat = lookup().findVirtual(String.class,
"concat", methodType(String.class, String.class)); "concat", methodType(String.class, String.class));
assertEquals("xy", (String) cat.invokeExact("x", "y")); assertEquals("xy", (String) cat.invokeExact("x", "y"));
MethodHandle d0 = dropArguments(cat, 0, String.class); MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
assertEquals("yz", (String) d0.invokeExact("x", "y", "z")); MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
MethodHandle d1 = dropArguments(cat, 1, String.class); assertEquals(bigType, d0.type());
assertEquals("xz", (String) d1.invokeExact("x", "y", "z")); assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
MethodHandle d2 = dropArguments(cat, 2, String.class); * </pre></blockquote>
assertEquals("xy", (String) d2.invokeExact("x", "y", "z")); * <p>
MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class); * This method is also equivalent to the following code:
assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z")); * <p><blockquote><pre>
* {@link #dropArguments(MethodHandle,int,Class...) dropArguments}(target, pos, valueTypes.toArray(new Class[0]))
* </pre></blockquote> * </pre></blockquote>
* @param target the method handle to invoke after the arguments are dropped * @param target the method handle to invoke after the arguments are dropped
* @param valueTypes the type(s) of the argument(s) to drop * @param valueTypes the type(s) of the argument(s) to drop
@ -1762,7 +1753,7 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
new ArrayList<Class<?>>(oldType.parameterList()); new ArrayList<Class<?>>(oldType.parameterList());
ptypes.addAll(pos, valueTypes); ptypes.addAll(pos, valueTypes);
MethodType newType = MethodType.methodType(oldType.returnType(), ptypes); MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
return MethodHandleImpl.dropArguments(IMPL_TOKEN, target, newType, pos); return MethodHandleImpl.dropArguments(target, newType, pos);
} }
/** /**
@ -1770,10 +1761,34 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
* after dropping the given argument(s) at the given position. * after dropping the given argument(s) at the given position.
* The type of the new method handle will insert the given argument * The type of the new method handle will insert the given argument
* type(s), at that position, into the original handle's type. * type(s), at that position, into the original handle's type.
* This method is equivalent to the following code: * <p>
* <code> * The <i>pos</i> may range between zero and <i>N</i>,
* where <i>N</i> is the number of argument types in <i>target</i>,
* meaning to drop the first or last argument (respectively),
* or an argument somewhere in between.
* <p>
* <b>Example:</b>
* <p><blockquote><pre>
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
MethodHandle cat = lookup().findVirtual(String.class,
"concat", methodType(String.class, String.class));
assertEquals("xy", (String) cat.invokeExact("x", "y"));
MethodHandle d0 = dropArguments(cat, 0, String.class);
assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
MethodHandle d1 = dropArguments(cat, 1, String.class);
assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
MethodHandle d2 = dropArguments(cat, 2, String.class);
assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
* </pre></blockquote>
* <p>
* This method is also equivalent to the following code:
* <p><blockquote><pre>
* {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes)) * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
* </code> * </pre></blockquote>
* @param target the method handle to invoke after the arguments are dropped * @param target the method handle to invoke after the arguments are dropped
* @param valueTypes the type(s) of the argument(s) to drop * @param valueTypes the type(s) of the argument(s) to drop
* @param pos position of first argument to drop (zero for the leftmost) * @param pos position of first argument to drop (zero for the leftmost)
@ -1789,7 +1804,7 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
} }
/** /**
* Adapt a target method handle {@code target} by pre-processing * Adapts a target method handle {@code target} by pre-processing
* one or more of its arguments, each with its own unary filter function, * one or more of its arguments, each with its own unary filter function,
* and then calling the target with each pre-processed argument * and then calling the target with each pre-processed argument
* replaced by the result of its corresponding filter function. * replaced by the result of its corresponding filter function.
@ -1812,8 +1827,8 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
* which do not correspond to argument positions in the target. * which do not correspond to argument positions in the target.
* <b>Example:</b> * <b>Example:</b>
* <p><blockquote><pre> * <p><blockquote><pre>
import static java.dyn.MethodHandles.*; import static java.lang.invoke.MethodHandles.*;
import static java.dyn.MethodType.*; import static java.lang.invoke.MethodType.*;
... ...
MethodHandle cat = lookup().findVirtual(String.class, MethodHandle cat = lookup().findVirtual(String.class,
"concat", methodType(String.class, String.class)); "concat", methodType(String.class, String.class));
@ -1855,16 +1870,16 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
|| filterType.returnType() != targetType.parameterType(curPos)) || filterType.returnType() != targetType.parameterType(curPos))
throw newIllegalArgumentException("target and filter types do not match"); throw newIllegalArgumentException("target and filter types do not match");
adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0)); adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
adapter = MethodHandleImpl.filterArgument(IMPL_TOKEN, adapter, curPos, filter); adapter = MethodHandleImpl.filterArgument(adapter, curPos, filter);
} }
MethodType midType = adapter.type(); MethodType midType = adapter.type();
if (midType != adapterType) if (midType != adapterType)
adapter = MethodHandleImpl.convertArguments(IMPL_TOKEN, adapter, adapterType, midType, null); adapter = MethodHandleImpl.convertArguments(adapter, adapterType, midType, null);
return adapter; return adapter;
} }
/** /**
* Adapt a target method handle {@code target} by post-processing * Adapts a target method handle {@code target} by post-processing
* its return value with a unary filter function. * its return value with a unary filter function.
* <p> * <p>
* If a filter {@code F} applies to the return value of * If a filter {@code F} applies to the return value of
@ -1876,8 +1891,8 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
* return type of the target. * return type of the target.
* <b>Example:</b> * <b>Example:</b>
* <p><blockquote><pre> * <p><blockquote><pre>
import static java.dyn.MethodHandles.*; import static java.lang.invoke.MethodHandles.*;
import static java.dyn.MethodType.*; import static java.lang.invoke.MethodType.*;
... ...
MethodHandle cat = lookup().findVirtual(String.class, MethodHandle cat = lookup().findVirtual(String.class,
"concat", methodType(String.class, String.class)); "concat", methodType(String.class, String.class));
@ -1909,7 +1924,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
} }
/** /**
* Adapt a target method handle {@code target} by pre-processing * Adapts a target method handle {@code target} by pre-processing
* some of its arguments, and then calling the target with * some of its arguments, and then calling the target with
* the result of the pre-processing, plus all original arguments. * the result of the pre-processing, plus all original arguments.
* <p> * <p>
@ -1966,11 +1981,11 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
if (!ok) if (!ok)
throw misMatchedTypes("target and combiner types", targetType, combinerType); throw misMatchedTypes("target and combiner types", targetType, combinerType);
MethodType newType = targetType.dropParameterTypes(0, 1); MethodType newType = targetType.dropParameterTypes(0, 1);
return MethodHandleImpl.foldArguments(IMPL_TOKEN, target, newType, combiner); return MethodHandleImpl.foldArguments(target, newType, combiner);
} }
/** /**
* Make a method handle which adapts a target method handle, * Makes a method handle which adapts a target method handle,
* by guarding it with a test, a boolean-valued method handle. * by guarding it with a test, a boolean-valued method handle.
* If the guard fails, a fallback handle is called instead. * If the guard fails, a fallback handle is called instead.
* All three method handles must have the same corresponding * All three method handles must have the same corresponding
@ -2021,7 +2036,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
test = dropArguments(test, gpc, targs.subList(gpc, tpc)); test = dropArguments(test, gpc, targs.subList(gpc, tpc));
gtype = test.type(); gtype = test.type();
} }
return MethodHandleImpl.makeGuardWithTest(IMPL_TOKEN, test, target, fallback); return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
} }
static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) { static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
@ -2029,7 +2044,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
} }
/** /**
* Make a method handle which adapts a target method handle, * Makes a method handle which adapts a target method handle,
* by running it inside an exception handler. * by running it inside an exception handler.
* If the target returns normally, the adapter returns that value. * If the target returns normally, the adapter returns that value.
* If an exception matching the specified type is thrown, the fallback * If an exception matching the specified type is thrown, the fallback
@ -2092,7 +2107,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
handler = dropArguments(handler, hpc, hargs.subList(hpc, tpc)); handler = dropArguments(handler, hpc, hargs.subList(hpc, tpc));
htype = handler.type(); htype = handler.type();
} }
return MethodHandleImpl.makeGuardWithCatch(IMPL_TOKEN, target, exType, handler); return MethodHandleImpl.makeGuardWithCatch(target, exType, handler);
} }
/** /**
@ -2107,51 +2122,45 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
*/ */
public static public static
MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) { MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType)); return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
} }
/** /**
* Produces an instance of the given "SAM" interface which redirects * Produces an instance of the given single-method interface which redirects
* its calls to the given method handle. * its calls to the given method handle.
* <p> * <p>
* A SAM interface is an interface which declares a single abstract method. * A single-method interface is an interface which declares a unique method.
* When determining the unique abstract method of a SAM interface, * When determining the unique method of a single-method interface,
* the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode}) * the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode})
* are disregarded. For example, {@link java.util.Comparator} is a SAM interface, * are disregarded. For example, {@link java.util.Comparator} is a single-method interface,
* even though it re-declares the {@code Object.equals} method. * even though it re-declares the {@code Object.equals} method.
* Also, if the SAM interface has a supertype,
* the SAM interface may override an inherited method.
* Any such overrides are respected, and the method handle will be accessible
* by either the inherited method or the SAM method.
* In particular, a {@linkplain java.lang.reflect.Method#isBridge bridge method}
* may be created if the methods have different return types.
* <p> * <p>
* The type must be public. No additional access checks are performed. * The type must be public. No additional access checks are performed.
* <p> * <p>
* The resulting instance of the required SAM type will respond to * The resulting instance of the required type will respond to
* invocation of the SAM type's single abstract method by calling * invocation of the type's single abstract method by calling
* the given {@code target} on the incoming arguments, * the given {@code target} on the incoming arguments,
* and returning or throwing whatever the {@code target} * and returning or throwing whatever the {@code target}
* returns or throws. The invocation will be as if by * returns or throws. The invocation will be as if by
* {@code target.invokeGeneric}. * {@code target.invokeGeneric}.
* The target's type will be checked before the SAM * The target's type will be checked before the
* instance is created, as if by a call to {@code asType}, * instance is created, as if by a call to {@code asType},
* which may result in a {@code WrongMethodTypeException}. * which may result in a {@code WrongMethodTypeException}.
* <p> * <p>
* The wrapper instance will implement the requested SAM interface * The wrapper instance will implement the requested interface
* and its super-types, but no other SAM types. * and its super-types, but no other single-method interfaces.
* This means that the SAM instance will not unexpectedly * This means that the instance will not unexpectedly
* pass an {@code instanceof} test for any unrequested type. * pass an {@code instanceof} test for any unrequested type.
* <p style="font-size:smaller;"> * <p style="font-size:smaller;">
* <em>Implementation Note:</em> * <em>Implementation Note:</em>
* Therefore, each SAM instance must implement a unique SAM type. * Therefore, each instance must implement a unique single-method interface.
* Implementations may not bundle together * Implementations may not bundle together
* multiple SAM types onto single implementation classes * multiple single-method interfaces onto single implementation classes
* in the style of {@link java.awt.AWTEventMulticaster}. * in the style of {@link java.awt.AWTEventMulticaster}.
* <p> * <p>
* The method handle may throw an <em>undeclared exception</em>, * The method handle may throw an <em>undeclared exception</em>,
* which means any checked exception (or other checked throwable) * which means any checked exception (or other checked throwable)
* not declared by the SAM type's single abstract method. * not declared by the requested type's single abstract method.
* If this happens, the throwable will be wrapped in an instance of * If this happens, the throwable will be wrapped in an instance of
* {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException} * {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException}
* and thrown in that wrapped form. * and thrown in that wrapped form.
@ -2161,28 +2170,37 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
* by their behavior. * by their behavior.
* It is not guaranteed to return a new instance for every call. * It is not guaranteed to return a new instance for every call.
* <p> * <p>
* Because of the possibility of {@linkplain java.lang.reflect.Method#isBridge bridge methods}
* and other corner cases, the interface may also have several abstract methods
* with the same name but having distinct descriptors (types of returns and parameters).
* In this case, all the methods are bound in common to the one given {@code target}.
* The type check and effective {@code asType} conversion is applied to each
* method type descriptor, and all abstract methods are bound to the {@code target} in common.
* Beyond this type check, no further checks are made to determine that the
* abstract methods are related in any way.
* <p>
* Future versions of this API may accept additional types, * Future versions of this API may accept additional types,
* such as abstract classes with single abstract methods. * such as abstract classes with single abstract methods.
* Future versions of this API may also equip wrapper instances * Future versions of this API may also equip wrapper instances
* with one or more additional public "marker" interfaces. * with one or more additional public "marker" interfaces.
* *
* @param target the method handle to invoke from the wrapper * @param target the method handle to invoke from the wrapper
* @param samType the desired type of the wrapper, a SAM type * @param smType the desired type of the wrapper, a single-method interface
* @return a correctly-typed wrapper for the given {@code target} * @return a correctly-typed wrapper for the given {@code target}
* @throws NullPointerException if either argument is null * @throws NullPointerException if either argument is null
* @throws IllegalArgumentException if the {@code samType} is not a * @throws IllegalArgumentException if the {@code smType} is not a
* valid argument to this method * valid argument to this method
* @throws WrongMethodTypeException if the {@code target} cannot * @throws WrongMethodTypeException if the {@code target} cannot
* be converted to the type required by the SAM type * be converted to the type required by the requested interface
*/ */
// Other notes to implementors: // Other notes to implementors:
// <p> // <p>
// No stable mapping is promised between the SAM type and // No stable mapping is promised between the single-method interface and
// the implementation class C. Over time, several implementation // the implementation class C. Over time, several implementation
// classes might be used for the same SAM type. // classes might be used for the same type.
// <p> // <p>
// If the implementation is able // If the implementation is able
// to prove that a wrapper of the required SAM type // to prove that a wrapper of the required type
// has already been created for a given // has already been created for a given
// method handle, or for another method handle with the // method handle, or for another method handle with the
// same behavior, the implementation may return that wrapper in place of // same behavior, the implementation may return that wrapper in place of
@ -2191,34 +2209,34 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
// This method is designed to apply to common use cases // This method is designed to apply to common use cases
// where a single method handle must interoperate with // where a single method handle must interoperate with
// an interface that implements a function-like // an interface that implements a function-like
// API. Additional variations, such as SAM classes with // API. Additional variations, such as single-abstract-method classes with
// private constructors, or interfaces with multiple but related // private constructors, or interfaces with multiple but related
// entry points, must be covered by hand-written or automatically // entry points, must be covered by hand-written or automatically
// generated adapter classes. // generated adapter classes.
// //
public static public static
<T> T asInstance(final MethodHandle target, final Class<T> samType) { <T> T asInstance(final MethodHandle target, final Class<T> smType) {
// POC implementation only; violates the above contract several ways // POC implementation only; violates the above contract several ways
final Method sam = getSamMethod(samType); final Method sm = getSingleMethod(smType);
if (sam == null) if (sm == null)
throw new IllegalArgumentException("not a SAM type: "+samType.getName()); throw new IllegalArgumentException("not a single-method interface: "+smType.getName());
MethodType samMT = MethodType.methodType(sam.getReturnType(), sam.getParameterTypes()); MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
MethodHandle checkTarget = target.asType(samMT); // make throw WMT MethodHandle checkTarget = target.asType(smMT); // make throw WMT
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class)); checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
final MethodHandle vaTarget = checkTarget.asSpreader(Object[].class, samMT.parameterCount()); final MethodHandle vaTarget = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
return samType.cast(Proxy.newProxyInstance( return smType.cast(Proxy.newProxyInstance(
samType.getClassLoader(), smType.getClassLoader(),
new Class[]{ samType, WrapperInstance.class }, new Class[]{ smType, WrapperInstance.class },
new InvocationHandler() { new InvocationHandler() {
private Object getArg(String name) { private Object getArg(String name) {
if ((Object)name == "getWrapperInstanceTarget") return target; if ((Object)name == "getWrapperInstanceTarget") return target;
if ((Object)name == "getWrapperInstanceType") return samType; if ((Object)name == "getWrapperInstanceType") return smType;
throw new AssertionError(); throw new AssertionError();
} }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getDeclaringClass() == WrapperInstance.class) if (method.getDeclaringClass() == WrapperInstance.class)
return getArg(method.getName()); return getArg(method.getName());
if (method.equals(sam)) if (method.equals(sm))
return vaTarget.invokeExact(args); return vaTarget.invokeExact(args);
if (isObjectMethod(method)) if (isObjectMethod(method))
return callObjectMethod(this, method, args); return callObjectMethod(this, method, args);
@ -2228,7 +2246,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
} }
/** /**
* Determine if the given object was produced by a call to {@link #asInstance asInstance}. * Determines if the given object was produced by a call to {@link #asInstance asInstance}.
* @param x any reference * @param x any reference
* @return true if the reference is not null and points to an object produced by {@code asInstance} * @return true if the reference is not null and points to an object produced by {@code asInstance}
*/ */
@ -2248,11 +2266,11 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
/** /**
* Produces or recovers a target method handle which is behaviorally * Produces or recovers a target method handle which is behaviorally
* equivalent to the SAM method of this wrapper instance. * equivalent to the unique method of this wrapper instance.
* The object {@code x} must have been produced by a call to {@link #asInstance asInstance}. * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
* This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}. * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
* @param x any reference * @param x any reference
* @return a method handle implementing the SAM method * @return a method handle implementing the unique method
* @throws IllegalArgumentException if the reference x is not to a wrapper instance * @throws IllegalArgumentException if the reference x is not to a wrapper instance
*/ */
public static public static
@ -2261,11 +2279,11 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
} }
/** /**
* Recover the SAM type for which this wrapper instance was created. * Recovers the unique single-method interface type for which this wrapper instance was created.
* The object {@code x} must have been produced by a call to {@link #asInstance asInstance}. * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
* This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}. * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
* @param x any reference * @param x any reference
* @return the SAM type for which the wrapper was created * @return the single-method interface type for which the wrapper was created
* @throws IllegalArgumentException if the reference x is not to a wrapper instance * @throws IllegalArgumentException if the reference x is not to a wrapper instance
*/ */
public static public static
@ -2305,24 +2323,24 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
} }
private static private static
Method getSamMethod(Class<?> samType) { Method getSingleMethod(Class<?> smType) {
Method sam = null; Method sm = null;
for (Method m : samType.getMethods()) { for (Method m : smType.getMethods()) {
int mod = m.getModifiers(); int mod = m.getModifiers();
if (Modifier.isAbstract(mod)) { if (Modifier.isAbstract(mod)) {
if (sam != null && !isObjectMethod(sam)) if (sm != null && !isObjectMethod(sm))
return null; // too many abstract methods return null; // too many abstract methods
sam = m; sm = m;
} }
} }
if (!samType.isInterface() && getSamConstructor(samType) == null) if (!smType.isInterface() && getSingleConstructor(smType) == null)
return null; // wrong kind of constructor return null; // wrong kind of constructor
return sam; return sm;
} }
private static private static
Constructor getSamConstructor(Class<?> samType) { Constructor getSingleConstructor(Class<?> smType) {
for (Constructor c : samType.getDeclaredConstructors()) { for (Constructor c : smType.getDeclaredConstructors()) {
if (c.getParameterTypes().length == 0) { if (c.getParameterTypes().length == 0) {
int mod = c.getModifiers(); int mod = c.getModifiers();
if (Modifier.isPublic(mod) || Modifier.isProtected(mod)) if (Modifier.isPublic(mod) || Modifier.isProtected(mod))
@ -2334,6 +2352,6 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
/*non-public*/ /*non-public*/
static MethodHandle asVarargsCollector(MethodHandle target, Class<?> arrayType) { static MethodHandle asVarargsCollector(MethodHandle target, Class<?> arrayType) {
return MethodHandleImpl.asVarargsCollector(IMPL_TOKEN, target, arrayType); return MethodHandleImpl.asVarargsCollector(target, arrayType);
} }
} }

View File

@ -23,18 +23,14 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import sun.dyn.Access; import sun.invoke.util.BytecodeDescriptor;
import sun.dyn.Invokers; import static java.lang.invoke.MethodHandleStatics.*;
import sun.dyn.MethodHandleImpl;
import sun.dyn.MethodTypeImpl;
import sun.dyn.util.BytecodeDescriptor;
import static sun.dyn.MemberName.newIllegalArgumentException;
/** /**
* A method type represents the arguments and return type accepted and * A method type represents the arguments and return type accepted and
@ -96,34 +92,6 @@ class MethodType implements java.io.Serializable {
private MethodType wrapAlt; // alternative wrapped/unwrapped version private MethodType wrapAlt; // alternative wrapped/unwrapped version
private Invokers invokers; // cache of handy higher-order adapters private Invokers invokers; // cache of handy higher-order adapters
private static final Access IMPL_TOKEN = Access.getToken();
// share a cache with a friend in this package
Invokers getInvokers() { return invokers; }
void setInvokers(Invokers inv) { invokers = inv; }
static {
// This hack allows the implementation package special access to
// the internals of MethodType. In particular, the MTImpl has all sorts
// of cached information useful to the implementation code.
MethodTypeImpl.setMethodTypeFriend(IMPL_TOKEN, new MethodTypeImpl.MethodTypeFriend() {
public Class<?>[] ptypes(MethodType mt) { return mt.ptypes; }
public MethodTypeImpl form(MethodType mt) { return mt.form; }
public void setForm(MethodType mt, MethodTypeImpl form) {
assert(mt.form == null);
mt.form = (MethodTypeForm) form;
}
public MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
return MethodType.makeImpl(rtype, ptypes, trusted);
}
public MethodTypeImpl newMethodTypeForm(MethodType mt) {
return new MethodTypeForm(mt);
}
public Invokers getInvokers(MethodType mt) { return mt.invokers; }
public void setInvokers(MethodType mt, Invokers inv) { mt.invokers = inv; }
});
}
/** /**
* Check the given parameters for validity and store them into the final fields. * Check the given parameters for validity and store them into the final fields.
*/ */
@ -134,6 +102,10 @@ class MethodType implements java.io.Serializable {
this.ptypes = ptypes; this.ptypes = ptypes;
} }
/*trusted*/ MethodTypeForm form() { return form; }
/*trusted*/ Class<?> rtype() { return rtype; }
/*trusted*/ Class<?>[] ptypes() { return ptypes; }
private static void checkRtype(Class<?> rtype) { private static void checkRtype(Class<?> rtype) {
rtype.equals(rtype); // null check rtype.equals(rtype); // null check
} }
@ -168,7 +140,7 @@ class MethodType implements java.io.Serializable {
static final Class<?>[] NO_PTYPES = {}; static final Class<?>[] NO_PTYPES = {};
/** /**
* Find or create an instance of the given method type. * Finds or creates an instance of the given method type.
* @param rtype the return type * @param rtype the return type
* @param ptypes the parameter types * @param ptypes the parameter types
* @return a method type with the given components * @return a method type with the given components
@ -253,7 +225,7 @@ class MethodType implements java.io.Serializable {
* @param trusted whether the ptypes can be used without cloning * @param trusted whether the ptypes can be used without cloning
* @return the unique method type of the desired structure * @return the unique method type of the desired structure
*/ */
private static /*trusted*/ static
MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) { MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
if (ptypes == null || ptypes.length == 0) { if (ptypes == null || ptypes.length == 0) {
ptypes = NO_PTYPES; trusted = true; ptypes = NO_PTYPES; trusted = true;
@ -269,7 +241,12 @@ class MethodType implements java.io.Serializable {
// defensively copy the array passed in by the user // defensively copy the array passed in by the user
mt1 = new MethodType(rtype, ptypes.clone()); mt1 = new MethodType(rtype, ptypes.clone());
// promote the object to the Real Thing, and reprobe // promote the object to the Real Thing, and reprobe
MethodTypeImpl.initForm(IMPL_TOKEN, mt1); MethodTypeForm form = MethodTypeForm.findForm(mt1);
mt1.form = form;
if (form.erasedType == mt1) {
// This is a principal (erased) type; show it to the JVM.
MethodHandleNatives.init(mt1);
}
synchronized (internTable) { synchronized (internTable) {
mt0 = internTable.get(mt1); mt0 = internTable.get(mt1);
if (mt0 != null) if (mt0 != null)
@ -279,12 +256,6 @@ class MethodType implements java.io.Serializable {
return mt1; return mt1;
} }
// Entry point from JVM. TODO: Change the name & signature.
private static MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes,
boolean ignore1, boolean ignore2) {
return makeImpl(rtype, ptypes, true);
}
private static final MethodType[] objectOnlyTypes = new MethodType[20]; private static final MethodType[] objectOnlyTypes = new MethodType[20];
/** /**
@ -519,7 +490,7 @@ class MethodType implements java.io.Serializable {
} }
/** /**
* Convert all wrapper types to their corresponding primitive types. * Converts all wrapper types to their corresponding primitive types.
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}. * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
* All primitive types (including {@code void}) will remain unchanged. * All primitive types (including {@code void}) will remain unchanged.
* A return type of {@code java.lang.Void} is changed to {@code void}. * A return type of {@code java.lang.Void} is changed to {@code void}.
@ -535,7 +506,7 @@ class MethodType implements java.io.Serializable {
MethodType wt = pt.wrapAlt; MethodType wt = pt.wrapAlt;
if (wt == null) { if (wt == null) {
// fill in lazily // fill in lazily
wt = MethodTypeImpl.canonicalize(pt, MethodTypeImpl.WRAP, MethodTypeImpl.WRAP); wt = MethodTypeForm.canonicalize(pt, MethodTypeForm.WRAP, MethodTypeForm.WRAP);
assert(wt != null); assert(wt != null);
pt.wrapAlt = wt; pt.wrapAlt = wt;
} }
@ -547,7 +518,7 @@ class MethodType implements java.io.Serializable {
MethodType uwt = wt.wrapAlt; MethodType uwt = wt.wrapAlt;
if (uwt == null) { if (uwt == null) {
// fill in lazily // fill in lazily
uwt = MethodTypeImpl.canonicalize(wt, MethodTypeImpl.UNWRAP, MethodTypeImpl.UNWRAP); uwt = MethodTypeForm.canonicalize(wt, MethodTypeForm.UNWRAP, MethodTypeForm.UNWRAP);
if (uwt == null) if (uwt == null)
uwt = wt; // type has no wrappers or prims at all uwt = wt; // type has no wrappers or prims at all
wt.wrapAlt = uwt; wt.wrapAlt = uwt;
@ -658,7 +629,7 @@ class MethodType implements java.io.Serializable {
/// Queries which have to do with the bytecode architecture /// Queries which have to do with the bytecode architecture
/** Reports the number of JVM stack slots required to invoke a method /** Reports the number of JVM stack slots required to invoke a method
* of this type. Note that (for historic reasons) the JVM requires * of this type. Note that (for historical reasons) the JVM requires
* a second stack slot to pass long and double arguments. * a second stack slot to pass long and double arguments.
* So this method returns {@link #parameterCount() parameterCount} plus the * So this method returns {@link #parameterCount() parameterCount} plus the
* number of long and double parameters (if any). * number of long and double parameters (if any).
@ -666,12 +637,18 @@ class MethodType implements java.io.Serializable {
* This method is included for the benfit of applications that must * This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic. * generate bytecodes that process method handles and invokedynamic.
* @return the number of JVM stack slots for this type's parameters * @return the number of JVM stack slots for this type's parameters
* @deprecated Will be removed for PFD.
*/ */
public int parameterSlotCount() { /*non-public*/ int parameterSlotCount() {
return form.parameterSlotCount(); return form.parameterSlotCount();
} }
/*non-public*/ Invokers invokers() {
Invokers inv = invokers;
if (inv != null) return inv;
invokers = inv = new Invokers(this);
return inv;
}
/** Reports the number of JVM stack slots which carry all parameters including and after /** Reports the number of JVM stack slots which carry all parameters including and after
* the given position, which must be in the range of 0 to * the given position, which must be in the range of 0 to
* {@code parameterCount} inclusive. Successive parameters are * {@code parameterCount} inclusive. Successive parameters are
@ -694,9 +671,8 @@ class MethodType implements java.io.Serializable {
* @return the index of the (shallowest) JVM stack slot transmitting the * @return the index of the (shallowest) JVM stack slot transmitting the
* given parameter * given parameter
* @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()} * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
* @deprecated Will be removed for PFD.
*/ */
public int parameterSlotDepth(int num) { /*non-public*/ int parameterSlotDepth(int num) {
if (num < 0 || num > ptypes.length) if (num < 0 || num > ptypes.length)
parameterType(num); // force a range check parameterType(num); // force a range check
return form.parameterToArgSlot(num-1); return form.parameterToArgSlot(num-1);
@ -710,14 +686,14 @@ class MethodType implements java.io.Serializable {
* This method is included for the benfit of applications that must * This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic. * generate bytecodes that process method handles and invokedynamic.
* @return the number of JVM stack slots (0, 1, or 2) for this type's return value * @return the number of JVM stack slots (0, 1, or 2) for this type's return value
* @deprecated Will be removed for PFD. * Will be removed for PFD.
*/ */
public int returnSlotCount() { /*non-public*/ int returnSlotCount() {
return form.returnSlotCount(); return form.returnSlotCount();
} }
/** /**
* Find or create an instance of a method type, given the spelling of its bytecode descriptor. * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}. * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
* Any class or interface name embedded in the descriptor string * Any class or interface name embedded in the descriptor string
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)} * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}

View File

@ -23,11 +23,10 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import sun.invoke.util.Wrapper;
import sun.dyn.util.Wrapper; import static java.lang.invoke.MethodHandleStatics.*;
import static sun.dyn.MemberName.newIllegalArgumentException;
/** /**
* Shared information for a group of method types, which differ * Shared information for a group of method types, which differ
@ -42,7 +41,7 @@ import static sun.dyn.MemberName.newIllegalArgumentException;
* No more than half of these are likely to be loaded at once. * No more than half of these are likely to be loaded at once.
* @author John Rose * @author John Rose
*/ */
public class MethodTypeImpl { class MethodTypeForm {
final int[] argToSlotTable, slotToArgTable; final int[] argToSlotTable, slotToArgTable;
final long argCounts; // packed slot & value counts final long argCounts; // packed slot & value counts
final long primCounts; // packed prim & double counts final long primCounts; // packed prim & double counts
@ -66,39 +65,10 @@ public class MethodTypeImpl {
return erasedType; return erasedType;
} }
public static MethodTypeImpl of(MethodType type) { protected MethodTypeForm(MethodType erasedType) {
return METHOD_TYPE_FRIEND.form(type);
}
/** Access methods for the internals of MethodType, supplied to
* MethodTypeImpl as a trusted agent.
*/
static public interface MethodTypeFriend {
Class<?>[] ptypes(MethodType mt);
MethodTypeImpl form(MethodType mt);
void setForm(MethodType mt, MethodTypeImpl form);
MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted);
MethodTypeImpl newMethodTypeForm(MethodType mt);
Invokers getInvokers(MethodType mt);
void setInvokers(MethodType mt, Invokers inv);
}
public static void setMethodTypeFriend(Access token, MethodTypeFriend am) {
Access.check(token);
if (METHOD_TYPE_FRIEND != null)
throw new InternalError(); // just once
METHOD_TYPE_FRIEND = am;
}
static private MethodTypeFriend METHOD_TYPE_FRIEND;
static MethodType makeImpl(Access token, Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
Access.check(token);
return METHOD_TYPE_FRIEND.makeImpl(rtype, ptypes, trusted);
}
protected MethodTypeImpl(MethodType erasedType) {
this.erasedType = erasedType; this.erasedType = erasedType;
Class<?>[] ptypes = METHOD_TYPE_FRIEND.ptypes(erasedType); Class<?>[] ptypes = erasedType.ptypes();
int ptypeCount = ptypes.length; int ptypeCount = ptypes.length;
int pslotCount = ptypeCount; // temp. estimate int pslotCount = ptypeCount; // temp. estimate
int rtypeCount = 1; // temp. estimate int rtypeCount = 1; // temp. estimate
@ -260,7 +230,7 @@ public class MethodTypeImpl {
* the type {@code (Object,int)Object} produces {@code null}. * the type {@code (Object,int)Object} produces {@code null}.
*/ */
public static int[] primsAtEndOrder(MethodType mt) { public static int[] primsAtEndOrder(MethodType mt) {
MethodTypeImpl form = METHOD_TYPE_FRIEND.form(mt); MethodTypeForm form = mt.form();
if (form.primsAtEnd == form.erasedType) if (form.primsAtEnd == form.erasedType)
// quick check shows no reordering is necessary // quick check shows no reordering is necessary
return null; return null;
@ -273,7 +243,7 @@ public class MethodTypeImpl {
int lac = form.longPrimitiveParameterCount(); int lac = form.longPrimitiveParameterCount();
int rfill = 0, ifill = argc - pac, lfill = argc - lac; int rfill = 0, ifill = argc - pac, lfill = argc - lac;
Class<?>[] ptypes = METHOD_TYPE_FRIEND.ptypes(mt); Class<?>[] ptypes = mt.ptypes();
boolean changed = false; boolean changed = false;
for (int i = 0; i < ptypes.length; i++) { for (int i = 0; i < ptypes.length; i++) {
Class<?> pt = ptypes[i]; Class<?> pt = ptypes[i];
@ -300,7 +270,7 @@ public class MethodTypeImpl {
*/ */
public static MethodType reorderParameters(MethodType mt, int[] newParamOrder, Class<?>[] moreParams) { public static MethodType reorderParameters(MethodType mt, int[] newParamOrder, Class<?>[] moreParams) {
if (newParamOrder == null) return mt; // no-op reordering if (newParamOrder == null) return mt; // no-op reordering
Class<?>[] ptypes = METHOD_TYPE_FRIEND.ptypes(mt); Class<?>[] ptypes = mt.ptypes();
Class<?>[] ntypes = new Class<?>[newParamOrder.length]; Class<?>[] ntypes = new Class<?>[newParamOrder.length];
int maxParam = ptypes.length + (moreParams == null ? 0 : moreParams.length); int maxParam = ptypes.length + (moreParams == null ? 0 : moreParams.length);
boolean changed = (ntypes.length != ptypes.length); boolean changed = (ntypes.length != ptypes.length);
@ -314,7 +284,7 @@ public class MethodTypeImpl {
ntypes[i] = nt; ntypes[i] = nt;
} }
if (!changed) return mt; if (!changed) return mt;
return METHOD_TYPE_FRIEND.makeImpl(mt.returnType(), ntypes, true); return MethodType.makeImpl(mt.returnType(), ntypes, true);
} }
private static boolean hasTwoArgSlots(Class<?> type) { private static boolean hasTwoArgSlots(Class<?> type) {
@ -376,28 +346,18 @@ public class MethodTypeImpl {
return slotToArgTable[argSlot] - 1; return slotToArgTable[argSlot] - 1;
} }
public static void initForm(Access token, MethodType mt) { static MethodTypeForm findForm(MethodType mt) {
Access.check(token);
MethodTypeImpl form = findForm(mt);
METHOD_TYPE_FRIEND.setForm(mt, form);
if (form.erasedType == mt) {
// This is a principal (erased) type; show it to the JVM.
MethodHandleImpl.init(token, mt);
}
}
static MethodTypeImpl findForm(MethodType mt) {
MethodType erased = canonicalize(mt, ERASE, ERASE); MethodType erased = canonicalize(mt, ERASE, ERASE);
if (erased == null) { if (erased == null) {
// It is already erased. Make a new MethodTypeImpl. // It is already erased. Make a new MethodTypeForm.
return METHOD_TYPE_FRIEND.newMethodTypeForm(mt); return new MethodTypeForm(mt);
} else { } else {
// Share the MethodTypeImpl with the erased version. // Share the MethodTypeForm with the erased version.
return METHOD_TYPE_FRIEND.form(erased); return erased.form();
} }
} }
/** Codes for {@link #canonicalize(java.lang.Class, int). /** Codes for {@link #canonicalize(java.lang.Class, int)}.
* ERASE means change every reference to {@code Object}. * ERASE means change every reference to {@code Object}.
* WRAP means convert primitives (including {@code void} to their * WRAP means convert primitives (including {@code void} to their
* corresponding wrapper types. UNWRAP means the reverse of WRAP. * corresponding wrapper types. UNWRAP means the reverse of WRAP.
@ -414,10 +374,10 @@ public class MethodTypeImpl {
* Otherwise return null. * Otherwise return null.
*/ */
public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) { public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) {
Class<?>[] ptypes = METHOD_TYPE_FRIEND.ptypes(mt); Class<?>[] ptypes = mt.ptypes();
Class<?>[] ptc = MethodTypeImpl.canonicalizes(ptypes, howArgs); Class<?>[] ptc = MethodTypeForm.canonicalizes(ptypes, howArgs);
Class<?> rtype = mt.returnType(); Class<?> rtype = mt.returnType();
Class<?> rtc = MethodTypeImpl.canonicalize(rtype, howRet); Class<?> rtc = MethodTypeForm.canonicalize(rtype, howRet);
if (ptc == null && rtc == null) { if (ptc == null && rtc == null) {
// It is already canonical. // It is already canonical.
return null; return null;
@ -425,7 +385,7 @@ public class MethodTypeImpl {
// Find the erased version of the method type: // Find the erased version of the method type:
if (rtc == null) rtc = rtype; if (rtc == null) rtc = rtype;
if (ptc == null) ptc = ptypes; if (ptc == null) ptc = ptypes;
return METHOD_TYPE_FRIEND.makeImpl(rtc, ptc, true); return MethodType.makeImpl(rtc, ptc, true);
} }
/** Canonicalize the given return or param type. /** Canonicalize the given return or param type.
@ -496,16 +456,16 @@ public class MethodTypeImpl {
return cs; return cs;
} }
public static Invokers invokers(Access token, MethodType type) { /*non-public*/ void notifyGenericMethodType() {
Access.check(token); if (genericInvoker != null) return;
return invokers(type); try {
} // Trigger adapter creation.
/*non-public*/ static Invokers invokers(MethodType type) { genericInvoker = InvokeGeneric.genericInvokerOf(erasedType);
Invokers inv = METHOD_TYPE_FRIEND.getInvokers(type); } catch (Exception ex) {
if (inv != null) return inv; Error err = new InternalError("Exception while resolving invokeGeneric");
inv = new Invokers(type); err.initCause(ex);
METHOD_TYPE_FRIEND.setInvokers(type, inv); throw err;
return inv; }
} }
@Override @Override

View File

@ -23,10 +23,8 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
import sun.dyn.*;
import sun.dyn.empty.Empty;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,14 +23,14 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*; import sun.invoke.util.ValueConversions;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import sun.dyn.util.ValueConversions; import static java.lang.invoke.MethodHandleStatics.*;
import static sun.dyn.MemberName.newIllegalArgumentException; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* Generic spread adapter. * Generic spread adapter.
@ -110,7 +110,7 @@ class SpreadGeneric {
static SpreadGeneric of(MethodType targetType, int spreadCount) { static SpreadGeneric of(MethodType targetType, int spreadCount) {
if (targetType != targetType.generic()) if (targetType != targetType.generic())
throw new UnsupportedOperationException("NYI type="+targetType); throw new UnsupportedOperationException("NYI type="+targetType);
MethodTypeImpl form = MethodTypeImpl.of(targetType); MethodTypeForm form = targetType.form();
int outcount = form.parameterCount(); int outcount = form.parameterCount();
assert(spreadCount <= outcount); assert(spreadCount <= outcount);
SpreadGeneric[] spreadGens = form.spreadGeneric; SpreadGeneric[] spreadGens = form.spreadGeneric;
@ -129,7 +129,7 @@ class SpreadGeneric {
// This mini-api is called from an Adapter to manage the spread. // This mini-api is called from an Adapter to manage the spread.
/** A check/coercion that happens once before any selections. */ /** A check/coercion that happens once before any selections. */
protected Object check(Object av, int n) { protected Object check(Object av, int n) {
MethodHandleImpl.checkSpreadArgument(av, n); checkSpreadArgument(av, n);
return av; return av;
} }
@ -166,7 +166,7 @@ class SpreadGeneric {
// see if it has the required invoke method // see if it has the required invoke method
MethodHandle entryPoint = null; MethodHandle entryPoint = null;
try { try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls); entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
} }
if (entryPoint == null) continue; if (entryPoint == null) continue;
@ -221,21 +221,21 @@ class SpreadGeneric {
@Override @Override
public String toString() { public String toString() {
return MethodHandleImpl.addTypeString(target, this); return addTypeString(target, this);
} }
static final MethodHandle NO_ENTRY = ValueConversions.identity(); static final MethodHandle NO_ENTRY = ValueConversions.identity();
protected boolean isPrototype() { return target == null; } protected boolean isPrototype() { return target == null; }
protected Adapter(SpreadGeneric outer) { protected Adapter(SpreadGeneric outer) {
super(Access.TOKEN, NO_ENTRY); super(NO_ENTRY);
this.outer = outer; this.outer = outer;
this.target = null; this.target = null;
assert(isPrototype()); assert(isPrototype());
} }
protected Adapter(SpreadGeneric outer, MethodHandle target) { protected Adapter(SpreadGeneric outer, MethodHandle target) {
super(Access.TOKEN, outer.entryPoint); super(outer.entryPoint);
this.outer = outer; this.outer = outer;
this.target = target; this.target = target;
} }
@ -251,7 +251,7 @@ class SpreadGeneric {
return outer.select(av, n); return outer.select(av, n);
} }
static private final String CLASS_PREFIX; // "sun.dyn.SpreadGeneric$" static private final String CLASS_PREFIX; // "java.lang.invoke.SpreadGeneric$"
static { static {
String aname = Adapter.class.getName(); String aname = Adapter.class.getName();
String sname = Adapter.class.getSimpleName(); String sname = Adapter.class.getSimpleName();

View File

@ -23,7 +23,7 @@
* questions. * questions.
*/ */
package java.dyn; package java.lang.invoke;
/** /**
* <p> * <p>
@ -73,6 +73,10 @@ assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
* Switch points are useful without subclassing. They may also be subclassed. * Switch points are useful without subclassing. They may also be subclassed.
* This may be useful in order to associate application-specific invalidation logic * This may be useful in order to associate application-specific invalidation logic
* with the switch point. * with the switch point.
* Notice that there is no permanent association between a switch point and
* the method handles it produces and consumes.
* The garbage collector may collect method handles produced or consumed
* by a switch point independently of the lifetime of the switch point itself.
* <p style="font-size:smaller;"> * <p style="font-size:smaller;">
* <em>Implementation Note:</em> * <em>Implementation Note:</em>
* A switch point behaves as if implemented on top of {@link MutableCallSite}, * A switch point behaves as if implemented on top of {@link MutableCallSite},

View File

@ -23,15 +23,14 @@
* questions. * questions.
*/ */
package sun.dyn; package java.lang.invoke;
import java.dyn.*;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import sun.dyn.util.ValueConversions; import sun.invoke.util.ValueConversions;
import sun.dyn.util.Wrapper; import sun.invoke.util.Wrapper;
import static sun.dyn.MemberName.newIllegalArgumentException; import static java.lang.invoke.MethodHandleStatics.*;
import static sun.dyn.MethodTypeImpl.invokers; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/** /**
* Adapters which mediate between incoming calls which are not generic * Adapters which mediate between incoming calls which are not generic
@ -73,7 +72,7 @@ class ToGeneric {
assert(entryType.erase() == entryType); // for now assert(entryType.erase() == entryType); // for now
// incoming call will first "forget" all reference types except Object // incoming call will first "forget" all reference types except Object
this.entryType = entryType; this.entryType = entryType;
MethodHandle invoker0 = invokers(entryType.generic()).exactInvoker(); MethodHandle invoker0 = entryType.generic().invokers().exactInvoker();
MethodType rawEntryTypeInit; MethodType rawEntryTypeInit;
Adapter ad = findAdapter(rawEntryTypeInit = entryType); Adapter ad = findAdapter(rawEntryTypeInit = entryType);
if (ad != null) { if (ad != null) {
@ -89,15 +88,15 @@ class ToGeneric {
} }
// next, it will reorder primitives after references // next, it will reorder primitives after references
MethodType primsAtEnd = MethodTypeImpl.of(entryType).primsAtEnd(); MethodType primsAtEnd = entryType.form().primsAtEnd();
// at the same time, it will "forget" all primitive types except int/long // at the same time, it will "forget" all primitive types except int/long
this.primsAtEndOrder = MethodTypeImpl.primsAtEndOrder(entryType); this.primsAtEndOrder = MethodTypeForm.primsAtEndOrder(entryType);
if (primsAtEndOrder != null) { if (primsAtEndOrder != null) {
// reordering is required; build on top of a simpler ToGeneric // reordering is required; build on top of a simpler ToGeneric
ToGeneric va2 = ToGeneric.of(primsAtEnd); ToGeneric va2 = ToGeneric.of(primsAtEnd);
this.adapter = va2.adapter; this.adapter = va2.adapter;
if (true) throw new UnsupportedOperationException("NYI: primitive parameters must follow references; entryType = "+entryType); if (true) throw new UnsupportedOperationException("NYI: primitive parameters must follow references; entryType = "+entryType);
this.entryPoint = MethodHandleImpl.convertArguments(Access.TOKEN, this.entryPoint = MethodHandleImpl.convertArguments(
va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder); va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder);
// example: for entryType of (int,Object,Object), the reordered // example: for entryType of (int,Object,Object), the reordered
// type is (Object,Object,int) and the order is {1,2,0}, // type is (Object,Object,int) and the order is {1,2,0},
@ -107,7 +106,7 @@ class ToGeneric {
// after any needed argument reordering, it will reinterpret // after any needed argument reordering, it will reinterpret
// primitive arguments according to their "raw" types int/long // primitive arguments according to their "raw" types int/long
MethodType intsAtEnd = MethodTypeImpl.of(primsAtEnd).primsAsInts(); MethodType intsAtEnd = primsAtEnd.form().primsAsInts();
ad = findAdapter(rawEntryTypeInit = intsAtEnd); ad = findAdapter(rawEntryTypeInit = intsAtEnd);
MethodHandle rawEntryPoint; MethodHandle rawEntryPoint;
if (ad != null) { if (ad != null) {
@ -116,7 +115,7 @@ class ToGeneric {
// Perhaps the adapter is available only for longs. // Perhaps the adapter is available only for longs.
// If so, we can use it, but there will have to be a little // If so, we can use it, but there will have to be a little
// more stack motion on each call. // more stack motion on each call.
MethodType longsAtEnd = MethodTypeImpl.of(primsAtEnd).primsAsLongs(); MethodType longsAtEnd = primsAtEnd.form().primsAsLongs();
ad = findAdapter(rawEntryTypeInit = longsAtEnd); ad = findAdapter(rawEntryTypeInit = longsAtEnd);
if (ad != null) { if (ad != null) {
MethodType eptWithLongs = longsAtEnd.insertParameterTypes(0, ad.getClass()); MethodType eptWithLongs = longsAtEnd.insertParameterTypes(0, ad.getClass());
@ -128,7 +127,7 @@ class ToGeneric {
assert(midType.parameterType(i) == long.class); assert(midType.parameterType(i) == long.class);
assert(eptWithInts.parameterType(i) == int.class); assert(eptWithInts.parameterType(i) == int.class);
MethodType nextType = midType.changeParameterType(i, int.class); MethodType nextType = midType.changeParameterType(i, int.class);
rawEntryPoint = MethodHandle.convertArguments(Access.TOKEN, rawEntryPoint = MethodHandleImpl.convertArguments(
rawEntryPoint, nextType, midType, null); rawEntryPoint, nextType, midType, null);
midType = nextType; midType = nextType;
} }
@ -143,7 +142,7 @@ class ToGeneric {
} }
MethodType tepType = entryType.insertParameterTypes(0, ad.getClass()); MethodType tepType = entryType.insertParameterTypes(0, ad.getClass());
this.entryPoint = this.entryPoint =
AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, rawEntryPoint); AdapterMethodHandle.makeRetypeRaw(tepType, rawEntryPoint);
if (this.entryPoint == null) if (this.entryPoint == null)
throw new UnsupportedOperationException("cannot retype to "+entryType throw new UnsupportedOperationException("cannot retype to "+entryType
+" from "+rawEntryPoint.type().dropParameterTypes(0, 1)); +" from "+rawEntryPoint.type().dropParameterTypes(0, 1));
@ -168,7 +167,7 @@ class ToGeneric {
assert(src.isPrimitive() && dst.isPrimitive()); assert(src.isPrimitive() && dst.isPrimitive());
if (filteredInvoker == null) { if (filteredInvoker == null) {
filteredInvoker = filteredInvoker =
AdapterMethodHandle.makeCheckCast(Access.TOKEN, AdapterMethodHandle.makeCheckCast(
invoker.type().generic(), invoker, 0, MethodHandle.class); invoker.type().generic(), invoker, 0, MethodHandle.class);
if (filteredInvoker == null) throw new UnsupportedOperationException("NYI"); if (filteredInvoker == null) throw new UnsupportedOperationException("NYI");
} }
@ -177,7 +176,7 @@ class ToGeneric {
if (filteredInvoker == null) throw new InternalError(); if (filteredInvoker == null) throw new InternalError();
} }
if (filteredInvoker == null) return invoker; if (filteredInvoker == null) return invoker;
return AdapterMethodHandle.makeRetypeOnly(Access.TOKEN, invoker.type(), filteredInvoker); return AdapterMethodHandle.makeRetypeOnly(invoker.type(), filteredInvoker);
} }
/** /**
@ -227,7 +226,7 @@ class ToGeneric {
// retype erased reference arguments (the cast makes it safe to do this) // retype erased reference arguments (the cast makes it safe to do this)
MethodType tepType = type.insertParameterTypes(0, adapter.getClass()); MethodType tepType = type.insertParameterTypes(0, adapter.getClass());
MethodHandle typedEntryPoint = MethodHandle typedEntryPoint =
AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, entryPoint); AdapterMethodHandle.makeRetypeRaw(tepType, entryPoint);
return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget); return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget);
} }
@ -248,7 +247,7 @@ class ToGeneric {
/** Return the adapter information for this type's erasure. */ /** Return the adapter information for this type's erasure. */
static ToGeneric of(MethodType type) { static ToGeneric of(MethodType type) {
MethodTypeImpl form = MethodTypeImpl.of(type); MethodTypeForm form = type.form();
ToGeneric toGen = form.toGeneric; ToGeneric toGen = form.toGeneric;
if (toGen == null) if (toGen == null)
form.toGeneric = toGen = new ToGeneric(form.erasedType()); form.toGeneric = toGen = new ToGeneric(form.erasedType());
@ -262,7 +261,7 @@ class ToGeneric {
/* Create an adapter for the given incoming call type. */ /* Create an adapter for the given incoming call type. */
static Adapter findAdapter(MethodType entryPointType) { static Adapter findAdapter(MethodType entryPointType) {
MethodTypeImpl form = MethodTypeImpl.of(entryPointType); MethodTypeForm form = entryPointType.form();
Class<?> rtype = entryPointType.returnType(); Class<?> rtype = entryPointType.returnType();
int argc = form.parameterCount(); int argc = form.parameterCount();
int lac = form.longPrimitiveParameterCount(); int lac = form.longPrimitiveParameterCount();
@ -283,7 +282,7 @@ class ToGeneric {
for (String iname : inames) { for (String iname : inames) {
MethodHandle entryPoint = null; MethodHandle entryPoint = null;
try { try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP. entryPoint = IMPL_LOOKUP.
findSpecial(acls, iname, entryPointType, acls); findSpecial(acls, iname, entryPointType, acls);
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
} }
@ -338,13 +337,13 @@ class ToGeneric {
@Override @Override
public String toString() { public String toString() {
return target == null ? "prototype:"+convert : MethodHandleImpl.addTypeString(target, this); return target == null ? "prototype:"+convert : addTypeString(target, this);
} }
protected boolean isPrototype() { return target == null; } protected boolean isPrototype() { return target == null; }
/* Prototype constructor. */ /* Prototype constructor. */
protected Adapter(MethodHandle entryPoint) { protected Adapter(MethodHandle entryPoint) {
super(Access.TOKEN, entryPoint); super(entryPoint);
this.invoker = null; this.invoker = null;
this.convert = entryPoint; this.convert = entryPoint;
this.target = null; this.target = null;
@ -356,7 +355,7 @@ class ToGeneric {
} }
protected Adapter(MethodHandle entryPoint, MethodHandle invoker, MethodHandle convert, MethodHandle target) { protected Adapter(MethodHandle entryPoint, MethodHandle invoker, MethodHandle convert, MethodHandle target) {
super(Access.TOKEN, entryPoint); super(entryPoint);
this.invoker = invoker; this.invoker = invoker;
this.convert = convert; this.convert = convert;
this.target = target; this.target = target;
@ -396,7 +395,7 @@ class ToGeneric {
protected float return_F(Object res) throws Throwable { return (float) convert.invokeExact(res); } protected float return_F(Object res) throws Throwable { return (float) convert.invokeExact(res); }
protected double return_D(Object res) throws Throwable { return (double)convert.invokeExact(res); } protected double return_D(Object res) throws Throwable { return (double)convert.invokeExact(res); }
static private final String CLASS_PREFIX; // "sun.dyn.ToGeneric$" static private final String CLASS_PREFIX; // "java.lang.invoke.ToGeneric$"
static { static {
String aname = Adapter.class.getName(); String aname = Adapter.class.getName();
String sname = Adapter.class.getSimpleName(); String sname = Adapter.class.getSimpleName();
@ -452,14 +451,15 @@ class genclasses {
static String[] TCHARS = { "L", "I", "J", "F", "D", "A" }; static String[] TCHARS = { "L", "I", "J", "F", "D", "A" };
static String[][] TEMPLATES = { { static String[][] TEMPLATES = { {
"@for@ arity=0..3 rcat<=4 nrefs<=99 nints<=99 nlongs<=99", "@for@ arity=0..3 rcat<=4 nrefs<=99 nints<=99 nlongs<=99",
"@for@ arity=4..5 rcat<=2 nrefs<=99 nints<=99 nlongs<=99", "@for@ arity=4..4 rcat<=4 nrefs<=99 nints<=99 nlongs<=99",
"@for@ arity=5..5 rcat<=2 nrefs<=99 nints<=99 nlongs<=99",
"@for@ arity=6..10 rcat<=2 nrefs<=99 nints=0 nlongs<=99", "@for@ arity=6..10 rcat<=2 nrefs<=99 nints=0 nlongs<=99",
" //@each-cat@", " //@each-cat@",
" static class @cat@ extends Adapter {", " static class @cat@ extends Adapter {",
" protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype", " protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
" protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }", " protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }",
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }", " protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
" protected Object target(@Ovav@) throws Throwable { return invoker.invokeExact(target, @av@); }", " protected Object target(@Ovav@) throws Throwable { return invoker.invokeExact(target@comma@@av@); }",
" //@each-Tv@", " //@each-Tv@",
" protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }", " protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }",
" //@end-Tv@", " //@end-Tv@",
@ -471,7 +471,7 @@ class genclasses {
" }", " }",
} }; } };
enum VAR { enum VAR {
cat, R, Rc, Tv, av, Tvav, Ovav; cat, R, Rc, Tv, av, comma, Tvav, Ovav;
public final String pattern = "@"+toString().replace('_','.')+"@"; public final String pattern = "@"+toString().replace('_','.')+"@";
public String binding; public String binding;
static void makeBindings(boolean topLevel, int rcat, int nrefs, int nints, int nlongs) { static void makeBindings(boolean topLevel, int rcat, int nrefs, int nints, int nlongs) {
@ -493,12 +493,13 @@ class genclasses {
} }
VAR.Tv.binding = comma(Tv); VAR.Tv.binding = comma(Tv);
VAR.av.binding = comma(av); VAR.av.binding = comma(av);
VAR.comma.binding = (av.length == 0 ? "" : ", ");
VAR.Tvav.binding = comma(Tvav); VAR.Tvav.binding = comma(Tvav);
VAR.Ovav.binding = comma(Ovav); VAR.Ovav.binding = comma(Ovav);
} }
static String arg(int i) { return "a"+i; } static String arg(int i) { return "a"+i; }
static String param(String t, String a) { return t+" "+a; } static String param(String t, String a) { return t+" "+a; }
static String comma(String[] v) { return comma(v, ""); } static String comma(String[] v) { return comma("", v); }
static String comma(String sep, String[] v) { static String comma(String sep, String[] v) {
if (v.length == 0) return ""; if (v.length == 0) return "";
String res = sep+v[0]; String res = sep+v[0];
@ -735,7 +736,7 @@ class genclasses {
protected float invoke_F(long a0, long a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); } protected float invoke_F(long a0, long a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(long a0, long a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); } protected double invoke_D(long a0, long a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
} }
//params=[4, 5, 2, 99, 99, 99] //params=[4, 4, 4, 99, 99, 99]
static class A4 extends Adapter { static class A4 extends Adapter {
protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); } protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
@ -753,31 +754,50 @@ class genclasses {
protected Object invoke_L(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(Object a0, Object a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(Object a0, Object a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(Object a0, Object a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(Object a0, Object a1, int a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(Object a0, Object a1, int a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(Object a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(Object a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(Object a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(Object a0, int a1, int a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(Object a0, int a1, int a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(int a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(int a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(int a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(int a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(int a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(int a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(int a0, int a1, int a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(int a0, int a1, int a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(Object a0, Object a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(Object a0, Object a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(Object a0, Object a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(Object a0, Object a1, long a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(Object a0, Object a1, long a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(Object a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(Object a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(Object a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(Object a0, long a1, long a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(Object a0, long a1, long a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(long a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); } protected Object invoke_L(long a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(long a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); } protected int invoke_I(long a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(long a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); } protected long invoke_J(long a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
protected float invoke_F(long a0, long a1, long a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
protected double invoke_D(long a0, long a1, long a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
} }
//params=[5, 5, 2, 99, 99, 99]
static class A5 extends Adapter { static class A5 extends Adapter {
protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); } protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }

Some files were not shown because too many files have changed in this diff Show More