changeset 3604:e5cd10425e7e

Merge
author ohair
date Thu, 03 Mar 2011 07:02:30 -0800
parents 869cba583dd4 f32f0ae3d873
children c588355b5bb7
files src/share/classes/java/dyn/NoAccessException.java src/share/classes/java/dyn/Switcher.java test/java/lang/Thread/StopBeforeStart.java
diffstat 149 files changed, 6270 insertions(+), 2311 deletions(-) [+]
line wrap: on
line diff
--- a/make/java/security/Makefile	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/java/security/Makefile	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -65,6 +65,8 @@
 ifndef OPENJDK
   BLACKLIST_SRC =	$(CLOSED_SHARE_SRC)/lib/security/blacklist
   BLACKLIST_BUILD = $(LIBDIR)/security/blacklist
+  TRUSTEDLIBS_SRC = $(CLOSED_SHARE_SRC)/lib/security/trusted.libraries
+  TRUSTEDLIBS_BUILD = $(LIBDIR)/security/trusted.libraries
 endif
 
 FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class)
@@ -77,7 +79,7 @@
 ifdef OPENJDK
 build: properties policy cacerts
 else
-build: properties policy cacerts blacklist
+build: properties policy cacerts blacklist trustedlibs
 endif
 
 install: all
@@ -90,6 +92,8 @@
 
 blacklist: classes $(BLACKLIST_BUILD)
 
+trustedlibs: classes $(TRUSTEDLIBS_BUILD)
+
 $(PROPS_BUILD): $(PROPS_SRC)
 	$(install-file)
 
@@ -102,9 +106,12 @@
 $(BLACKLIST_BUILD): $(BLACKLIST_SRC)
 	$(install-file)
 
+$(TRUSTEDLIBS_BUILD): $(TRUSTEDLIBS_SRC)
+	$(install-file)
+
 clean clobber:: .delete.classlist
 	$(RM) -r $(CLASSBINDIR)/java/security
-	$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD)
+	$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) $(TRUSTEDLIBS_BUILD)
 
 # Additional Rule for building sun.security.util
 $(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java
--- a/make/sun/javazic/tzdata/VERSION	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/javazic/tzdata/VERSION	Thu Mar 03 07:02:30 2011 -0800
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2010o
+tzdata2011b
--- a/make/sun/javazic/tzdata/australasia	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/javazic/tzdata/australasia	Thu Mar 03 07:02:30 2011 -0800
@@ -106,14 +106,13 @@
 Rule	AS	1987	2007	-	Oct	lastSun	2:00s	1:00	-
 Rule	AS	1972	only	-	Feb	27	2:00s	0	-
 Rule	AS	1973	1985	-	Mar	Sun>=1	2:00s	0	-
-Rule	AS	1986	1989	-	Mar	Sun>=15	2:00s	0	-
-Rule	AS	1990	only	-	Mar	Sun>=18	2:00s	0	-
-Rule	AS	1991	only	-	Mar	Sun>=1	2:00s	0	-
-Rule	AS	1992	only	-	Mar	Sun>=18	2:00s	0	-
-Rule	AS	1993	only	-	Mar	Sun>=1	2:00s	0	-
-Rule	AS	1994	only	-	Mar	Sun>=18	2:00s	0	-
+Rule	AS	1986	1990	-	Mar	Sun>=15	2:00s	0	-
+Rule	AS	1991	only	-	Mar	3	2:00s	0	-
+Rule	AS	1992	only	-	Mar	22	2:00s	0	-
+Rule	AS	1993	only	-	Mar	7	2:00s	0	-
+Rule	AS	1994	only	-	Mar	20	2:00s	0	-
 Rule	AS	1995	2005	-	Mar	lastSun	2:00s	0	-
-Rule	AS	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AS	2006	only	-	Apr	2	2:00s	0	-
 Rule	AS	2007	only	-	Mar	lastSun	2:00s	0	-
 Rule	AS	2008	max	-	Apr	Sun>=1	2:00s	0	-
 Rule	AS	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
--- a/make/sun/javazic/tzdata/northamerica	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/javazic/tzdata/northamerica	Thu Mar 03 07:02:30 2011 -0800
@@ -368,6 +368,27 @@
 			-7:00	US	M%sT	2003 Oct 26 02:00
 			-6:00	US	C%sT
 
+# From Josh Findley (2011-01-21):
+# ...it appears that Mercer County, North Dakota, changed from the
+# mountain time zone to the central time zone at the last transition from
+# daylight-saving to standard time (on Nov. 7, 2010):
+# <a href="http://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm">
+# http://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm
+# </a>
+# <a href="http://www.bismarcktribune.com/news/local/article_1eb1b588-c758-11df-b472-001cc4c03286.html">
+# http://www.bismarcktribune.com/news/local/article_1eb1b588-c758-11df-b472-001cc4c03286.html
+# </a>
+
+# From Andy Lipscomb (2011-01-24):
+# ...according to the Census Bureau, the largest city is Beulah (although
+# it's commonly referred to as Beulah-Hazen, with Hazen being the next
+# largest city in Mercer County).  Google Maps places Beulah's city hall
+# at 4715'51" north, 10146'40" west, which yields an offset of 6h47'07".
+
+Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
+			-7:00	US	M%sT	2010 Nov  7 2:00
+			-6:00	US	C%sT
+
 # US mountain time, represented by Denver
 #
 # Colorado, far western Kansas, Montana, western
@@ -493,20 +514,50 @@
 #  three votes for and one against."
 
 # Hawaii
+
+# From Arthur David Olson (2010-12-09):
+# "Hawaiian Time" by Robert C. Schmitt and Doak C. Cox appears on pages 207-225
+# of volume 26 of The Hawaiian Journal of History (1992). As of 2010-12-09,
+# the article is available at
+# <a href="http://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf">
+# http://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf
+# </a>
+# and indicates that standard time was adopted effective noon, January
+# 13, 1896 (page 218), that in "1933, the Legislature decreed daylight
+# saving for the period between the last Sunday of each April and the
+# last Sunday of each September, but less than a month later repealed the
+# act," (page 220), that year-round daylight saving time was in effect
+# from 1942-02-09 to 1945-09-30 (page 221, with no time of day given for
+# when clocks changed) and that clocks were changed by 30 minutes
+# effective the second Sunday of June, 1947 (page 219, with no time of
+# day given for when clocks changed). A footnote for the 1933 changes
+# cites Session Laws of Hawaii 1933, "Act. 90 (approved 26 Apr. 1933)
+# and Act 163 (approved 21 May 1933)."
+
+# From Arthur David Olson (2011-01-19):
+# The following is from "Laws of the Territory of Hawaii Passed by the
+# Seventeenth Legislature: Regular Session 1933," available (as of
+# 2011-01-19) at American University's Pence Law Library. Page 85: "Act
+# 90...At 2 o'clock ante meridian of the last Sunday in April of each
+# year, the standard time of this Territory shall be advanced one
+# hour...This Act shall take effect upon its approval. Approved this 26th
+# day of April, A. D. 1933. LAWRENCE M JUDD, Governor of the Territory of
+# Hawaii." Page 172:  "Act 163...Act 90 of the Session Laws of 1933 is
+# hereby repealed...This Act shall take effect upon its approval, upon
+# which date the standard time of this Territory shall be restored to
+# that existing immediately prior to the taking effect of said Act 90.
+# Approved this 21st day of May, A. D. 1933. LAWRENCE M. JUDD, Governor
+# of the Territory of Hawaii."
 #
-# From Arthur David Olson:
-# And then there's Hawaii.
-# DST was observed for one day in 1933;
-# standard time was changed by half an hour in 1947;
-# it's always standard as of 1986.
-#
-# From Paul Eggert:
-# Shanks says the 1933 experiment lasted for three weeks.  Go with Shanks.
-#
-Zone Pacific/Honolulu	-10:31:26 -	LMT	1900 Jan  1 12:00
-			-10:30	-	HST	1933 Apr 30 2:00
-			-10:30	1:00	HDT	1933 May 21 2:00
-			-10:30	US	H%sT	1947 Jun  8 2:00
+# Note that 1933-05-21 was a Sunday.
+# We're left to guess the time of day when Act 163 was approved; guess noon.
+
+Zone Pacific/Honolulu	-10:31:26 -	LMT	1896 Jan 13 12:00 #Schmitt&Cox
+			-10:30	-	HST	1933 Apr 30 2:00 #Laws 1933
+			-10:30	1:00	HDT	1933 May 21 12:00 #Laws 1933+12
+			-10:30	-	HST	1942 Feb 09 2:00 #Schmitt&Cox+2
+			-10:30	1:00	HDT	1945 Sep 30 2:00 #Schmitt&Fox+2
+			-10:30	US	H%sT	1947 Jun  8 2:00 #Schmitt&Fox+2
 			-10:00	-	HST
 
 # Now we turn to US areas that have diverged from the consensus since 1970.
--- a/make/sun/javazic/tzdata/zone.tab	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/javazic/tzdata/zone.tab	Thu Mar 03 07:02:30 2011 -0800
@@ -233,8 +233,8 @@
 HU	+4730+01905	Europe/Budapest
 ID	-0610+10648	Asia/Jakarta	Java & Sumatra
 ID	-0002+10920	Asia/Pontianak	west & central Borneo
-ID	-0507+11924	Asia/Makassar	east & south Borneo, Celebes, Bali, Nusa Tengarra, west Timor
-ID	-0232+14042	Asia/Jayapura	Irian Jaya & the Moluccas
+ID	-0507+11924	Asia/Makassar	east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor
+ID	-0232+14042	Asia/Jayapura	west New Guinea (Irian Jaya) & Malukus (Moluccas)
 IE	+5320-00615	Europe/Dublin
 IL	+3146+03514	Asia/Jerusalem
 IM	+5409-00428	Europe/Isle_of_Man
@@ -426,6 +426,7 @@
 US	+450628-0873651	America/Menominee	Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
 US	+470659-1011757	America/North_Dakota/Center	Central Time - North Dakota - Oliver County
 US	+465042-1012439	America/North_Dakota/New_Salem	Central Time - North Dakota - Morton County (except Mandan area)
+US	+471551-1014640	America/North_Dakota/Beulah	Central Time - North Dakota - Mercer County
 US	+394421-1045903	America/Denver	Mountain Time
 US	+433649-1161209	America/Boise	Mountain Time - south Idaho & east Oregon
 US	+364708-1084111	America/Shiprock	Mountain Time - Navajo
--- a/make/sun/jpeg/Makefile	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/jpeg/Makefile	Thu Mar 03 07:02:30 2011 -0800
@@ -65,6 +65,19 @@
     FILES_reorder += reorder-$(ARCH)
   endif
 endif
+
+ifeq ($(PLATFORM), linux)
+
+  # Suppress gcc warnings like "variable might be clobbered by 'longjmp'
+  # or 'vfork'": this warning indicates that some variable is placed to
+  # a register by optimized compiler and it's value might be lost on longjmp().
+  # Recommended way to avoid such warning is to declare the variable as
+  # volatile to prevent the optimization. However, this approach does not
+  # work because we have to declare all variables as volatile in result.
+
+  OTHER_CFLAGS += -Wno-clobbered
+endif
+
 include $(BUILDDIR)/common/Mapfile-vers.gmk
 include $(BUILDDIR)/common/Library.gmk
 
--- a/make/sun/jpeg/reorder-i586	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/jpeg/reorder-i586	Thu Mar 03 07:02:30 2011 -0800
@@ -22,7 +22,7 @@
 text: .text%alloc_small: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jmemmgr.o;
 text: .text%reset_marker_reader: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%jIInCtlr;
-text: .text%GET_ARRAYS: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jpegdecoder.o;
+# text: .text%GET_ARRAYS: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jpegdecoder.o;
 text: .text%jReadHeader;
 text: .text%jConsumeInput;
 text: .text%reset_input_controller: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
@@ -30,36 +30,36 @@
 text: .text%sun_jpeg_init_source;
 text: .text%consume_markers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
 text: .text%read_markers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
-text: .text%first_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%first_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%sun_jpeg_fill_input_buffer;
-text: .text%RELEASE_ARRAYS: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jpegdecoder.o;
-text: .text%get_soi: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%RELEASE_ARRAYS: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jpegdecoder.o;
+# text: .text%get_soi: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%emit_message: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jerror.o;
-text: .text%next_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%next_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%get_interesting_appn: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
-text: .text%examine_app0: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%examine_app0: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%skip_variable: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%sun_jpeg_skip_input_data;
-text: .text%examine_app14: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%examine_app14: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%get_dqt: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%jAlcQTable;
 text: .text%get_sof: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
-text: .text%get_dri: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%get_dri: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%get_dht: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%jAlcHTable;
 text: .text%get_sos: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
-text: .text%initial_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
+# text: .text%initial_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
 text: .text%jDivRound;
-text: .text%default_decompress_parms: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdapimin.o;
+# text: .text%default_decompress_parms: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdapimin.o;
 text: .text%jHasMultScn;
 text: .text%jStrtDecompress;
 text: .text%jIDMaster;
-text: .text%master_selection: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
+# text: .text%master_selection: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%jCalcDimensions;
-text: .text%use_merged_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
-text: .text%prepare_range_limit_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
+# text: .text%use_merged_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
+# text: .text%prepare_range_limit_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%jIDColor;
-text: .text%build_ycc_rgb_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcolor.o;
+# text: .text%build_ycc_rgb_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcolor.o;
 text: .text%jIUpsampler;
 text: .text%jRound;
 text: .text%alloc_sarray: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jmemmgr.o;
@@ -70,16 +70,16 @@
 text: .text%jIHDecoder;
 text: .text%jIDCoefC;
 text: .text%jIDMainC;
-text: .text%alloc_funny_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
+# text: .text%alloc_funny_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
 text: .text%realize_virt_arrays: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jmemmgr.o;
 text: .text%start_input_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
-text: .text%per_scan_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
-text: .text%latch_quant_tables: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
+# text: .text%per_scan_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
+# text: .text%latch_quant_tables: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
 text: .text%start_pass_huff_decoder: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdhuff.o;
 text: .text%jMkDDerived;
 text: .text%start_input_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
-text: .text%start_iMCU_row: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
-text: .text%output_pass_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdapistd.o;
+# text: .text%start_iMCU_row: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
+# text: .text%output_pass_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdapistd.o;
 text: .text%prepare_for_output_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%start_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jddctmgr.o;
 text: .text%start_output_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
@@ -87,7 +87,7 @@
 text: .text%start_pass_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdsample.o;
 text: .text%start_pass_dpost: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdpostct.o;
 text: .text%start_pass_main: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
-text: .text%make_funny_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
+# text: .text%make_funny_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
 text: .text%jReadScanlines;
 text: .text%process_data_context_main: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
 text: .text%decompress_onepass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
@@ -100,11 +100,11 @@
 text: .text%fullsize_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdsample.o;
 text: .text%h2v2_fancy_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdsample.o;
 text: .text%ycc_rgb_convert: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcolor.o;
-text: .text%set_wraparound_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
-text: .text%process_restart: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdhuff.o;
+# text: .text%set_wraparound_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
+# text: .text%process_restart: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdhuff.o;
 text: .text%read_restart_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%finish_input_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
-text: .text%set_bottom_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
+# text: .text%set_bottom_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
 text: .text%jFinDecompress;
 text: .text%finish_output_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%sun_jpeg_term_source;
--- a/make/sun/jpeg/reorder-sparc	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/jpeg/reorder-sparc	Thu Mar 03 07:02:30 2011 -0800
@@ -30,10 +30,10 @@
 text: .text%sun_jpeg_init_source;
 text: .text%consume_markers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
 text: .text%read_markers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
-text: .text%first_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%first_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%sun_jpeg_fill_input_buffer;
 text: .text%RELEASE_ARRAYS: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jpegdecoder.o;
-text: .text%get_soi: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%get_soi: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%emit_message: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jerror.o;
 text: .text%next_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%get_interesting_appn: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
@@ -44,7 +44,7 @@
 text: .text%get_dqt: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%jAlcQTable;
 text: .text%get_sof: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
-text: .text%get_dri: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
+# text: .text%get_dri: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%get_dht: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%jAlcHTable;
 text: .text%get_sos: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
@@ -56,10 +56,10 @@
 text: .text%jIDMaster;
 text: .text%master_selection: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%jCalcDimensions;
-text: .text%use_merged_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
-text: .text%prepare_range_limit_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
+# text: .text%use_merged_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
+# text: .text%prepare_range_limit_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%jIDColor;
-text: .text%build_ycc_rgb_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcolor.o;
+# text: .text%build_ycc_rgb_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcolor.o;
 text: .text%jIUpsampler;
 text: .text%jRound;
 text: .text%alloc_sarray: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jmemmgr.o;
@@ -78,7 +78,7 @@
 text: .text%start_pass_huff_decoder: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdhuff.o;
 text: .text%jMkDDerived;
 text: .text%start_input_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
-text: .text%start_iMCU_row: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
+# text: .text%start_iMCU_row: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcoefct.o;
 text: .text%output_pass_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdapistd.o;
 text: .text%prepare_for_output_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%start_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jddctmgr.o;
@@ -100,11 +100,11 @@
 text: .text%fullsize_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdsample.o;
 text: .text%h2v2_fancy_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdsample.o;
 text: .text%ycc_rgb_convert: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdcolor.o;
-text: .text%set_wraparound_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
-text: .text%process_restart: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdhuff.o;
+# text: .text%set_wraparound_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
+#text: .text%process_restart: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdhuff.o;
 text: .text%read_restart_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmarker.o;
 text: .text%finish_input_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdinput.o;
-text: .text%set_bottom_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
+# text: .text%set_bottom_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmainct.o;
 text: .text%jFinDecompress;
 text: .text%finish_output_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj/jdmaster.o;
 text: .text%sun_jpeg_term_source;
--- a/make/sun/jpeg/reorder-sparcv9	Wed Mar 02 13:18:36 2011 -0800
+++ b/make/sun/jpeg/reorder-sparcv9	Thu Mar 03 07:02:30 2011 -0800
@@ -30,10 +30,10 @@
 text: .text%sun_jpeg_init_source;
 text: .text%consume_markers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdinput.o;
 text: .text%read_markers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
-text: .text%first_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
+# text: .text%first_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
 text: .text%sun_jpeg_fill_input_buffer;
 text: .text%RELEASE_ARRAYS: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jpegdecoder.o;
-text: .text%get_soi: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
+# text: .text%get_soi: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
 text: .text%emit_message: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jerror.o;
 text: .text%next_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
 text: .text%get_interesting_appn: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
@@ -44,7 +44,7 @@
 text: .text%get_dqt: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
 text: .text%jAlcQTable;
 text: .text%get_sof: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
-text: .text%get_dri: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
+# text: .text%get_dri: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
 text: .text%get_dht: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
 text: .text%jAlcHTable;
 text: .text%get_sos: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
@@ -56,10 +56,10 @@
 text: .text%jIDMaster;
 text: .text%master_selection: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmaster.o;
 text: .text%jCalcDimensions;
-text: .text%use_merged_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmaster.o;
-text: .text%prepare_range_limit_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmaster.o;
+# text: .text%use_merged_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmaster.o;
+# text: .text%prepare_range_limit_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmaster.o;
 text: .text%jIDColor;
-text: .text%build_ycc_rgb_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdcolor.o;
+# text: .text%build_ycc_rgb_table: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdcolor.o;
 text: .text%jIUpsampler;
 text: .text%jRound;
 text: .text%alloc_sarray: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jmemmgr.o;
@@ -78,7 +78,7 @@
 text: .text%start_pass_huff_decoder: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdhuff.o;
 text: .text%jMkDDerived;
 text: .text%start_input_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdcoefct.o;
-text: .text%start_iMCU_row: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdcoefct.o;
+# text: .text%start_iMCU_row: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdcoefct.o;
 text: .text%output_pass_setup: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdapistd.o;
 text: .text%prepare_for_output_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmaster.o;
 text: .text%start_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jddctmgr.o;
@@ -100,11 +100,11 @@
 text: .text%fullsize_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdsample.o;
 text: .text%h2v2_fancy_upsample: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdsample.o;
 text: .text%ycc_rgb_convert: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdcolor.o;
-text: .text%set_wraparound_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmainct.o;
+# text: .text%set_wraparound_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmainct.o;
 text: .text%process_restart: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdhuff.o;
 text: .text%read_restart_marker: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmarker.o;
 text: .text%finish_input_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdinput.o;
-text: .text%set_bottom_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmainct.o;
+# text: .text%set_bottom_pointers: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmainct.o;
 text: .text%jFinDecompress;
 text: .text%finish_output_pass: OUTPUTDIR/tmp/sun/sun.awt/jpeg/obj64/jdmaster.o;
 text: .text%sun_jpeg_term_source;
--- a/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.FormatConversionProvider	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/com/sun/media/sound/services/javax.sound.sampled.spi.FormatConversionProvider	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 # Providers for FormatConversion
+com.sun.media.sound.AudioFloatFormatConverter
 com.sun.media.sound.UlawCodec
 com.sun.media.sound.AlawCodec
 com.sun.media.sound.PCMtoPCMCodec
-com.sun.media.sound.AudioFloatFormatConverter
--- a/src/share/classes/java/dyn/CallSite.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/CallSite.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,7 @@
 }
 private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
   // ignore caller and name, but match the type:
-  return new ConstantCallSite(MethodHandles.collectArguments(printArgs, type));
+  return new ConstantCallSite(printArgs.asType(type));
 }
 </pre></blockquote>
  * @author John Rose, JSR 292 EG
@@ -86,6 +86,7 @@
 abstract
 public class CallSite {
     private static final Access IMPL_TOKEN = Access.getToken();
+    static { MethodHandleImpl.initStatics(); }
 
     // Fields used only by the JVM.  Do not use or change.
     private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
@@ -125,8 +126,8 @@
     }
 
     /**
-     * Report the type of this call site's target.
-     * Although targets may change, the call site's type can never change.
+     * Returns the type of this call site's target.
+     * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
      * The {@code setTarget} method enforces this invariant by refusing any new target that does
      * not have the previous target's type.
      * @return the type of the current target, which is also the type of any future target
@@ -154,73 +155,40 @@
     }
 
     /**
-     * Report the current linkage state of the call site, a value which may change over time.
-     * <p>
-     * If a {@code CallSite} object is returned
-     * from the bootstrap method of the {@code invokedynamic} instruction,
-     * the {@code CallSite} is permanently bound to that instruction.
-     * When the {@code invokedynamic} instruction is executed, the target method
-     * of its associated call site object is invoked directly.
-     * It is as if the instruction calls {@code getTarget} and then
-     * calls {@link MethodHandle#invokeExact invokeExact} on the result.
-     * <p>
-     * Unless specified differently by a subclass,
-     * the interactions of {@code getTarget} with memory are the same
-     * as of a read from an ordinary variable, such as an array element or a
-     * non-volatile, non-final field.
-     * <p>
-     * In particular, the current thread may choose to reuse the result
-     * of a previous read of the target from memory, and may fail to see
-     * a recent update to the target by another thread.
-     * <p>
-     * In a {@linkplain ConstantCallSite constant call site}, the {@code getTarget} method behaves
-     * like a read from a {@code final} field of the {@code CallSite}.
-     * <p>
-     * In a {@linkplain VolatileCallSite volatile call site}, the {@code getTarget} method behaves
-     * like a read from a {@code volatile} field of the {@code CallSite}.
-     * <p>
-     * This method may not be overridden by application code.
+     * Returns the target method of the call site, according to the
+     * behavior defined by this call site's specific class.
+     * The immediate subclasses of {@code CallSite} document the
+     * class-specific behaviors of this method.
+     *
      * @return the current linkage state of the call site, its target method handle
      * @see ConstantCallSite
      * @see VolatileCallSite
      * @see #setTarget
+     * @see ConstantCallSite#getTarget
+     * @see MutableCallSite#getTarget
+     * @see VolatileCallSite#getTarget
      */
-    public final MethodHandle getTarget() {
-        return getTarget0();
-    }
+    public abstract MethodHandle getTarget();
 
     /**
-     * Privileged implementations can override this to force final or volatile semantics on getTarget.
-     */
-    /*package-private*/
-    MethodHandle getTarget0() {
-        return target;
-    }
-
-    /**
-     * Set the target method of this call site.
+     * Updates the target method of this call site, according to the
+     * behavior defined by this call site's specific class.
+     * The immediate subclasses of {@code CallSite} document the
+     * class-specific behaviors of this method.
      * <p>
-     * Unless a subclass of CallSite documents otherwise,
-     * the interactions of {@code setTarget} with memory are the same
-     * as of a write to an ordinary variable, such as an array element or a
-     * non-volatile, non-final field.
-     * <p>
-     * In particular, unrelated threads may fail to see the updated target
-     * until they perform a read from memory.
-     * Stronger guarantees can be created by putting appropriate operations
-     * into the bootstrap method and/or the target methods used
-     * at any given call site.
+     * The type of the new target must be {@linkplain MethodType#equals equal to}
+     * the type of the old target.
+     *
      * @param newTarget the new target
      * @throws NullPointerException if the proposed new target is null
      * @throws WrongMethodTypeException if the proposed new target
      *         has a method type that differs from the previous target
-     * @throws UnsupportedOperationException if the call site is
-     *         in fact a {@link ConstantCallSite}
+     * @see CallSite#getTarget
+     * @see ConstantCallSite#setTarget
+     * @see MutableCallSite#setTarget
+     * @see VolatileCallSite#setTarget
      */
-    public void setTarget(MethodHandle newTarget) {
-        checkTargetChange(this.target, newTarget);
-        setTargetNormal(newTarget);
-    }
+    public abstract void setTarget(MethodHandle newTarget);
 
     void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
         MethodType oldType = oldTarget.type();
@@ -236,31 +204,31 @@
     /**
      * Produce a method handle equivalent to an invokedynamic instruction
      * which has been linked to this call site.
-     * <p>If this call site is a {@linkplain ConstantCallSite constant call site},
-     * this method simply returns the call site's target, since that will never change.
-     * <p>Otherwise, this method is equivalent to the following code:
-     * <p><blockquote><pre>
+     * <p>
+     * This method is equivalent to the following code:
+     * <blockquote><pre>
      * MethodHandle getTarget, invoker, result;
-     * getTarget = MethodHandles.lookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
+     * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
      * invoker = MethodHandles.exactInvoker(this.type());
      * result = MethodHandles.foldArguments(invoker, getTarget)
      * </pre></blockquote>
+     *
      * @return a method handle which always invokes this call site's current target
      */
-    public final MethodHandle dynamicInvoker() {
-        if (this instanceof ConstantCallSite) {
-            return getTarget0();  // will not change dynamically
-        }
+    public abstract MethodHandle dynamicInvoker();
+
+    /*non-public*/ MethodHandle makeDynamicInvoker() {
         MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, GET_TARGET, this);
         MethodHandle invoker = MethodHandles.exactInvoker(this.type());
         return MethodHandles.foldArguments(invoker, getTarget);
     }
+
     private static final MethodHandle GET_TARGET;
     static {
         try {
             GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP.
                 findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
-        } catch (NoAccessException ignore) {
+        } catch (ReflectiveOperationException ignore) {
             throw new InternalError();
         }
     }
--- a/src/share/classes/java/dyn/ClassValue.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/ClassValue.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -31,10 +31,14 @@
 import java.lang.reflect.UndeclaredThrowableException;
 
 /**
- * Lazily associate a computed value with (potentially) every class.
+ * Lazily associate a computed value with (potentially) every type.
+ * For example, if a dynamic language needs to construct a message dispatch
+ * table for each class encountered at a message send call site,
+ * it can use a {@code ClassValue} to cache information needed to
+ * perform the message send quickly, for each class encountered.
  * @author John Rose, JSR 292 EG
  */
-public class ClassValue<T> {
+public abstract class ClassValue<T> {
     /**
      * Compute the given class's derived value for this {@code ClassValue}.
      * <p>
@@ -45,61 +49,41 @@
      * but it may be invoked again if there has been a call to
      * {@link #remove remove}.
      * <p>
-     * If there is no override from a subclass, this method returns
-     * the result of applying the {@code ClassValue}'s {@code computeValue}
-     * method handle, which was supplied at construction time.
+     * If this method throws an exception, the corresponding call to {@code get}
+     * will terminate abnormally with that exception, and no class value will be recorded.
      *
+     * @param type the type whose class value must be computed
      * @return the newly computed value associated with this {@code ClassValue}, for the given class or interface
-     * @throws UndeclaredThrowableException if the {@code computeValue} method handle invocation throws something other than a {@code RuntimeException} or {@code Error}
-     * @throws UnsupportedOperationException if the {@code computeValue} method handle is null (subclasses must override)
+     * @see #get
+     * @see #remove
      */
-    protected T computeValue(Class<?> type) {
-        if (computeValue == null)
-            return null;
-        try {
-            return (T) (Object) computeValue.invokeGeneric(type);
-        } catch (Throwable ex) {
-            if (ex instanceof Error)             throw (Error) ex;
-            if (ex instanceof RuntimeException)  throw (RuntimeException) ex;
-            throw new UndeclaredThrowableException(ex);
-        }
-    }
-
-    private final MethodHandle computeValue;
-
-    /**
-     * Creates a new class value.
-     * Subclasses which use this constructor must override
-     * the {@link #computeValue computeValue} method,
-     * since the default {@code computeValue} method requires a method handle,
-     * which this constructor does not provide.
-     */
-    protected ClassValue() {
-        this.computeValue = null;
-    }
-
-    /**
-     * Creates a new class value, whose {@link #computeValue computeValue} method
-     * will return the result of {@code computeValue.invokeGeneric(type)}.
-     * @throws NullPointerException  if the method handle parameter is null
-     */
-    public ClassValue(MethodHandle computeValue) {
-        computeValue.getClass();  // trigger NPE if null
-        this.computeValue = computeValue;
-    }
+    protected abstract T computeValue(Class<?> type);
 
     /**
      * Returns the value for the given class.
      * If no value has yet been computed, it is obtained by
-     * by an invocation of the {@link #computeValue computeValue} method.
+     * an invocation of the {@link #computeValue computeValue} method.
      * <p>
      * The actual installation of the value on the class
      * is performed atomically.
-     * At that point, if racing threads have
+     * At that point, if several racing threads have
      * computed values, one is chosen, and returned to
      * all the racing threads.
+     * <p>
+     * The {@code type} parameter is typically a class, but it may be any type,
+     * such as an interface, a primitive type (like {@code int.class}), or {@code void.class}.
+     * <p>
+     * In the absence of {@code remove} calls, a class value has a simple
+     * state diagram:  uninitialized and initialized.
+     * When {@code remove} calls are made,
+     * the rules for value observation are more complex.
+     * See the documentation for {@link #remove remove} for more information.
      *
+     * @param type the type whose class value must be computed or retrieved
      * @return the current value associated with this {@code ClassValue}, for the given class or interface
+     * @throws NullPointerException if the argument is null
+     * @see #remove
+     * @see #computeValue
      */
     public T get(Class<?> type) {
         ClassValueMap map = getMap(type);
@@ -119,12 +103,51 @@
      * This may result in an additional invocation of the
      * {@code computeValue computeValue} method for the given class.
      * <p>
-     * If racing threads perform a combination of {@code get} and {@code remove} calls,
-     * the calls are serialized.
-     * A value produced by a call to {@code computeValue} will be discarded, if
-     * the corresponding {@code get} call was followed by a {@code remove} call
-     * before the {@code computeValue} could complete.
-     * In such a case, the {@code get} call will re-invoke {@code computeValue}.
+     * In order to explain the interaction between {@code get} and {@code remove} calls,
+     * we must model the state transitions of a class value to take into account
+     * the alternation between uninitialized and initialized states.
+     * To do this, number these states sequentially from zero, and note that
+     * uninitialized (or removed) states are numbered with even numbers,
+     * while initialized (or re-initialized) states have odd numbers.
+     * <p>
+     * When a thread {@code T} removes a class value in state {@code 2N},
+     * nothing happens, since the class value is already uninitialized.
+     * Otherwise, the state is advanced atomically to {@code 2N+1}.
+     * <p>
+     * When a thread {@code T} queries a class value in state {@code 2N},
+     * the thread first attempts to initialize the class value to state {@code 2N+1}
+     * by invoking {@code computeValue} and installing the resulting value.
+     * <p>
+     * When {@code T} attempts to install the newly computed value,
+     * if the state is still at {@code 2N}, the class value will be initialized
+     * with the computed value, advancing it to state {@code 2N+1}.
+     * <p>
+     * Otherwise, whether the new state is even or odd,
+     * {@code T} will discard the newly computed value
+     * and retry the {@code get} operation.
+     * <p>
+     * Discarding and retrying is an important proviso,
+     * since otherwise {@code T} could potentially install
+     * a disastrously stale value.  For example:
+     * <ul>
+     * <li>{@code T} calls {@code CV.get(C)} and sees state {@code 2N}
+     * <li>{@code T} quickly computes a time-dependent value {@code V0} and gets ready to install it
+     * <li>{@code T} is hit by an unlucky paging or scheduling event, and goes to sleep for a long time
+     * <li>...meanwhile, {@code T2} also calls {@code CV.get(C)} and sees state {@code 2N}
+     * <li>{@code T2} quickly computes a similar time-dependent value {@code V1} and installs it on {@code CV.get(C)}
+     * <li>{@code T2} (or a third thread) then calls {@code CV.remove(C)}, undoing {@code T2}'s work
+     * <li> the previous actions of {@code T2} are repeated several times
+     * <li> also, the relevant computed values change over time: {@code V1}, {@code V2}, ...
+     * <li>...meanwhile, {@code T} wakes up and attempts to install {@code V0}; <em>this must fail</em>
+     * </ul>
+     * We can assume in the above scenario that {@code CV.computeValue} uses locks to properly
+     * observe the time-dependent states as it computes {@code V1}, etc.
+     * This does not remove the threat of a stale value, since there is a window of time
+     * between the return of {@code computeValue} in {@code T} and the installation
+     * of the the new value.  No user synchronization is possible during this time.
+     *
+     * @param type the type whose class value must be removed
+     * @throws NullPointerException if the argument is null
      */
     public void remove(Class<?> type) {
         ClassValueMap map = getMap(type);
@@ -137,9 +160,9 @@
 
     /// Implementation...
 
-    /** The hash code for this type is based on the identity of the object,
-     *  and is well-dispersed for power-of-two tables.
-     */
+    // 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();
--- a/src/share/classes/java/dyn/ConstantCallSite.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/ConstantCallSite.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,16 +32,46 @@
  * @author John Rose, JSR 292 EG
  */
 public class ConstantCallSite extends CallSite {
-    /** Create a call site with a permanent target.
+    /**
+     * Creates a call site with a permanent target.
+     * @param target the target to be permanently associated with this call site
      * @throws NullPointerException if the proposed target is null
      */
     public ConstantCallSite(MethodHandle target) {
         super(target);
     }
+
     /**
-     * Throw an {@link UnsupportedOperationException}, because this kind of call site cannot change its target.
+     * Returns the target method of the call site, which behaves
+     * like a {@code final} field of the {@code ConstantCallSite}.
+     * That is, the the target is always the original value passed
+     * to the constructor call which created this instance.
+     *
+     * @return the immutable linkage state of this call site, a constant method handle
+     * @throws UnsupportedOperationException because this kind of call site cannot change its target
+     */
+    @Override public final MethodHandle getTarget() {
+        return target;
+    }
+
+    /**
+     * Always throws an {@link UnsupportedOperationException}.
+     * This kind of call site cannot change its target.
+     * @param ignore a new target proposed for the call site, which is ignored
+     * @throws UnsupportedOperationException because this kind of call site cannot change its target
      */
     @Override public final void setTarget(MethodHandle ignore) {
         throw new UnsupportedOperationException("ConstantCallSite");
     }
+
+    /**
+     * Returns this call site's permanent target.
+     * Since that target will never change, this is a correct implementation
+     * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
+     * @return the immutable linkage state of this call site, a constant method handle
+     */
+    @Override
+    public final MethodHandle dynamicInvoker() {
+        return getTarget();
+    }
 }
--- a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java	Thu Mar 03 07:02:30 2011 -0800
@@ -31,8 +31,8 @@
  * {@linkplain BootstrapMethod bootstrap method},
  * or the bootstrap method has
  * failed to provide a
- * {@linkplain CallSite} call site with a non-null {@linkplain MethodHandle target}
- * of the correct {@linkplain MethodType 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
  * @since 1.7
--- a/src/share/classes/java/dyn/Linkage.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/Linkage.java	Thu Mar 03 07:02:30 2011 -0800
@@ -88,7 +88,7 @@
         MethodHandle bootstrapMethod;
         try {
             bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
-        } catch (NoAccessException ex) {
+        } catch (ReflectiveOperationException ex) {
             throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
         }
         MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
@@ -101,8 +101,9 @@
     /**
      * <em>METHOD WILL BE REMOVED FOR PFD:</em>
      * Invalidate all <code>invokedynamic</code> call sites everywhere.
-     * @deprecated Use {@linkplain CallSite#setTarget call site target setting}
-     * and {@link VolatileCallSite#invalidateAll call site invalidation} instead.
+     * @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() {
@@ -113,8 +114,9 @@
      * <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 CallSite#setTarget call site target setting}
-     * and {@link VolatileCallSite#invalidateAll call site invalidation} instead.
+     * @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) {
--- a/src/share/classes/java/dyn/MethodHandle.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/MethodHandle.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
 import static sun.dyn.MemberName.newIllegalArgumentException;  // utility
 
 /**
- * A method handle is a typed, directly executable reference to a method,
+ * A method handle is a typed, directly executable reference to an underlying method,
  * constructor, field, or similar low-level operation, with optional
  * transformations of arguments or return values.
  * These transformations are quite general, and include such patterns as
@@ -48,99 +48,182 @@
  *     will be removed before the Proposed Final Draft.
  *     Also, the final version will not include any public or
  *     protected constructors.</em>
- * <p>
- * Method handles are strongly typed according to signature.
- * They are not distinguished by method name or enclosing class.
- * A method handle must be invoked under a signature which matches
- * the method handle's own {@linkplain MethodType method type}.
+ *
+ * <h3>Method handle contents</h3>
+ * Method handles are dynamically and strongly typed according to type descriptor.
+ * They are not distinguished by the name or defining class of their underlying methods.
+ * A method handle must be invoked using type descriptor which matches
+ * the method handle's own {@linkplain #type method type}.
  * <p>
  * Every method handle reports its type via the {@link #type type} accessor.
- * The structure of this type is a series of classes, one of which is
+ * This type descriptor is a {@link java.dyn.MethodType MethodType} object,
+ * whose structure is a series of classes, one of which is
  * the return type of the method (or {@code void.class} if none).
  * <p>
- * Every method handle appears as an object containing a method named
- * {@link #invokeExact invokeExact}, whose signature exactly matches
- * the method handle's type.
- * A Java method call expression, which compiles to an
- * {@code invokevirtual} instruction,
- * can invoke this method from Java source code.
+ * A method handle's type controls the types of invocations it accepts,
+ * and the kinds of transformations that apply to it.
  * <p>
- * Every call to a method handle specifies an intended method type,
- * which must exactly match the type of the method handle.
- * (The type is specified in the {@code invokevirtual} instruction,
- * via a {@code CONSTANT_NameAndType} constant pool entry.)
- * The call looks within the receiver object for a method
- * named {@code invokeExact} of the intended method type.
- * The call fails with a {@link WrongMethodTypeException}
- * if the method does not exist, even if there is an {@code invokeExact}
- * method of a closely similar signature.
- * As with other kinds
- * of methods in the JVM, signature matching during method linkage
- * is exact, and does not allow for language-level implicit conversions
- * such as {@code String} to {@code Object} or {@code short} to {@code int}.
+ * A method handle contains a pair of special invoker methods
+ * called {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.
+ * Both invoker methods provide direct access to the method handle's
+ * underlying method, constructor, field, or other operation,
+ * as modified by transformations of arguments and return values.
+ * Both invokers accept calls which exactly match the method handle's own type.
+ * The {@code invokeGeneric} invoker also accepts a range of other call types.
  * <p>
- * Each individual method handle also contains a method named
- * {@link #invokeGeneric invokeGeneric}, whose type is the same
- * as {@code invokeExact}, and is therefore also reported by
- * the {@link #type type} accessor.
+ * Method handles are immutable and have no visible state.
+ * Of course, they can be bound to underlying methods or data which exhibit state.
+ * With respect to the Java Memory Model, any method handle will behave
+ * as if all of its (internal) fields are final variables.  This means that any method
+ * handle made visible to the application will always be fully formed.
+ * This is true even if the method handle is published through a shared
+ * variable in a data race.
+ * <p>
+ * Method handles cannot be subclassed by the user.
+ * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
+ * which may be visible via the {@link java.lang.Object#getClass Object.getClass}
+ * operation.  The programmer should not draw conclusions about a method handle
+ * from its specific class, as the method handle class hierarchy (if any)
+ * may change from time to time or across implementations from different vendors.
+ *
+ * <h3>Method handle compilation</h3>
+ * A Java method call expression naming {@code invokeExact} or {@code invokeGeneric}
+ * can invoke a method handle from Java source code.
+ * From the viewpoint of source code, these methods can take any arguments
+ * and their result can be cast to any return type.
+ * Formally this is accomplished by giving the invoker methods
+ * {@code Object} return types and variable-arity {@code Object} arguments,
+ * but they have an additional quality called <em>signature polymorphism</em>
+ * which connects this freedom of invocation directly to the JVM execution stack.
+ * <p>
+ * As is usual with virtual methods, source-level calls to {@code invokeExact}
+ * and {@code invokeGeneric} compile to an {@code invokevirtual} instruction.
+ * More unusually, the compiler must record the actual argument types,
+ * and may not perform method invocation conversions on the arguments.
+ * Instead, it must push them on the stack according to their own unconverted types.
+ * The method handle object itself is pushed on the stack before the arguments.
+ * The compiler then calls the method handle with a type descriptor which
+ * describes the argument and return types.
+ * <p>
+ * To issue a complete type descriptor, the compiler must also determine
+ * the return type.  This is based on a cast on the method invocation expression,
+ * if there is one, or else {@code Object} if the invocation is an expression
+ * or else {@code void} if the invocation is a statement.
+ * The cast may be to a primitive type (but not {@code void}).
+ * <p>
+ * As a corner case, an uncasted {@code null} argument is given
+ * a type descriptor of {@code java.lang.Void}.
+ * The ambiguity with the type {@code Void} is harmless, since there are no references of type
+ * {@code Void} except the null reference.
+ *
+ * <h3>Method handle invocation</h3>
+ * The first time a {@code invokevirtual} instruction is executed
+ * it is linked, by symbolically resolving the names in the instruction
+ * and verifying that the method call is statically legal.
+ * This is true of calls to {@code invokeExact} and {@code invokeGeneric}.
+ * In this case, the type descriptor emitted by the compiler is checked for
+ * correct syntax and names it contains are resolved.
+ * Thus, an {@code invokevirtual} instruction which invokes
+ * a method handle will always link, as long
+ * as the type descriptor is syntactically well-formed
+ * and the types exist.
+ * <p>
+ * When the {@code invokevirtual} is executed after linking,
+ * the receiving method handle's type is first checked by the JVM
+ * to ensure that it matches the descriptor.
+ * If the type match fails, it means that the method which the
+ * caller is invoking is not present on the individual
+ * method handle being invoked.
+ * <p>
+ * In the case of {@code invokeExact}, the type descriptor of the invocation
+ * (after resolving symbolic type names) must exactly match the method type
+ * of the receiving method handle.
+ * In the case of {@code invokeGeneric}, the resolved type descriptor
+ * must be a valid argument to the receiver's {@link #asType asType} method.
+ * Thus, {@code invokeGeneric} is more permissive than {@code invokeExact}.
+ * <p>
+ * After type matching, a call to {@code invokeExact} directly
+ * and immediately invoke the method handle's underlying method
+ * (or other behavior, as the case may be).
+ * <p>
  * A call to {@code invokeGeneric} works the same as a call to
- * {@code invokeExact}, if the signature specified by the caller
+ * {@code invokeExact}, if the type descriptor specified by the caller
  * exactly matches the method handle's own type.
  * If there is a type mismatch, {@code invokeGeneric} attempts
- * to adjust the type of the target method handle
- * (as if by a call to {@link #asType asType})
- * to obtain an exactly invokable target.
+ * to adjust the type of the receiving method handle,
+ * as if by a call to {@link #asType asType},
+ * to obtain an exactly invokable method handle {@code M2}.
  * This allows a more powerful negotiation of method type
  * between caller and callee.
  * <p>
- * A method handle is an unrestricted capability to call a method.
- * A method handle can be formed on a non-public method by a class
- * that has access to that method; the resulting handle can be used
- * in any place by any caller who receives a reference to it.  Thus, access
- * checking is performed when the method handle is created, not
- * (as in reflection) every time it is called.  Handles to non-public
- * methods, or in non-public classes, should generally be kept secret.
+ * (Note: The adjusted method handle {@code M2} is not directly observable,
+ * and implementations are therefore not required to materialize it.)
+ *
+ * <h3>Invocation checking</h3>
+ * In typical programs, method handle type matching will usually succeed.
+ * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
+ * either directly (in the case of {@code invokeExact}) or indirectly as if
+ * by a failed call to {@code asType} (in the case of {@code invokeGeneric}).
+ * <p>
+ * Thus, a method type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as
+ * a dynamic {@code WrongMethodTypeException}
+ * in a program which uses method handles.
+ * <p>
+ * Because method types contain "live" {@code Class} objects,
+ * method type matching takes into account both types names and class loaders.
+ * Thus, even if a method handle {@code M} is created in one
+ * class loader {@code L1} and used in another {@code L2},
+ * method handle calls are type-safe, because the caller's type
+ * descriptor, as resolved in {@code L2},
+ * is matched against the original callee method's type descriptor,
+ * as resolved in {@code L1}.
+ * The resolution in {@code L1} happens when {@code M} is created
+ * and its type is assigned, while the resolution in {@code L2} happens
+ * when the {@code invokevirtual} instruction is linked.
+ * <p>
+ * Apart from the checking of type descriptors,
+ * a method handle's capability to call its underlying method is unrestricted.
+ * If a method handle is formed on a non-public method by a class
+ * that has access to that method, the resulting handle can be used
+ * in any place by any caller who receives a reference to it.
+ * <p>
+ * Unlike with the Core Reflection API, where access is checked every time
+ * a reflective method is invoked,
+ * method handle access checking is performed
+ * <a href="MethodHandles.Lookup.html#access">when the method handle is created</a>.
+ * In the case of {@code ldc} (see below), access checking is performed as part of linking
+ * the constant pool entry underlying the constant method handle.
+ * <p>
+ * Thus, handles to non-public methods, or to methods in non-public classes,
+ * should generally be kept secret.
  * They should not be passed to untrusted code unless their use from
  * the untrusted code would be harmless.
+ *
+ * <h3>Method handle creation</h3>
+ * Java code can create a method handle that directly accesses
+ * any method, constructor, or field that is accessible to that code.
+ * This is done via a reflective, capability-based API called
+ * {@link java.dyn.MethodHandles.Lookup MethodHandles.Lookup}
+ * For example, a static method handle can be obtained
+ * from {@link java.dyn.MethodHandles.Lookup#findStatic Lookup.findStatic}.
+ * There are also conversion methods from Core Reflection API objects,
+ * such as {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}.
  * <p>
- * Bytecode in the JVM can directly call a method handle's
- * {@code invokeExact} method from an {@code invokevirtual} instruction.
- * The receiver class type must be {@code MethodHandle} and the method name
- * must be {@code invokeExact}.  The signature of the invocation
- * (after resolving symbolic type names) must exactly match the method type
- * of the target method.
- * Similarly, bytecode can directly call a method handle's {@code invokeGeneric}
- * method.  The signature of the invocation (after resolving symbolic type names)
- * must either exactly match the method type or be a valid argument to
- * the target's {@link #asType asType} method.
- * <p>
- * Every {@code invokeExact} and {@code invokeGeneric} method always
- * throws {@link java.lang.Throwable Throwable},
- * which is to say that there is no static restriction on what a method handle
- * can throw.  Since the JVM does not distinguish between checked
- * and unchecked exceptions (other than by their class, of course),
- * there is no particular effect on bytecode shape from ascribing
- * checked exceptions to method handle invocations.  But in Java source
- * code, methods which perform method handle calls must either explicitly
- * throw {@code java.lang.Throwable Throwable}, or else must catch all
- * throwables locally, rethrowing only those which are legal in the context,
- * and wrapping ones which are illegal.
- * <p>
- * Bytecode in the JVM can directly obtain a method handle
- * for any accessible method from a {@code ldc} instruction
- * which refers to a {@code CONSTANT_MethodHandle} constant pool entry.
- * (Each such entry refers directly to a {@code CONSTANT_Methodref},
+ * Like classes and strings, method handles that correspond to accessible
+ * fields, methods, and constructors can also be represented directly
+ * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
+ * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
+ * refers directly to an associated {@code CONSTANT_Methodref},
  * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
  * constant pool entry.
- * For more details, see the <a href="package-summary.html#mhcon">package summary</a>.)
+ * (For more details on method handle constants,
+ * see the <a href="package-summary.html#mhcon">package summary</a>.)
  * <p>
- * Java code can also use a reflective API called
- * {@link java.dyn.MethodHandles.Lookup MethodHandles.Lookup}
- * for creating and calling method handles.
- * For example, a static method handle can be obtained
- * from {@link java.dyn.MethodHandles.Lookup#findStatic Lookup.findStatic}.
- * There are also bridge methods from Core Reflection API objects,
- * such as {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.ureflect}.
+ * Method handles produced by lookups or constant loads from methods or
+ * constructors with the variable arity modifier bit ({@code 0x0080})
+ * have a corresponding variable arity, as if they were defined with
+ * the help of {@link #asVarargsCollector asVarargsCollector}.
  * <p>
  * A method reference may refer either to a static or non-static method.
  * In the non-static case, the method handle type includes an explicit
@@ -153,61 +236,191 @@
  * When a method handle to a virtual method is invoked, the method is
  * always looked up in the receiver (that is, the first argument).
  * <p>
- * A non-virtual method handles to a specific virtual method implementation
+ * A non-virtual method handle to a specific virtual method implementation
  * can also be created.  These do not perform virtual lookup based on
  * receiver type.  Such a method handle simulates the effect of
  * an {@code invokespecial} instruction to the same method.
- * <p>
+ *
+ * <h3>Usage examples</h3>
  * Here are some examples of usage:
  * <p><blockquote><pre>
 Object x, y; String s; int i;
 MethodType mt; MethodHandle mh;
 MethodHandles.Lookup lookup = MethodHandles.lookup();
-// mt is {(char,char) =&gt; String}
+// mt is (char,char)String
 mt = MethodType.methodType(String.class, char.class, char.class);
 mh = lookup.findVirtual(String.class, "replace", mt);
-// (Ljava/lang/String;CC)Ljava/lang/String;
 s = (String) mh.invokeExact("daddy",'d','n');
+// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
 assert(s.equals("nanny"));
 // weakly typed invocation (using MHs.invoke)
 s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
 assert(s.equals("savvy"));
-// mt is {Object[] =&gt; List}
+// mt is (Object[])List
 mt = MethodType.methodType(java.util.List.class, Object[].class);
 mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
-// mt is {(Object,Object,Object) =&gt; Object}
+assert(mh.isVarargsCollector());
+x = mh.invokeGeneric("one", "two");
+// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
+assert(x.equals(java.util.Arrays.asList("one","two")));
+// mt is (Object,Object,Object)Object
 mt = MethodType.genericMethodType(3);
-mh = MethodHandles.collectArguments(mh, mt);
-// mt is {(Object,Object,Object) =&gt; Object}
-// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+mh = mh.asType(mt);
 x = mh.invokeExact((Object)1, (Object)2, (Object)3);
+// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 assert(x.equals(java.util.Arrays.asList(1,2,3)));
 // mt is { =&gt; int}
 mt = MethodType.methodType(int.class);
 mh = lookup.findVirtual(java.util.List.class, "size", mt);
-// (Ljava/util/List;)I
 i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
+// invokeExact(Ljava/util/List;)I
 assert(i == 3);
 mt = MethodType.methodType(void.class, String.class);
 mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
 mh.invokeExact(System.out, "Hello, world.");
-// (Ljava/io/PrintStream;Ljava/lang/String;)V
+// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
  * </pre></blockquote>
- * Each of the above calls generates a single invokevirtual instruction
- * with the name {@code invoke} and the type descriptors indicated in the comments.
- * The argument types are taken directly from the actual arguments,
- * while the return type is taken from the cast immediately applied to the call.
- * This cast may be to a primitive.
- * If it is missing, the type defaults to {@code Object} if the call
- * occurs in a context which uses the return value.
- * If the call occurs as a statement, a cast is impossible,
- * and there is no return type; the call is {@code void}.
+ * Each of the above calls to {@code invokeExact} or {@code invokeGeneric}
+ * generates a single invokevirtual instruction with
+ * the type descriptor indicated in the following comment.
+ *
+ * <h3>Exceptions</h3>
+ * The methods {@code invokeExact} and {@code invokeGeneric} are declared
+ * to throw {@link java.lang.Throwable Throwable},
+ * which is to say that there is no static restriction on what a method handle
+ * can throw.  Since the JVM does not distinguish between checked
+ * and unchecked exceptions (other than by their class, of course),
+ * there is no particular effect on bytecode shape from ascribing
+ * checked exceptions to method handle invocations.  But in Java source
+ * code, methods which perform method handle calls must either explicitly
+ * throw {@code java.lang.Throwable Throwable}, or else must catch all
+ * throwables locally, rethrowing only those which are legal in the context,
+ * and wrapping ones which are illegal.
+ *
+ * <h3><a name="sigpoly"></a>Signature polymorphism</h3>
+ * The unusual compilation and linkage behavior of
+ * {@code invokeExact} and {@code invokeGeneric}
+ * is referenced by the term <em>signature polymorphism</em>.
+ * A signature polymorphic method is one which can operate with
+ * any of a wide range of call signatures and return types.
+ * In order to make this work, both the Java compiler and the JVM must
+ * give special treatment to signature polymorphic methods.
  * <p>
- * <em>A note on generic typing:</em>  Method handles do not represent
- * their function types in terms of Java parameterized (generic) types,
- * because there are three mismatches between function types and parameterized
+ * In source code, a call to a signature polymorphic method will
+ * compile, regardless of the requested type descriptor.
+ * As usual, the Java compiler emits an {@code invokevirtual}
+ * instruction with the given type descriptor against the named method.
+ * The unusual part is that the type descriptor is derived from
+ * the actual argument and return types, not from the method declaration.
+ * <p>
+ * When the JVM processes bytecode containing signature polymorphic calls,
+ * it will successfully link any such call, regardless of its type descriptor.
+ * (In order to retain type safety, the JVM will guard such calls with suitable
+ * dynamic type checks, as described elsewhere.)
+ * <p>
+ * Bytecode generators, including the compiler back end, are required to emit
+ * untransformed type descriptors for these methods.
+ * Tools which determine symbolic linkage are required to accept such
+ * untransformed descriptors, without reporting linkage errors.
+ * <p>
+ * For the sake of tools (but not as a programming API), the signature polymorphic
+ * methods are marked with a private yet standard annotation,
+ * {@code @java.dyn.MethodHandle.PolymorphicSignature}.
+ * The annotation's retention is {@code RUNTIME}, so that all tools can see it.
+ *
+ * <h3>Formal rules for processing signature polymorphic methods</h3>
+ * <p>
+ * The following methods (and no others) are signature polymorphic:
+ * <ul>
+ * <li>{@link java.dyn.MethodHandle#invokeExact   MethodHandle.invokeExact}
+ * <li>{@link java.dyn.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
+ * </ul>
+ * <p>
+ * A signature polymorphic method will be declared with the following properties:
+ * <ul>
+ * <li>It must be native.
+ * <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 be contained within the {@code java.dyn} package.
+ * </ul>
+ * 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.
+ * However, the JVM will treat these declaration features as a documentation convention,
+ * rather than a description of the actual structure of the methods as executed.
+ * <p>
+ * When a call to a signature polymorphic method is compiled, the associated linkage information for
+ * its arguments is not array of {@code Object} (as for other similar varargs methods)
+ * but rather the erasure of the static types of all the arguments.
+ * <p>
+ * 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.
+ * (Note: This typing rule allows the null type to have its own encoding in linkage information
+ * distinct from other types.
+ * <p>
+ * The linkage information for the return type is derived from a context-dependent target typing convention.
+ * The return type for a signature polymorphic method invocation is determined as follows:
+ * <ul>
+ * <li>If the method invocation expression is an expression statement, the method is {@code void}.
+ * <li>Otherwise, if the method invocation expression is the immediate operand of a cast,
+ * the return type is the erasure of the cast type.
+ * <li>Otherwise, the return type is the method's nominal return type, {@code Object}.
+ * </ul>
+ * (Programmers are encouraged to use explicit casts unless it is clear that a signature polymorphic
+ * call will be used as a plain {@code Object} expression.)
+ * <p>
+ * The linkage information for argument and return types is stored in the descriptor for the
+ * compiled (bytecode) call site. As for any invocation instruction, the arguments and return value
+ * will be passed directly on the JVM stack, in accordance with the descriptor,
+ * and without implicit boxing or unboxing.
+ *
+ * <h3>Interoperation between method handles and the Core Reflection API</h3>
+ * Using factory methods in the {@link java.dyn.MethodHandles.Lookup Lookup} API,
+ * any class member represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent method handle.
+ * For example, a reflective {@link java.lang.reflect.Method Method} can
+ * be converted to a method handle using
+ * {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * The resulting method handles generally provide more direct and efficient
+ * access to the underlying class members.
+ * <p>
+ * As a special case,
+ * when the Core Reflection API is used to view the signature polymorphic
+ * methods {@code invokeExact} or {@code invokeGeneric} in this class,
+ * they appear as single, non-polymorphic native methods.
+ * Calls to these native methods do not result in method handle invocations.
+ * Since {@code invokevirtual} instructions can natively
+ * invoke method handles under any type descriptor, this reflective view conflicts
+ * with the normal presentation via bytecodes.
+ * Thus, these two native methods, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * are placeholders only.
+ * If invoked via {@link java.lang.reflect.Method#invoke Method.invoke},
+ * they will throw {@code UnsupportedOperationException}.
+ * <p>
+ * In order to obtain an invoker method for a particular type descriptor,
+ * use {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker},
+ * or {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker}.
+ * The {@link java.dyn.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle
+ * to call {@code invokeExact} or {@code invokeGeneric},
+ * for any specified type descriptor .
+ *
+ * <h3>Interoperation between method handles and Java generics</h3>
+ * A method handle can be obtained on a method, constructor, or field
+ * which is declared with Java generic types.
+ * As with the Core Reflection API, the type of the method handle
+ * will constructed from the erasure of the source-level type.
+ * When a method handle is invoked, the types of its arguments
+ * or the return value cast type may be generic types or type instances.
+ * If this occurs, the compiler will replace those
+ * types by their erasures when when it constructs the type descriptor
+ * for the {@code invokevirtual} instruction.
+ * <p>
+ * Method handles do not represent
+ * their function-like types in terms of Java parameterized (generic) types,
+ * because there are three mismatches between function-like types and parameterized
  * Java types.
- * <ol>
+ * <ul>
  * <li>Method types range over all possible arities,
  * from no arguments to up to 255 of arguments (a limit imposed by the JVM).
  * Generics are not variadic, and so cannot represent this.</li>
@@ -217,29 +430,7 @@
  * often generic across a wide range of function types, including
  * those of multiple arities.  It is impossible to represent such
  * genericity with a Java type parameter.</li>
- * </ol>
- * Signature polymorphic methods in this class appear to be documented
- * as having type parameters for return types and a parameter, but that is
- * merely a documentation convention.  These type parameters do
- * not play a role in type-checking method handle invocations.
- * <p>
- * Like classes and strings, method handles that correspond to accessible
- * fields, methods, and constructors can be represented directly
- * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
- * Loading such a constant causes the component classes of its type to be loaded as necessary.
- * <p>
- * Method handles cannot be subclassed by the user.
- * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
- * which may be visible via the {@code java.lang.Object#getClass Object.getClass}
- * operation.  The programmer should not draw conclusions about a method handle
- * from its specific class, as the method handle class hierarchy (if any)
- * may change from time to time or across implementations from different vendors.
- * <p>
- * With respect to the Java Memory Model, any method handle will behave
- * as if all of its fields are final variables.  This means that any method
- * handle made visible to the application will always be fully formed.
- * This is true even if the method handle is published through a shared
- * variables in a data race.
+ * </ul>
  *
  * @see MethodType
  * @see MethodHandles
@@ -251,15 +442,16 @@
         extends MethodHandleImpl
 {
     private static Access IMPL_TOKEN = Access.getToken();
+    static { MethodHandleImpl.initStatics(); }
 
     // interface MethodHandle<R throws X extends Exception,A...>
     // { MethodType<R throws X,A...> type(); public R invokeExact(A...) throws X; }
 
     /**
      * Internal marker interface which distinguishes (to the Java compiler)
-     * those methods which are signature polymorphic.
+     * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
      */
-    @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.TYPE})
+    @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
     @interface PolymorphicSignature { }
 
@@ -270,7 +462,7 @@
      * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
      * @return the method handle type
      */
-    public final MethodType type() {
+    public MethodType type() {
         return type;
     }
 
@@ -307,40 +499,27 @@
     }
 
     /**
-     * Returns a string representation of the method handle,
-     * starting with the string {@code "MethodHandle"} and
-     * ending with the string representation of the method handle's type.
-     * In other words, this method returns a string equal to the value of:
-     * <blockquote><pre>
-     * "MethodHandle" + type().toString()
-     * </pre></blockquote>
-     * <p>
-     * Note:  Future releases of this API may add further information
-     * to the string representation.
-     * Therefore, the present syntax should not be parsed by applications.
-     *
-     * @return a string representation of the method handle
-     */
-    @Override
-    public String toString() {
-        return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
-    }
-
-    /**
-     * Invoke the method handle, allowing any caller signature, but requiring an exact signature match.
-     * The signature at the call site of {@code invokeExact} must
+     * Invoke 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
      * exactly match this method handle's {@link #type type}.
      * No conversions are allowed on arguments or return values.
-     * @throws WrongMethodTypeException if the target's type is not identical with the caller's type signature
+     * <p>
+     * When this method is observed via the Core Reflection API,
+     * it will appear as a single native method, taking an object array and returning an object.
+     * If this native method is invoked directly via
+     * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
+     * or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect},
+     * it will throw an {@code UnsupportedOperationException}.
+     * @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
      */
     public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
 
     /**
-     * Invoke the method handle, allowing any caller signature,
-     * and optionally performing conversions for arguments and return types.
+     * Invoke the method handle, allowing any caller type descriptor,
+     * and optionally performing conversions on arguments and return values.
      * <p>
-     * If the call site signature exactly matches this method handle's {@link #type type},
+     * If the call site type descriptor exactly matches this method handle's {@link #type type},
      * the call proceeds as if by {@link #invokeExact invokeExact}.
      * <p>
      * Otherwise, the call proceeds as if this method handle were first
@@ -353,14 +532,20 @@
      * adaptations directly on the caller's arguments,
      * and call the target method handle according to its own exact type.
      * <p>
-     * If the method handle is equipped with a
-     * {@linkplain #withTypeHandler type handler}, the handler must produce
-     * an entry point of the call site's exact type.
-     * Otherwise, the signature at the call site of {@code invokeGeneric} must
-     * be a valid argument to the standard {@code asType} method.
+     * The type descriptor at the call site of {@code invokeGeneric} must
+     * be a valid argument to the receivers {@code asType} method.
      * In particular, the caller must specify the same argument arity
-     * as the callee's type.
-     * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's type signature
+     * as the callee's type,
+     * if the callee is not a {@linkplain #asVarargsCollector variable arity collector}.
+     * <p>
+     * When this method is observed via the Core Reflection API,
+     * it will appear as a single native method, taking an object array and returning an object.
+     * If this native method is invoked directly via
+     * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
+     * or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect},
+     * it will throw an {@code UnsupportedOperationException}.
+     * @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 Throwable anything thrown by the underlying method propagates unchanged through the method handle call
      */
     public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable;
@@ -400,16 +585,22 @@
      * <p>
      * This call is equivalent to the following code:
      * <p><blockquote><pre>
-     * MethodHandle invoker = MethodHandles.varargsInvoker(this.type(), 0);
+     * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
      * Object result = invoker.invokeExact(this, arguments);
      * </pre></blockquote>
+     * <p>
+     * Unlike the signature polymorphic methods {@code invokeExact} and {@code invokeGeneric},
+     * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
+     * It can therefore be used as a bridge between native or reflective code and method handles.
+     *
      * @param arguments the arguments to pass to the target
      * @return the result returned by the target
-     * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the arguments
+     * @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
-     * @see MethodHandles#varargsInvoker
+     * @see MethodHandles#spreadInvoker
      */
-    public final Object invokeWithArguments(Object... arguments) throws Throwable {
+    public Object invokeWithArguments(Object... arguments) throws Throwable {
         int argc = arguments == null ? 0 : arguments.length;
         MethodType type = type();
         if (type.parameterCount() != argc) {
@@ -417,7 +608,7 @@
             return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
         }
         if (argc <= 10) {
-            MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
+            MethodHandle invoker = invokers(type).genericInvoker();
             switch (argc) {
                 case 0:  return invoker.invokeExact(this);
                 case 1:  return invoker.invokeExact(this,
@@ -456,19 +647,11 @@
         }
 
         // more than ten arguments get boxed in a varargs list:
-        MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
+        MethodHandle invoker = invokers(type).spreadInvoker(0);
         return invoker.invokeExact(this, arguments);
     }
     /** Equivalent to {@code invokeWithArguments(arguments.toArray())}. */
-    public final Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
-        return invokeWithArguments(arguments.toArray());
-    }
-    @Deprecated
-    public final Object invokeVarargs(Object... arguments) throws Throwable {
-        return invokeWithArguments(arguments);
-    }
-    @Deprecated
-    public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
+    public Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
         return invokeWithArguments(arguments.toArray());
     }
 
@@ -488,13 +671,7 @@
      * to match up the caller's and callee's types.
      * <p>
      * This method is equivalent to {@link MethodHandles#convertArguments convertArguments},
-     * except for method handles produced by {@link #withTypeHandler withTypeHandler},
-     * in which case the specified type handler is used for calls to {@code asType}.
-     * <p>
-     * Note that the default behavior of {@code asType} only performs
-     * pairwise argument conversion and return value conversion.
-     * Because of this, unless the method handle has a type handler,
-     * the original type and new type must have the same number of arguments.
+     * except for variable arity method handles produced by {@link #asVarargsCollector asVarargsCollector}.
      *
      * @param newType the expected type of the new method handle
      * @return a method handle which delegates to {@code this} after performing
@@ -508,14 +685,16 @@
     }
 
     /**
-     * Produce a method handle which adapts, as its <i>target</i>,
+     * Make an adapter which accepts a trailing array argument
+     * and spreads its elements as positional arguments.
+     * The new method handle adapts, as its <i>target</i>,
      * the current method handle.  The type of the adapter will be
      * the same as the type of the target, except that the final
      * {@code arrayLength} parameters of the target's type are replaced
      * by a single array parameter of type {@code arrayType}.
      * <p>
      * If the array element type differs from any of the corresponding
-     * argument types on original target,
+     * argument types on the original target,
      * the original target is adapted to take the array elements directly,
      * as if by a call to {@link #asType asType}.
      * <p>
@@ -539,8 +718,9 @@
      * @throws IllegalArgumentException if target does not have at least
      *         {@code arrayLength} parameter types
      * @throws WrongMethodTypeException if the implied {@code asType} call fails
+     * @see #asCollector
      */
-    public final MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
+    public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
         Class<?> arrayElement = arrayType.getComponentType();
         if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
         MethodType oldType = type();
@@ -553,13 +733,15 @@
     }
 
     /**
-     * Produce a method handle which adapts, as its <i>target</i>,
+     * Make an adapter which accepts a given number of trailing
+     * positional arguments and collects them into an array argument.
+     * The new method handle adapts, as its <i>target</i>,
      * the current method handle.  The type of the adapter will be
      * the same as the type of the target, except that a single trailing
      * parameter (usually of type {@code arrayType}) is replaced by
      * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
      * <p>
-     * If the array type differs from the final argument type on original target,
+     * If the array type differs from the final argument type on the original target,
      * the original target is adapted to take the array type directly,
      * as if by a call to {@link #asType asType}.
      * <p>
@@ -570,21 +752,31 @@
      * What the target eventually returns is returned unchanged by the adapter.
      * <p>
      * (The array may also be a shared constant when {@code arrayLength} is zero.)
-     * @param arrayType usually {@code Object[]}, the type of the array argument which will collect the arguments
+     * <p>
+     * (<em>Note:</em> The {@code arrayType} is often identical to the last
+     * parameter type of the original target.
+     * It is an explicit argument for symmetry with {@code asSpreader}, and also
+     * to allow the target to use a simple {@code Object} as its last parameter type.)
+     * <p>
+     * In order to create a collecting adapter which is not restricted to a particular
+     * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
+     * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
      * @param arrayLength the number of arguments to collect into a new array argument
      * @return a new method handle which collects some trailing argument
      *         into an array, before calling the original method handle
      * @throws IllegalArgumentException if {@code arrayType} is not an array type
-               or {@code arrayType} is not assignable to this method handle's trailing parameter type
-     * @throws IllegalArgumentException if {@code arrayLength} is not
-     *         a legal array size
+     *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
+     *         or {@code arrayLength} is not a legal array size
      * @throws WrongMethodTypeException if the implied {@code asType} call fails
+     * @see #asSpreader
+     * @see #asVarargsCollector
      */
-    public final MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
+    public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
         Class<?> arrayElement = arrayType.getComponentType();
         if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
         MethodType oldType = type();
         int nargs = oldType.parameterCount();
+        if (nargs == 0)  throw newIllegalArgumentException("no trailing argument");
         MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
         newType = newType.insertParameterTypes(nargs-1,
                     java.util.Collections.<Class<?>>nCopies(arrayLength, arrayElement));
@@ -592,8 +784,185 @@
     }
 
     /**
-     * Produce a method handle which binds the given argument
-     * to the current method handle as <i>target</i>.
+     * Make a <em>variable arity</em> adapter which is able to accept
+     * any number of trailing positional arguments and collect them
+     * into an array argument.
+     * <p>
+     * The type and behavior of the adapter will be the same as
+     * the type and behavior of the target, except that certain
+     * {@code invokeGeneric} and {@code asType} requests can lead to
+     * trailing positional arguments being collected into target's
+     * trailing parameter.
+     * Also, the last parameter type of the adapter will be
+     * {@code arrayType}, even if the target has a different
+     * last parameter type.
+     * <p>
+     * When called with {@link #invokeExact invokeExact}, the adapter invokes
+     * the target with no argument changes.
+     * (<em>Note:</em> This behavior is different from a
+     * {@linkplain #asCollector fixed arity collector},
+     * since it accepts a whole array of indeterminate length,
+     * rather than a fixed number of arguments.)
+     * <p>
+     * When called with {@link #invokeGeneric invokeGeneric}, if the caller
+     * type is the same as the adapter, the adapter invokes the target as with
+     * {@code invokeExact}.
+     * (This is the normal behavior for {@code invokeGeneric} when types match.)
+     * <p>
+     * Otherwise, if the caller and adapter arity are the same, and the
+     * trailing parameter type of the caller is a reference type identical to
+     * or assignable to the trailing parameter type of the adapter,
+     * the arguments and return values are converted pairwise,
+     * as if by {@link MethodHandles#convertArguments convertArguments}.
+     * (This is also normal behavior for {@code invokeGeneric} in such a case.)
+     * <p>
+     * Otherwise, the arities differ, or the adapter's trailing parameter
+     * type is not assignable from the corresponding caller type.
+     * In this case, the adapter replaces all trailing arguments from
+     * the original trailing argument position onward, by
+     * a new array of type {@code arrayType}, whose elements
+     * comprise (in order) the replaced arguments.
+     * <p>
+     * The caller type must provides as least enough arguments,
+     * and of the correct type, to satisfy the target's requirement for
+     * positional arguments before the trailing array argument.
+     * Thus, the caller must supply, at a minimum, {@code N-1} arguments,
+     * where {@code N} is the arity of the target.
+     * Also, there must exist conversions from the incoming arguments
+     * to the target's arguments.
+     * As with other uses of {@code invokeGeneric}, if these basic
+     * requirements are not fulfilled, a {@code WrongMethodTypeException}
+     * may be thrown.
+     * <p>
+     * In all cases, what the target eventually returns is returned unchanged by the adapter.
+     * <p>
+     * In the final case, it is exactly as if the target method handle were
+     * temporarily adapted with a {@linkplain #asCollector fixed arity collector}
+     * to the arity required by the caller type.
+     * (As with {@code asCollector}, if the array length is zero,
+     * a shared constant may be used instead of a new array.
+     * If the implied call to {@code asCollector} would throw
+     * an {@code IllegalArgumentException} or {@code WrongMethodTypeException},
+     * the call to the variable arity adapter must throw
+     * {@code WrongMethodTypeException}.)
+     * <p>
+     * The behavior of {@link #asType asType} is also specialized for
+     * variable arity adapters, to maintain the invariant that
+     * {@code invokeGeneric} is always equivalent to an {@code asType}
+     * call to adjust the target type, followed by {@code invokeExact}.
+     * Therefore, a variable arity adapter responds
+     * to an {@code asType} request by building a fixed arity collector,
+     * if and only if the adapter and requested type differ either
+     * in arity or trailing argument type.
+     * The resulting fixed arity collector has its type further adjusted
+     * (if necessary) to the requested type by pairwise conversion,
+     * as if by another application of {@code asType}.
+     * <p>
+     * When a method handle is obtained by executing an {@code ldc} instruction
+     * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
+     * as a variable arity method (with the modifier bit {@code 0x0080}),
+     * the method handle will accept multiple arities, as if the method handle
+     * constant were created by means of a call to {@code asVarargsCollector}.
+     * <p>
+     * In order to create a collecting adapter which collects a predetermined
+     * number of arguments, and whose type reflects this predetermined number,
+     * use {@link #asCollector asCollector} instead.
+     * <p>
+     * No method handle transformations produce new method handles with
+     * variable arity, unless they are documented as doing so.
+     * Therefore, besides {@code asVarargsCollector},
+     * all methods in {@code MethodHandle} and {@code MethodHandles}
+     * will return a method handle with fixed arity,
+     * except in the cases where they are specified to return their original
+     * operand (e.g., {@code asType} of the method handle's own type).
+     * <p>
+     * Calling {@code asVarargsCollector} on a method handle which is already
+     * of variable arity will produce a method handle with the same type and behavior.
+     * It may (or may not) return the original variable arity method handle.
+     * <p>
+     * Here is an example, of a list-making variable arity method handle:
+     * <blockquote><pre>
+MethodHandle asList = publicLookup()
+  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
+  .asVarargsCollector(Object[].class);
+assertEquals("[]", asList.invokeGeneric().toString());
+assertEquals("[1]", asList.invokeGeneric(1).toString());
+assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString());
+Object[] argv = { "three", "thee", "tee" };
+assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString());
+List ls = (List) asList.invokeGeneric((Object)argv);
+assertEquals(1, ls.size());
+assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
+     * </pre></blockquote>
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * These rules are designed as a dynamically-typed variation
+     * of the Java rules for variable arity methods.
+     * In both cases, callers to a variable arity method or method handle
+     * can either pass zero or more positional arguments, or else pass
+     * pre-collected arrays of any length.  Users should be aware of the
+     * special role of the final argument, and of the effect of a
+     * type match on that final argument, which determines whether
+     * or not a single trailing argument is interpreted as a whole
+     * array or a single element of an array to be collected.
+     * Note that the dynamic type of the trailing argument has no
+     * effect on this decision, only a comparison between the static
+     * type descriptor of the call site and the type of the method handle.)
+     * <p style="font-size:smaller;">
+     * As a result of the previously stated rules, the variable arity behavior
+     * of a method handle may be suppressed, by binding it to the exact invoker
+     * of its own type, as follows:
+     * <blockquote><pre>
+MethodHandle vamh = publicLookup()
+  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
+  .asVarargsCollector(Object[].class);
+MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh);
+assert(vamh.type().equals(mh.type()));
+assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString());
+boolean failed = false;
+try { mh.invokeGeneric(1,2,3); }
+catch (WrongMethodTypeException ex) { failed = true; }
+assert(failed);
+     * </pre></blockquote>
+     * This transformation has no behavioral effect if the method handle is
+     * not of variable arity.
+     *
+     * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
+     * @return a new method handle which can collect any number of trailing arguments
+     *         into an array, before calling the original method handle
+     * @throws IllegalArgumentException if {@code arrayType} is not an array type
+     *         or {@code arrayType} is not assignable to this method handle's trailing parameter type
+     * @see #asCollector
+     * @see #isVarargsCollector
+     */
+    public MethodHandle asVarargsCollector(Class<?> arrayType) {
+        Class<?> arrayElement = arrayType.getComponentType();
+        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
+        return MethodHandles.asVarargsCollector(this, arrayType);
+    }
+
+    /**
+     * Determine if this method handle
+     * supports {@linkplain #asVarargsCollector variable arity} calls.
+     * Such method handles arise from the following sources:
+     * <ul>
+     * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
+     * <li>a call to a {@linkplain java.dyn.MethodHandles.Lookup lookup method}
+     *     which resolves to a variable arity Java method or constructor
+     * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
+     *     which resolves to a variable arity Java method or constructor
+     * </ul>
+     * @return true if this method handle accepts more than one arity of {@code invokeGeneric} calls
+     * @see #asVarargsCollector
+     */
+    public boolean isVarargsCollector() {
+        return false;
+    }
+
+    /**
+     * Bind 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>,
+     * to the current method handle.
      * The type of the bound handle will be
      * the same as the type of the target, except that a single leading
      * reference parameter will be omitted.
@@ -614,79 +983,27 @@
      *         to the leading parameter type of the target
      * @see MethodHandles#insertArguments
      */
-    public final MethodHandle bindTo(Object x) {
+    public MethodHandle bindTo(Object x) {
         return MethodHandles.insertArguments(this, 0, x);
     }
 
     /**
-     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
-     * Create a new method handle with the same type as this one,
-     * but whose {@code asType} method invokes the given
-     * {@code typeHandler} on this method handle,
-     * instead of the standard {@code MethodHandles.convertArguments}.
-     * <p>
-     * The new method handle will have the same behavior as the
-     * old one when invoked by {@code invokeExact}.
-     * For {@code invokeGeneric} calls which exactly match
-     * the method type, the two method handles will also
-     * have the same behavior.
-     * For other {@code invokeGeneric} calls, the {@code typeHandler}
-     * will control the behavior of the new method handle.
-     * <p>
-     * Thus, a method handle with an {@code asType} handler can
-     * be configured to accept more than one arity of {@code invokeGeneric}
-     * call, and potentially every possible arity.
-     * It can also be configured to supply default values for
-     * optional arguments, when the caller does not specify them.
-     * <p>
-     * The given method handle must take two arguments and return
-     * one result.  The result it returns must be a method handle
-     * of exactly the requested type.  If the result returned by
-     * the target is null, a {@link NullPointerException} is thrown,
-     * else if the type of the target does not exactly match
-     * the requested type, a {@link WrongMethodTypeException} is thrown.
-     * <p>
-     * A method handle's type handler is not guaranteed to be called every
-     * time its {@code asType} or {@code invokeGeneric} method is called.
-     * If the implementation is faced is able to prove that an equivalent
-     * type handler call has already occurred (on the same two arguments),
-     * it may substitute the result of that previous invocation, without
-     * making a new invocation.  Thus, type handlers should not (in general)
-     * perform significant side effects.
-     * <p>
-     * Therefore, the type handler is invoked as if by this code:
+     * Returns a string representation of the method handle,
+     * starting with the string {@code "MethodHandle"} and
+     * ending with the string representation of the method handle's type.
+     * In other words, this method returns a string equal to the value of:
      * <blockquote><pre>
-     * MethodHandle target = this;      // original method handle
-     * MethodHandle adapter = ...;      // adapted method handle
-     * MethodType requestedType = ...;  // argument to asType()
-     * if (type().equals(requestedType))
-     *    return adapter;
-     * MethodHandle result = (MethodHandle)
-     *    typeHandler.invokeGeneric(target, requestedType);
-     * if (!result.type().equals(requestedType))
-     *    throw new WrongMethodTypeException();
-     * return result;
+     * "MethodHandle" + type().toString()
      * </pre></blockquote>
      * <p>
-     * For example, here is a list-making variable-arity method handle:
-     * <blockquote><pre>
-MethodHandle makeEmptyList = MethodHandles.constant(List.class, Arrays.asList());
-MethodHandle asList = lookup()
-  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
-static MethodHandle collectingTypeHandler(MethodHandle base, MethodType newType) {
-  return asList.asCollector(Object[].class, newType.parameterCount()).asType(newType);
-}
-MethodHandle collectingTypeHandler = lookup()
-  .findStatic(lookup().lookupClass(), "collectingTypeHandler",
-     methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
-MethodHandle makeAnyList = makeEmptyList.withTypeHandler(collectingTypeHandler);
-
-assertEquals("[]", makeAnyList.invokeGeneric().toString());
-assertEquals("[1]", makeAnyList.invokeGeneric(1).toString());
-assertEquals("[two, too]", makeAnyList.invokeGeneric("two", "too").toString());
-     * <pre><blockquote>
+     * Note:  Future releases of this API may add further information
+     * to the string representation.
+     * Therefore, the present syntax should not be parsed by applications.
+     *
+     * @return a string representation of the method handle
      */
-    public MethodHandle withTypeHandler(MethodHandle typeHandler) {
-        return MethodHandles.withTypeHandler(this, typeHandler);
+    @Override
+    public String toString() {
+        return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
     }
 }
--- a/src/share/classes/java/dyn/MethodHandles.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/MethodHandles.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import sun.dyn.Access;
 import sun.dyn.MemberName;
 import sun.dyn.MethodHandleImpl;
+import sun.dyn.WrapperInstance;
 import sun.dyn.util.ValueConversions;
 import sun.dyn.util.VerifyAccess;
 import sun.dyn.util.Wrapper;
@@ -45,10 +46,10 @@
  * This class consists exclusively of static methods that operate on or return
  * method handles. They fall into several categories:
  * <ul>
- * <li>Factory methods which create method handles for methods and fields.
- * <li>Invoker methods which can invoke method handles on dynamically typed arguments and/or varargs arrays.
- * <li>Combinator methods, which combine or transforming pre-existing method handles into new ones.
- * <li>Factory methods which create method handles that emulate other common JVM operations or control flow patterns.
+ * <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>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".
  * </ul>
  * <p>
  * @author John Rose, JSR 292 EG
@@ -97,47 +98,155 @@
      * when the creation requires access checking.
      * Method handles do not perform
      * access checks when they are called, but rather when they are created.
-     * (This is a major difference
-     * from reflective {@link Method}, which performs access checking
-     * against every caller, on every call.)
      * Therefore, method handle access
      * restrictions must be enforced when a method handle is created.
      * The caller class against which those restrictions are enforced
      * is known as the {@linkplain #lookupClass lookup class}.
-     * A lookup object embodies an
-     * authenticated lookup class, and can be used to create any number
+     * <p>
+     * A lookup class which needs to create method handles will call
+     * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
+     * When the {@code Lookup} factory object is created, the identity of the lookup class is
+     * determined, and securely stored in the {@code Lookup} object.
+     * The lookup class (or its delegates) may then use factory methods
+     * on the {@code Lookup} object to create method handles for access-checked members.
+     * This includes all methods, constructors, and fields which are allowed to the lookup class,
+     * even private ones.
+     * <p>
+     * The factory methods on a {@code Lookup} object correspond to all major
+     * use cases for methods, constructors, and fields.
+     * Here is a summary of the correspondence between these factory methods and
+     * the behavior the resulting method handles:
+     * <code>
+     * <table border=1 cellpadding=5 summary="lookup method behaviors">
+     * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
+     *     <td>FT f;</td><td>(T) this.f;</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
+     *     <td>static<br>FT f;</td><td>(T) C.f;</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
+     *     <td>FT f;</td><td>this.f = x;</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
+     *     <td>static<br>FT f;</td><td>C.f = arg;</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
+     *     <td>T m(A*);</td><td>(T) this.m(arg*);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
+     *     <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
+     *     <td>T m(A*);</td><td>(T) super.m(arg*);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
+     *     <td>C(A*);</td><td>(T) new C(arg*);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
+     *     <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
+     *     <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+     *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
+     *     <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td>
+     * </tr>
+     * <tr>
+     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+     *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
+     * </tr>
+     * </table>
+     * </code>
+     * Here, the type {@code C} is the class or interface being searched for a member,
+     * documented as a parameter named {@code refc} in the lookup methods.
+     * The method or constructor type {@code MT} is composed from the return type {@code T}
+     * and the sequence of argument types {@code A*}.
+     * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
+     * The formal parameter {@code this} stands for the self-reference of type {@code C};
+     * if it is present, it is always the leading argument to the method handle invocation.
+     * The name {@code arg} stands for all the other method handle arguments.
+     * In the code examples for the Core Reflection API, the name {@code thisOrNull}
+     * stands for a null reference if the accessed method or field is static,
+     * and {@code this} otherwise.
+     * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
+     * for reflective objects corresponding to the given members.
+     * <p>
+     * The equivalence between looked-up method handles and underlying
+     * class members can break down in a few ways:
+     * <ul>
+     * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
+     * the lookup can still succeed, even when there is no equivalent
+     * Java expression or bytecoded constant.
+     * <li>Likewise, if {@code T} or {@code MT}
+     * is not symbolically accessible from the lookup class's loader,
+     * the lookup can still succeed.
+     * For example, lookups for {@code MethodHandle.invokeExact} and
+     * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
+     * <li>If there is a security manager installed, it can forbid the lookup
+     * on various grounds (<a href="#secmgr">see below</a>).
+     * By contrast, the {@code ldc} instruction is not subject to
+     * security manager checks.
+     * </ul>
+     *
+     * <h3><a name="access"></a>Access checking</h3>
+     * Access checks are applied in the factory methods of {@code Lookup},
+     * when a method handle is created.
+     * This is a key difference from the Core Reflection API, since
+     * {@link java.lang.reflect.Method#invoke Method.invoke}
+     * performs access checking against every caller, on every call.
+     * <p>
+     * All access checks start from a {@code Lookup} object, which
+     * compares its recorded lookup class against all requests to
+     * create method handles.
+     * A single {@code Lookup} object can be used to create any number
      * of access-checked method handles, all checked against a single
      * lookup class.
      * <p>
-     * A class which needs to create method handles will call
-     * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
-     * It may then use this factory to create method handles on
-     * all of its methods, including private ones.
-     * It may also delegate the lookup (e.g., to a metaobject protocol)
-     * by passing the lookup object to other code.
-     * If this other code creates method handles, they will be access
-     * checked against the original lookup class, and not with any higher
-     * privileges.
+     * A {@code Lookup} object can be shared with other trusted code,
+     * such as a metaobject protocol.
+     * A shared {@code Lookup} object delegates the capability
+     * to create method handles on private members of the lookup class.
+     * Even if privileged code uses the {@code Lookup} object,
+     * the access checking is confined to the privileges of the
+     * original lookup class.
      * <p>
-     * Access checks only apply to named and reflected methods.
-     * Other method handle creation methods, such as
-     * {@link #convertArguments MethodHandles.convertArguments},
-     * do not require any access checks, and can be done independently
-     * of any lookup class.
-     * <h3>How access errors are handled</h3>
      * A lookup can fail, because
      * the containing class is not accessible to the lookup class, or
      * because the desired class member is missing, or because the
      * desired class member is not accessible to the lookup class.
-     * It can also fail if a security manager is installed and refuses
-     * access.  In any of these cases, an exception will be
-     * thrown from the attempted lookup.
+     * In any of these cases, a {@code ReflectiveOperationException} will be
+     * thrown from the attempted lookup.  The exact class will be one of
+     * the following:
+     * <ul>
+     * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
+     * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
+     * <li>IllegalAccessException &mdash; if the member exists but an access check fails
+     * </ul>
      * <p>
      * In general, the conditions under which a method handle may be
-     * created for a method {@code M} are exactly as restrictive as the conditions
-     * under which the lookup class could have compiled a call to {@code M}.
+     * looked up for a method {@code M} are exactly equivalent to the conditions
+     * under which the lookup class could have compiled and resolved a call to {@code M}.
+     * And the effect of invoking the method handle resulting from the lookup
+     * is exactly equivalent to executing the compiled and resolved call to {@code M}.
+     * The same point is true of fields and constructors.
      * <p>
-     * In some cases, this access is obtained by the Java compiler by creating
+     * In some cases, access between nested classes is obtained by the Java compiler by creating
      * an wrapper method to access a private method of another class
      * in the same top-level declaration.
      * For example, a nested class {@code C.D}
@@ -149,6 +258,61 @@
      * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
      * which can transform a lookup on {@code C.E} into one on any of those other
      * classes, without special elevation of privilege.
+     * <p>
+     * Although bytecode instructions can only refer to classes in
+     * a related class loader, this API can search for methods in any
+     * class, as long as a reference to its {@code Class} object is
+     * available.  Such cross-loader references are also possible with the
+     * Core Reflection API, and are impossible to bytecode instructions
+     * such as {@code invokestatic} or {@code getfield}.
+     * There is a {@linkplain java.lang.SecurityManager security manager API}
+     * to allow applications to check such cross-loader references.
+     * These checks apply to both the {@code MethodHandles.Lookup} API
+     * and the Core Reflection API
+     * (as found on {@link java.lang.Class Class}).
+     * <p>
+     * Access checks only apply to named and reflected methods,
+     * constructors, and fields.
+     * Other method handle creation methods, such as
+     * {@link #convertArguments MethodHandles.convertArguments},
+     * do not require any access checks, and are done
+     * with static methods of {@link MethodHandles},
+     * independently of any {@code Lookup} object.
+     *
+     * <h3>Security manager interactions</h3>
+     * <a name="secmgr"></a>
+     * If a security manager is present, member lookups are subject to
+     * additional checks.
+     * From one to four calls are made to the security manager.
+     * Any of these calls can refuse access by throwing a
+     * {@link java.lang.SecurityException SecurityException}.
+     * Define {@code smgr} as the security manager,
+     * {@code refc} as the containing class in which the member
+     * is being sought, and {@code defc} as the class in which the
+     * member is actually defined.
+     * The calls are made according to the following rules:
+     * <ul>
+     * <li>In all cases, {@link SecurityManager#checkMemberAccess
+     *     smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
+     * <li>If the class loader of the lookup class is not
+     *     the same as or an ancestor of the class loader of {@code refc},
+     *     then {@link SecurityManager#checkPackageAccess
+     *     smgr.checkPackageAccess(refcPkg)} is called,
+     *     where {@code refcPkg} is the package of {@code refc}.
+     * <li>If the retrieved member is not public,
+     *     {@link SecurityManager#checkMemberAccess
+     *     smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
+     *     (Note that {@code defc} might be the same as {@code refc}.)
+     * <li>If the retrieved member is not public,
+     *     and if {@code defc} and {@code refc} are in different class loaders,
+     *     and if the class loader of the lookup class is not
+     *     the same as or an ancestor of the class loader of {@code defc},
+     *     then {@link SecurityManager#checkPackageAccess
+     *     smgr.checkPackageAccess(defcPkg)} is called,
+     *     where {@code defcPkg} is the package of {@code defc}.
+     * </ul>
+     * In all cases, the requesting class presented to the security
+     * manager will be the lookup class from the current {@code Lookup} object.
      */
     public static final
     class Lookup {
@@ -194,12 +358,12 @@
             return (mods != 0) ? mods : PACKAGE;
         }
 
-        /** Which class is performing the lookup?  It is this class against
+        /** Tells which class is performing the lookup.  It is this class against
          *  which checks are performed for visibility and access permissions.
          *  <p>
          *  The class implies a maximum level of access permission,
          *  but the permissions may be additionally limited by the bitmask
-         *  {@link #lookupModes}, which controls whether non-public members
+         *  {@link #lookupModes lookupModes}, which controls whether non-public members
          *  can be accessed.
          */
         public Class<?> lookupClass() {
@@ -211,7 +375,7 @@
             return (allowedModes == TRUSTED) ? null : lookupClass;
         }
 
-        /** Which types of members can this lookup object produce?
+        /** Tells which access-protection classes of members this lookup object can produce.
          *  The result is a bit-mask of the bits
          *  {@linkplain #PUBLIC PUBLIC (0x01)},
          *  {@linkplain #PRIVATE PRIVATE (0x02)},
@@ -257,7 +421,7 @@
         }
 
         /**
-         * Create a lookup on the specified new lookup class.
+         * Creates a lookup on the specified new lookup class.
          * The resulting object will report the specified
          * class as its own {@link #lookupClass lookupClass}.
          * <p>
@@ -275,6 +439,10 @@
          * then no members, not even public members, will be accessible.
          * (In all other cases, public members will continue to be accessible.)
          * </ul>
+         *
+         * @param requestedLookupClass the desired lookup class for the new lookup object
+         * @return a lookup object which reports the desired lookup class
+         * @throws NullPointerException if the argument is null
          */
         public Lookup in(Class<?> requestedLookupClass) {
             requestedLookupClass.getClass();  // null check
@@ -322,11 +490,12 @@
         }
 
         /**
-         * Display the name of the class from which lookups are to be made.
+         * Displays the name of the class from which lookups are to be made.
          * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
          * If there are restrictions on the access permitted to this lookup,
          * this is indicated by adding a suffix to the class name, consisting
-         * of a slash and a keyword.  The keyword is chosen as follows:
+         * of a slash and a keyword.  The keyword represents the strongest
+         * allowed access, and is chosen as follows:
          * <ul>
          * <li>If no access is allowed, the suffix is "/noaccess".
          * <li>If only public access is allowed, the suffix is "/public".
@@ -337,26 +506,37 @@
          * access (public, package, private, and protected) is allowed.
          * In this case, no suffix is added.
          * This is true only of an object obtained originally from
-         * {@link java.dyn.MethodHandles#lookup() MethodHandles.lookup}.
-         * Objects created by {@link java.dyn.MethodHandles.Lookup#in() Lookup#in}
+         * {@link java.dyn.MethodHandles#lookup MethodHandles.lookup}.
+         * Objects created by {@link java.dyn.MethodHandles.Lookup#in Lookup.in}
          * always have restricted access, and will display a suffix.
+         * <p>
+         * (It may seem strange that protected access should be
+         * stronger than private access.  Viewed independently from
+         * package access, protected access is the first to be lost,
+         * because it requires a direct subclass relationship between
+         * caller and callee.)
+         * @see #in
          */
         @Override
         public String toString() {
             String cname = lookupClass.getName();
             switch (allowedModes) {
-            case TRUSTED:
-                return "/trusted";  // internal only
+            case 0:  // no privileges
+                return cname + "/noaccess";
             case PUBLIC:
                 return cname + "/public";
             case PUBLIC|PACKAGE:
                 return cname + "/package";
-            case 0:  // no privileges
-                return cname + "/noaccess";
+            case ALL_MODES & ~PROTECTED:
+                return cname + "/private";
             case ALL_MODES:
                 return cname;
-            default:
-                return cname + "/private";
+            case TRUSTED:
+                return "/trusted";  // internal only; not exported
+            default:  // Should not happen, but it's a bitfield...
+                cname = cname + "/" + Integer.toHexString(allowedModes);
+                assert(false) : cname;
+                return cname;
             }
         }
 
@@ -371,29 +551,37 @@
         }
 
         /**
-         * Produce a method handle for a static method.
+         * Produces a method handle for a static method.
          * The type of the method handle will be that of the method.
          * (Since static methods do not take receivers, there is no
          * additional receiver argument inserted into the method handle type,
-         * as there would be with {@link #findVirtual} or {@link #findSpecial}.)
+         * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
          * The method and all its argument types must be accessible to the lookup class.
          * If the method's class has not yet been initialized, that is done
          * immediately, before the method handle is returned.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
          * @param refc the class from which the method is accessed
          * @param name the name of the method
          * @param type the type of the method
          * @return the desired method handle
-         * @exception NoAccessException if the method does not exist or access checking fails
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
         public
-        MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoAccessException {
+        MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             MemberName method = resolveOrFail(refc, name, type, true);
             checkMethod(refc, method, true);
             return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull());
         }
 
         /**
-         * Produce a method handle for a virtual method.
+         * Produces a method handle for a virtual method.
          * The type of the method handle will be that of the method,
          * with the receiver type (usually {@code refc}) prepended.
          * The method and all its argument types must be accessible to the lookup class.
@@ -403,13 +591,31 @@
          * implementation to enter.
          * (The dispatching action is identical with that performed by an
          * {@code invokevirtual} or {@code invokeinterface} instruction.)
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * Because of the general equivalence between {@code invokevirtual}
+         * instructions and method handles produced by {@code findVirtual},
+         * if the class is {@code MethodHandle} and the name string is
+         * {@code invokeExact} or {@code invokeGeneric}, the resulting
+         * method handle is equivalent to one produced by
+         * {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
+         * {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker}
+         * with the same {@code type} argument.
+         *
          * @param refc the class or interface from which the method is accessed
          * @param name the name of the method
          * @param type the type of the method, with the receiver argument omitted
          * @return the desired method handle
-         * @exception NoAccessException if the method does not exist or access checking fails
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails, or if the method is {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoAccessException {
+        public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             MemberName method = resolveOrFail(refc, name, type, false);
             checkMethod(refc, method, false);
             MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
@@ -417,7 +623,7 @@
         }
 
         /**
-         * Produce a method handle which creates an object and initializes it, using
+         * Produces a method handle which creates an object and initializes it, using
          * the constructor of the specified type.
          * The parameter types of the method handle will be those of the constructor,
          * while the return type will be a reference to the constructor's class.
@@ -426,23 +632,47 @@
          * immediately, before the method handle is returned.
          * <p>
          * Note:  The requested type must have a return type of {@code void}.
-         * This is consistent with the JVM's treatment of constructor signatures.
+         * This is consistent with the JVM's treatment of constructor type descriptors.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
          * @param refc the class or interface from which the method is accessed
          * @param type the type of the method, with the receiver argument omitted, and a void return type
          * @return the desired method handle
-         * @exception NoAccessException if the method does not exist or access checking fails
+         * @throws NoSuchMethodException if the constructor does not exist
+         * @throws IllegalAccessException if access checking fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoAccessException {
+        public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             String name = "<init>";
             MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
             assert(ctor.isConstructor());
             checkAccess(refc, ctor);
             MethodHandle rawMH = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull());
-            return MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawMH);
+            MethodHandle allocMH = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawMH);
+            return fixVarargs(allocMH, rawMH);
+        }
+
+        /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
+        private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
+            boolean va1 = mh.isVarargsCollector();
+            boolean va2 = matchMH.isVarargsCollector();
+            if (va1 == va2) {
+                return mh;
+            } else if (va2) {
+                MethodType type = mh.type();
+                int arity = type.parameterCount();
+                return mh.asVarargsCollector(type.parameterType(arity-1));
+            } else {
+                throw new InternalError("already varargs, but template is not: "+mh);
+            }
         }
 
         /**
-         * Produce an early-bound method handle for a virtual method,
+         * Produces an early-bound method handle for a virtual method,
          * as if called from an {@code invokespecial}
          * instruction from {@code caller}.
          * The type of the method handle will be that of the method,
@@ -458,15 +688,23 @@
          * If the explicitly specified caller class is not identical with the
          * lookup class, or if this lookup object does not have private access
          * privileges, the access fails.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
          * @param refc the class or interface from which the method is accessed
          * @param name the name of the method (which must not be "&lt;init&gt;")
          * @param type the type of the method, with the receiver argument omitted
          * @param specialCaller the proposed calling class to perform the {@code invokespecial}
          * @return the desired method handle
-         * @exception NoAccessException if the method does not exist or access checking fails
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
-                                        Class<?> specialCaller) throws NoAccessException {
+                                        Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
             checkSpecialCaller(specialCaller);
             MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
             checkMethod(refc, method, false);
@@ -475,69 +713,89 @@
         }
 
         /**
-         * Produce a method handle giving read access to a non-static field.
+         * Produces a method handle giving read access to a non-static field.
          * The type of the method handle will have a return type of the field's
          * value type.
          * The method handle's single argument will be the instance containing
          * the field.
          * Access checking is performed immediately on behalf of the lookup class.
+         * @param refc the class or interface from which the method is accessed
          * @param name the field's name
          * @param type the field's type
          * @return a method handle which can load values from the field
-         * @exception NoAccessException if access checking fails
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoAccessException {
+        public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             return makeAccessor(refc, name, type, false, false);
         }
 
         /**
-         * Produce a method handle giving write access to a non-static field.
+         * Produces a method handle giving write access to a non-static field.
          * The type of the method handle will have a void return type.
          * The method handle will take two arguments, the instance containing
          * the field, and the value to be stored.
          * The second argument will be of the field's value type.
          * Access checking is performed immediately on behalf of the lookup class.
+         * @param refc the class or interface from which the method is accessed
          * @param name the field's name
          * @param type the field's type
          * @return a method handle which can store values into the field
-         * @exception NoAccessException if access checking fails
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoAccessException {
+        public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             return makeAccessor(refc, name, type, false, true);
         }
 
         /**
-         * Produce a method handle giving read access to a static field.
+         * Produces a method handle giving read access to a static field.
          * The type of the method handle will have a return type of the field's
          * value type.
          * The method handle will take no arguments.
          * Access checking is performed immediately on behalf of the lookup class.
+         * @param refc the class or interface from which the method is accessed
          * @param name the field's name
          * @param type the field's type
          * @return a method handle which can load values from the field
-         * @exception NoAccessException if access checking fails
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoAccessException {
+        public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             return makeAccessor(refc, name, type, true, false);
         }
 
         /**
-         * Produce a method handle giving write access to a static field.
+         * Produces a method handle giving write access to a static field.
          * The type of the method handle will have a void return type.
          * The method handle will take a single
          * argument, of the field's value type, the value to be stored.
          * Access checking is performed immediately on behalf of the lookup class.
+         * @param refc the class or interface from which the method is accessed
          * @param name the field's name
          * @param type the field's type
          * @return a method handle which can store values into the field
-         * @exception NoAccessException if access checking fails
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoAccessException {
+        public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             return makeAccessor(refc, name, type, true, true);
         }
 
         /**
-         * Produce an early-bound method handle for a non-static method.
+         * Produces an early-bound method handle for a non-static method.
          * The receiver must have a supertype {@code defc} in which a method
          * of the given name and type is accessible to the lookup class.
          * The method and all its argument types must be accessible to the lookup class.
@@ -547,28 +805,47 @@
          * so that every call to the method handle will invoke the
          * requested method on the given receiver.
          * <p>
-         * This is equivalent to the following expression:
-         * <code>
-         * {@link #insertArguments insertArguments}({@link #findVirtual findVirtual}(defc, name, type), receiver)
-         * </code>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set
+         * <em>and</em> the trailing array argument is not the only argument.
+         * (If the trailing array argument is the only argument,
+         * the given receiver value will be bound to it.)
+         * <p>
+         * This is equivalent to the following code:
+         * <blockquote><pre>
+MethodHandle mh0 = {@link #findVirtual findVirtual}(defc, name, type);
+MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
+MethodType mt1 = mh1.type();
+if (mh0.isVarargsCollector() && mt1.parameterCount() > 0) {
+  mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
+return mh1;
+         * </pre></blockquote>
          * where {@code defc} is either {@code receiver.getClass()} or a super
          * type of that class, in which the requested method is accessible
          * to the lookup class.
+         * (Note that {@code bindTo} does not preserve variable arity.)
          * @param receiver the object from which the method is accessed
          * @param name the name of the method
          * @param type the type of the method, with the receiver argument omitted
          * @return the desired method handle
-         * @exception NoAccessException if the method does not exist or access checking fails
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle bind(Object receiver, String name, MethodType type) throws NoAccessException {
+        public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             Class<? extends Object> refc = receiver.getClass(); // may get NPE
             MemberName method = resolveOrFail(refc, name, type, false);
             checkMethod(refc, method, false);
             MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
             MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, dmh, receiver);
             if (bmh == null)
-                throw newNoAccessException(method, lookupClass());
-            return bmh;
+                throw newNoAccessException(method, this);
+            if (dmh.type().parameterCount() == 0)
+                return dmh;  // bound the trailing parameter; no varargs possible
+            return fixVarargs(bmh, dmh);
         }
 
         /**
@@ -581,11 +858,16 @@
          * If the method's {@code accessible} flag is not set,
          * access checking is performed immediately on behalf of the lookup class.
          * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
          * @param m the reflected method
          * @return a method handle which can invoke the reflected method
-         * @exception NoAccessException if access checking fails
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if the argument is null
          */
-        public MethodHandle unreflect(Method m) throws NoAccessException {
+        public MethodHandle unreflect(Method m) throws IllegalAccessException {
             MemberName method = new MemberName(m);
             assert(method.isMethod());
             if (!m.isAccessible())  checkMethod(method.getDeclaringClass(), method, method.isStatic());
@@ -595,7 +877,7 @@
         }
 
         /**
-         * Produce a method handle for a reflected method.
+         * Produces a method handle for a reflected method.
          * It will bypass checks for overriding methods on the receiver,
          * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
          * The type of the method handle will be that of the method,
@@ -603,12 +885,17 @@
          * If the method's {@code accessible} flag is not set,
          * access checking is performed immediately on behalf of the lookup class,
          * as if {@code invokespecial} instruction were being linked.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
          * @param m the reflected method
          * @param specialCaller the class nominally calling the method
          * @return a method handle which can invoke the reflected method
-         * @exception NoAccessException if access checking fails
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if any argument is null
          */
-        public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws NoAccessException {
+        public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
             checkSpecialCaller(specialCaller);
             MemberName method = new MemberName(m);
             assert(method.isMethod());
@@ -619,7 +906,7 @@
         }
 
         /**
-         * Produce a method handle for a reflected constructor.
+         * Produces a method handle for a reflected constructor.
          * The type of the method handle will be that of the constructor,
          * with the return type changed to the declaring class.
          * The method handle will perform a {@code newInstance} operation,
@@ -628,20 +915,26 @@
          * <p>
          * If the constructor's {@code accessible} flag is not set,
          * access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
          * @param c the reflected constructor
          * @return a method handle which can invoke the reflected constructor
-         * @exception NoAccessException if access checking fails
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if the argument is null
          */
-        public MethodHandle unreflectConstructor(Constructor c) throws NoAccessException {
+        public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
             MemberName ctor = new MemberName(c);
             assert(ctor.isConstructor());
             if (!c.isAccessible())  checkAccess(c.getDeclaringClass(), ctor);
             MethodHandle rawCtor = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull());
-            return MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawCtor);
+            MethodHandle allocator = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawCtor);
+            return fixVarargs(allocator, rawCtor);
         }
 
         /**
-         * Produce a method handle giving read access to a reflected field.
+         * Produces a method handle giving read access to a reflected field.
          * The type of the method handle will have a return type of the field's
          * value type.
          * If the field is static, the method handle will take no arguments.
@@ -651,14 +944,15 @@
          * access checking is performed immediately on behalf of the lookup class.
          * @param f the reflected field
          * @return a method handle which can load values from the reflected field
-         * @exception NoAccessException if access checking fails
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if the argument is null
          */
-        public MethodHandle unreflectGetter(Field f) throws NoAccessException {
+        public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
             return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false);
         }
 
         /**
-         * Produce a method handle giving write access to a reflected field.
+         * Produces a method handle giving write access to a reflected field.
          * The type of the method handle will have a void return type.
          * If the field is static, the method handle will take a single
          * argument, of the field's value type, the value to be stored.
@@ -668,40 +962,47 @@
          * access checking is performed immediately on behalf of the lookup class.
          * @param f the reflected field
          * @return a method handle which can store values into the reflected field
-         * @exception NoAccessException if access checking fails
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if the argument is null
          */
-        public MethodHandle unreflectSetter(Field f) throws NoAccessException {
+        public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
             return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true);
         }
 
         /// Helper methods, all package-private.
 
-        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoAccessException {
+        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
+            name.getClass(); type.getClass();  // NPE
             int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
+            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
+                                            NoSuchFieldException.class);
         }
 
-        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoAccessException {
+        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
+            name.getClass(); type.getClass();  // NPE
             int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
+            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
+                                            NoSuchMethodException.class);
         }
 
         MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
-                                 boolean searchSupers, Class<?> specialCaller) throws NoAccessException {
+                                 boolean searchSupers, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
+            name.getClass(); type.getClass();  // NPE
             int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller);
+            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
+                                            NoSuchMethodException.class);
         }
 
-        void checkSymbolicClass(Class<?> refc) throws NoAccessException {
+        void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
             Class<?> caller = lookupClassOrNull();
             if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
-                throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), caller);
+                throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), this);
         }
 
-        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws NoAccessException {
+        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
             String message;
             if (m.isConstructor())
                 message = "expected a method, not a constructor";
@@ -711,10 +1012,10 @@
                 message = wantStatic ? "expected a static method" : "expected a non-static method";
             else
                 { checkAccess(refc, m); return; }
-            throw newNoAccessException(message, m, lookupClass());
+            throw newNoAccessException(message, m, this);
         }
 
-        void checkAccess(Class<?> refc, MemberName m) throws NoAccessException {
+        void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
             int allowedModes = this.allowedModes;
             if (allowedModes == TRUSTED)  return;
             int mods = m.getModifiers();
@@ -729,22 +1030,25 @@
                 && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
                 // Protected members can also be checked as if they were package-private.
                 return;
-            throw newNoAccessException(accessFailedMessage(refc, m), m, lookupClass());
+            throw newNoAccessException(accessFailedMessage(refc, m), m, this);
         }
 
         String accessFailedMessage(Class<?> refc, MemberName m) {
             Class<?> defc = m.getDeclaringClass();
             int mods = m.getModifiers();
-            if (!VerifyAccess.isClassAccessible(defc, lookupClass()))
+            // check the class first:
+            boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
+                               (defc == refc ||
+                                Modifier.isPublic(refc.getModifiers())));
+            if (!classOK && (allowedModes & PACKAGE) != 0) {
+                classOK = (VerifyAccess.isClassAccessible(defc, lookupClass()) &&
+                           (defc == refc ||
+                            VerifyAccess.isClassAccessible(refc, lookupClass())));
+            }
+            if (!classOK)
                 return "class is not public";
-            if (refc != defc && !VerifyAccess.isClassAccessible(refc, lookupClass()))
-                return "symbolic reference "+refc.getName()+" is not public";
             if (Modifier.isPublic(mods))
                 return "access to public member failed";  // (how?)
-            else if (allowedModes == PUBLIC)
-                return "member is not public";
-            else if (allowedModes == 0)
-                return "attempted member access through a non-public class";
             if (Modifier.isPrivate(mods))
                 return "member is private";
             if (Modifier.isProtected(mods))
@@ -754,17 +1058,17 @@
 
         private static final boolean ALLOW_NESTMATE_ACCESS = false;
 
-        void checkSpecialCaller(Class<?> specialCaller) throws NoAccessException {
+        void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
             if (allowedModes == TRUSTED)  return;
             if ((allowedModes & PRIVATE) == 0
                 || (specialCaller != lookupClass()
                     && !(ALLOW_NESTMATE_ACCESS &&
                          VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
                 throw newNoAccessException("no private access for invokespecial",
-                                           new MemberName(specialCaller), lookupClass());
+                                           new MemberName(specialCaller), this);
         }
 
-        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws NoAccessException {
+        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
             // The accessing class only has the right to use a protected member
             // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
             if (!method.isProtected() || method.isStatic()
@@ -776,7 +1080,7 @@
             else
                 return restrictReceiver(method, mh, lookupClass());
         }
-        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws NoAccessException {
+        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
             assert(!method.isStatic());
             Class<?> defc = method.getDeclaringClass();  // receiver type of mh is too wide
             if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
@@ -785,22 +1089,23 @@
             MethodType rawType = mh.type();
             if (rawType.parameterType(0) == caller)  return mh;
             MethodType narrowType = rawType.changeParameterType(0, caller);
-            return MethodHandleImpl.convertArguments(IMPL_TOKEN, mh, narrowType, rawType, null);
+            MethodHandle narrowMH = MethodHandleImpl.convertArguments(IMPL_TOKEN, mh, narrowType, rawType, null);
+            return fixVarargs(narrowMH, mh);
         }
 
         MethodHandle makeAccessor(Class<?> refc, String name, Class<?> type,
-                                  boolean isStatic, boolean isSetter) throws NoAccessException {
+                                  boolean isStatic, boolean isSetter) throws NoSuchFieldException, IllegalAccessException {
             MemberName field = resolveOrFail(refc, name, type, isStatic);
             if (isStatic != field.isStatic())
                 throw newNoAccessException(isStatic
                                            ? "expected a static field"
                                            : "expected a non-static field",
-                                           field, lookupClass());
+                                           field, this);
             return makeAccessor(refc, field, false, isSetter);
         }
 
         MethodHandle makeAccessor(Class<?> refc, MemberName field,
-                                  boolean trusted, boolean isSetter) throws NoAccessException {
+                                  boolean trusted, boolean isSetter) throws IllegalAccessException {
             assert(field.isField());
             if (trusted)
                 return MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull());
@@ -811,12 +1116,13 @@
     }
 
     /**
-     * Produce a method handle giving read access to elements of an array.
+     * Produces a method handle giving read access to elements of an array.
      * The type of the method handle will have a return type of the array's
      * element type.  Its first argument will be the array type,
      * and the second will be {@code int}.
      * @param arrayClass an array type
      * @return a method handle which can load values from the given array type
+     * @throws NullPointerException if the argument is null
      * @throws  IllegalArgumentException if arrayClass is not an array type
      */
     public static
@@ -825,11 +1131,12 @@
     }
 
     /**
-     * Produce a method handle giving write access to elements of an array.
+     * Produces a method handle giving write access to elements of an array.
      * The type of the method handle will have a void return type.
      * Its last argument will be the array's element type.
      * The first and second arguments will be the array type and int.
      * @return a method handle which can store values into the array type
+     * @throws NullPointerException if the argument is null
      * @throws IllegalArgumentException if arrayClass is not an array type
      */
     public static
@@ -840,47 +1147,7 @@
     /// method handle invocation (reflective style)
 
     /**
-     * Produce a method handle which will invoke any method handle of the
-     * given type on a standard set of {@code Object} type arguments.
-     * The resulting invoker will be a method handle with the following
-     * arguments:
-     * <ul>
-     * <li>a single {@code MethodHandle} target
-     * <li>zero or more {@code Object} values (one for each argument in {@code type})
-     * </ul>
-     * <p>
-     * The invoker will behave like a call to {@link MethodHandle.invokeGeneric} with
-     * the indicated {@code type}.
-     * That is, if the target is exactly of the given {@code type}, it will behave
-     * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle.asType}
-     * is used to convert the target to the required {@code type}.
-     * <p>
-     * The type of the returned invoker will not be the given {@code type}, but rather
-     * will have all parameter and return types replaced by {@code Object}.
-     * <p>
-     * Before invoking its target, the invoker will apply reference casts as
-     * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments}.
-     * The return value of the invoker will be an {@code Object} reference,
-     * boxing a primitive value if the original type returns a primitive,
-     * and always null if the original type returns void.
-     * <p>
-     * This method is equivalent to the following code (though it may be more efficient):
-     * <p><blockquote><pre>
-     * MethodHandle invoker = lookup().findVirtual(MethodHandle.class, "invokeGeneric", type);
-     * MethodType genericType = type.generic();
-     * genericType = genericType.insertParameterType(0, MethodHandle.class);
-     * return invoker.asType(genericType);
-     * </pre></blockquote>
-     * @param type the type of target methods which the invoker will apply to
-     * @return a method handle suitable for invoking any method handle of the given type
-     */
-    static public
-    MethodHandle genericInvoker(MethodType type) {
-        return invokers(type).genericInvoker();
-    }
-
-    /**
-     * Produce a method handle which will invoke any method handle of the
+     * Produces a method handle which will invoke any method handle of the
      * given {@code type} on a standard set of {@code Object} type arguments
      * and a single trailing {@code Object[]} array.
      * The resulting invoker will be a method handle with the following
@@ -891,10 +1158,10 @@
      * <li>an {@code Object[]} array containing more arguments
      * </ul>
      * <p>
-     * The invoker will behave like a call to {@link MethodHandle.invokeGeneric} with
+     * The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with
      * the indicated {@code type}.
      * That is, if the target is exactly of the given {@code type}, it will behave
-     * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle.asType}
+     * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
      * is used to convert the target to the required {@code type}.
      * <p>
      * The type of the returned invoker will not be the given {@code type}, but rather
@@ -909,34 +1176,56 @@
      * <p>
      * This method is equivalent to the following code (though it may be more efficient):
      * <p><blockquote><pre>
-     * MethodHandle invoker = lookup().findVirtual(MethodHandle.class, "invokeGeneric", type);
-     * MethodType vaType = MethodType.genericMethodType(objectArgCount, true);
-     * vaType = vaType.insertParameterType(0, MethodHandle.class);
-     * int spreadArgCount = type.parameterCount - objectArgCount;
-     * invoker = invoker.asSpreader(Object.class, spreadArgCount);
-     * return invoker.asType(vaType);
+MethodHandle invoker = MethodHandles.genericInvoker(type);
+int spreadArgCount = type.parameterCount - objectArgCount;
+invoker = invoker.asSpreader(Object[].class, spreadArgCount);
+return invoker;
      * </pre></blockquote>
+     * <p>
+     * This method throws no reflective or security exceptions.
      * @param type the desired target type
      * @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
      * @return a method handle suitable for invoking any method handle of the given type
      */
     static public
-    MethodHandle varargsInvoker(MethodType type, int objectArgCount) {
+    MethodHandle spreadInvoker(MethodType type, int objectArgCount) {
         if (objectArgCount < 0 || objectArgCount > type.parameterCount())
             throw new IllegalArgumentException("bad argument count "+objectArgCount);
-        return invokers(type).varargsInvoker(objectArgCount);
+        return invokers(type).spreadInvoker(objectArgCount);
     }
 
     /**
-     * Produce a method handle which will take a invoke any method handle of the
-     * given type.  The resulting invoker will have a type which is
+     * Produces a special <em>invoker method handle</em> which can be used to
+     * invoke any method handle of the given type, as if by {@code invokeExact}.
+     * The resulting invoker will have a type which is
      * exactly equal to the desired type, except that it will accept
      * an additional leading argument of type {@code MethodHandle}.
      * <p>
      * This method is equivalent to the following code (though it may be more efficient):
      * <p><blockquote><pre>
-     * lookup().findVirtual(MethodHandle.class, "invokeExact", type);
+publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
      * </pre></blockquote>
+     *
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * Invoker method handles can be useful when working with variable method handles
+     * of unknown types.
+     * For example, to emulate an {@code invokeExact} call to a variable method
+     * handle {@code M}, extract its type {@code T},
+     * look up the invoker method {@code X} for {@code T},
+     * and call the invoker method, as {@code X.invokeGeneric(T, A...)}.
+     * (It would not work to call {@code X.invokeExact}, since the type {@code T}
+     * is unknown.)
+     * If spreading, collecting, or other argument transformations are required,
+     * they can be applied once to the invoker {@code X} and reused on many {@code M}
+     * method handle values, as long as they are compatible with the type of {@code X}.
+     * <p>
+     * <em>(Note:  The invoker method is not available via the Core Reflection API.
+     * An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke}
+     * on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an
+     * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
+     * <p>
+     * This method throws no reflective or security exceptions.
      * @param type the desired target type
      * @return a method handle suitable for invoking any method handle of the given type
      */
@@ -945,12 +1234,38 @@
         return invokers(type).exactInvoker();
     }
 
+    /**
+     * Produces a special <em>invoker method handle</em> which can be used to
+     * invoke any method handle of the given type, as if by {@code invokeGeneric}.
+     * The resulting invoker will have a type which is
+     * exactly equal to the desired type, except that it will accept
+     * an additional leading argument of type {@code MethodHandle}.
+     * <p>
+     * Before invoking its target, the invoker will apply reference casts as
+     * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}.
+     * The return value of the invoker will be an {@code Object} reference,
+     * boxing a primitive value if the original type returns a primitive,
+     * and always null if the original type returns void.
+     * <p>
+     * This method is equivalent to the following code (though it may be more efficient):
+     * <p><blockquote><pre>
+publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
+     * </pre></blockquote>
+     * <p>
+     * This method throws no reflective or security exceptions.
+     * @param type the desired target type
+     * @return a method handle suitable for invoking any method handle convertible to the given type
+     */
+    static public
+    MethodHandle genericInvoker(MethodType type) {
+        return invokers(type).genericInvoker();
+    }
+
     static Invokers invokers(MethodType type) {
         return MethodTypeImpl.invokers(IMPL_TOKEN, type);
     }
 
     /**
-     * <em>WORK IN PROGRESS:</em>
      * Perform value checking, exactly as if for an adapted method handle.
      * It is assumed that the given value is either null, of type T0,
      * or (if T0 is primitive) of the wrapper type corresponding to T0.
@@ -1021,7 +1336,7 @@
     /// method handle modification (creation from other method handles)
 
     /**
-     * Produce a method handle which adapts the type of the
+     * Produces a method handle which adapts the type of the
      * given method handle to a new type by pairwise argument conversion.
      * The original type and new type must have the same number of arguments.
      * The resulting method handle is guaranteed to report a type
@@ -1060,6 +1375,7 @@
      * @return a method handle which delegates to {@code target} after performing
      *           any necessary argument conversions, and arranges for any
      *           necessary return value conversions
+     * @throws NullPointerException if either argument is null
      * @throws WrongMethodTypeException if the conversion cannot be made
      * @see MethodHandle#asType
      * @see MethodHandles#explicitCastArguments
@@ -1081,7 +1397,7 @@
     }
 
     /**
-     * Produce a method handle which adapts the type of the
+     * Produces a method handle which adapts the type of the
      * given method handle to a new type by pairwise argument conversion.
      * The original type and new type must have the same number of arguments.
      * The resulting method handle is guaranteed to report a type
@@ -1113,6 +1429,7 @@
      * @return a method handle which delegates to {@code target} after performing
      *           any necessary argument conversions, and arranges for any
      *           necessary return value conversions
+     * @throws NullPointerException if either argument is null
      * @throws WrongMethodTypeException if the conversion cannot be made
      * @see MethodHandle#asType
      * @see MethodHandles#convertArguments
@@ -1160,7 +1477,7 @@
     */
 
     /**
-     * Produce a method handle which adapts the calling sequence of the
+     * Produces a method handle which adapts the calling sequence of the
      * given method handle to a new type, by reordering the arguments.
      * The resulting method handle is guaranteed to report a type
      * which is equal to the desired new type.
@@ -1208,6 +1525,7 @@
      * @param reorder a string which controls the reordering
      * @return a method handle which delegates to {@code target} after it
      *           drops unused arguments and moves and/or duplicates the other arguments
+     * @throws NullPointerException if any argument is null
      */
     public static
     MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
@@ -1233,11 +1551,10 @@
     }
 
     /**
-     * <em>METHOD WILL BE REMOVED FOR PFD:</em>
      * Equivalent to the following code:
      * <p><blockquote><pre>
      * int spreadPos = newType.parameterCount() - 1;
-     * Class<?> spreadType = newType.parameterType(spreadPos);
+     * Class&lt;?&gt; spreadType = newType.parameterType(spreadPos);
      * int spreadCount = target.type().parameterCount() - spreadPos;
      * MethodHandle adapter = target.asSpreader(spreadType, spreadCount);
      * adapter = adapter.asType(newType);
@@ -1247,9 +1564,8 @@
      * @param newType the expected type of the new method handle
      * @return a method handle which spreads its final argument,
      *         before calling the original method handle
-     * @deprecated Use {@link MethodHandle#asSpreader}
      */
-    public static
+    /*non-public*/ static
     MethodHandle spreadArguments(MethodHandle target, MethodType newType) {
         MethodType oldType = target.type();
         int inargs  = newType.parameterCount();
@@ -1267,11 +1583,10 @@
     }
 
     /**
-     * <em>METHOD WILL BE REMOVED FOR PFD:</em>
      * Equivalent to the following code:
      * <p><blockquote><pre>
      * int collectPos = target.type().parameterCount() - 1;
-     * Class<?> collectType = target.type().parameterType(collectPos);
+     * Class&lt;?&gt; collectType = target.type().parameterType(collectPos);
      * if (!collectType.isArray())  collectType = Object[].class;
      * int collectCount = newType.parameterCount() - collectPos;
      * MethodHandle adapter = target.asCollector(collectType, collectCount);
@@ -1282,9 +1597,8 @@
      * @param newType the expected type of the new method handle
      * @return a method handle which collects some trailing argument
      *         into an array, before calling the original method handle
-     * @deprecated Use {@link MethodHandle#asCollector} instead.
      */
-    public static
+    /*non-public*/ static
     MethodHandle collectArguments(MethodHandle target, MethodType newType) {
         MethodType oldType = target.type();
         int inargs  = newType.parameterCount();
@@ -1301,7 +1615,7 @@
     }
 
     /**
-     * Produce a method handle of the requested return type which returns the given
+     * Produces a method handle of the requested return type which returns the given
      * constant value every time it is invoked.
      * <p>
      * Before the method handle is returned, the passed-in value is converted to the requested type.
@@ -1312,12 +1626,15 @@
      * @param type the return type of the desired method handle
      * @param value the value to return
      * @return a method handle of the given return type and no arguments, which always returns the given value
-     * @throws WrongMethodTypeException if the value cannot be converted to the required return type
+     * @throws NullPointerException if the {@code type} argument is null
+     * @throws ClassCastException if the value cannot be converted to the required return type
+     * @throws IllegalArgumentException if the given type is {@code void.class}
      */
     public static
     MethodHandle constant(Class<?> type, Object value) {
         if (type.isPrimitive()) {
-            if (type == void.class)  return identity(type);
+            if (type == void.class)
+                throw newIllegalArgumentException("void type");
             Wrapper w = Wrapper.forPrimitiveType(type);
             return identity(type).bindTo(w.convert(value, type));
         } else {
@@ -1326,64 +1643,22 @@
     }
 
     /**
-     * Produce a method handle of the requested type which returns the given
-     * constant value every time it is invoked.
-     * <p>
-     * Before the method handle is returned, the passed-in value is converted to the requested return type,
-     * as if by {@link #explicitCastArguments #explicitCastArguments}.
-     * That is, if the return type is primitive, the value is unboxed,
-     * and the primitive value is widened and/or narrowed.
-     * Otherwise, reference conversions are attempted.
-     * @param type the type of the desired method handle
-     * @param value the value to return
-     * @return a method handle of the given return type and no arguments, which always returns the given value
-     * @throws WrongMethodTypeException if the value cannot be converted to the required return type
+     * Produces a method handle which returns its sole argument when invoked.
+     * <p>The identity function for {@code void} takes no arguments and returns no values.
+     * @param type the type of the sole parameter and return value of the desired method handle
+     * @return a unary method handle which accepts and returns the given type
+     * @throws NullPointerException if the argument is null
+     * @throws IllegalArgumentException if the given type is {@code void.class}
      */
     public static
-    MethodHandle constant(MethodType type, Object value) {
-        MethodHandle target = constant(type.returnType(), value);
-        int len = type.parameterCount();
-        if (len == 0)
-            return target.asType(type);
-        target = target.asType(type.dropParameterTypes(0, len));
-        return dropArguments(target, 0, type.parameterList().subList(0, len));
-    }
-
-     /**
-      * Produce a method handle which returns its sole argument when invoked.
-      * <p>The identity function for {@code void} takes no arguments and returns no values.
-      * @param type the type of the sole parameter and return value of the desired method handle
-      * @return a unary method handle which accepts and returns the given type
-      */
-    public static
     MethodHandle identity(Class<?> type) {
+        if (type == void.class)
+            throw newIllegalArgumentException("void type");
         return ValueConversions.identity(type);
     }
 
-     /**
-      * Produce a method handle of the requested type which returns its argument when invoked.
-      * If the return type differs from the first argument type, the argument will be
-      * converted as if by {@link #explicitCastArguments explicitCastArguments}.
-      * If there are additional arguments beyond the first, they are discarded.
-      * <p>The identity function for {@code void} discards all its arguments.
-      * @param type the type of the desired method handle
-      * @return a method handle of the given type, which always returns its first argument
-      * @throws WrongMethodTypeException if the first argument cannot be converted to the required return type
-      */
-    public static
-    MethodHandle identity(MethodType type) {
-        MethodHandle target = identity(type.returnType());
-        int len = type.parameterCount();
-        if (len == 1)
-            return explicitCastArguments(target, type);
-        if (len == 0)
-            throw new IllegalArgumentException("not enough arguments");
-        target = explicitCastArguments(target, type.dropParameterTypes(1, len));
-        return dropArguments(target, 1, type.parameterList().subList(1, len));
-    }
-
     /**
-     * Produce a method handle which calls the original method handle {@code target},
+     * Produces a method handle which calls the original method handle {@code target},
      * after inserting the given argument(s) at the given position.
      * The formal parameters to {@code target} which will be supplied by those
      * arguments are called <em>bound parameters</em>, because the new method
@@ -1404,6 +1679,7 @@
      * @param values the series of arguments to insert
      * @return a method handle which inserts an additional argument,
      *         before calling the original method handle
+     * @throws NullPointerException if the {@code target} argument or the {@code values} array is null
      * @see MethodHandle#bindTo
      */
     public static
@@ -1438,7 +1714,7 @@
     }
 
     /**
-     * Produce a method handle which calls the original method handle,
+     * Produces a method handle which calls the original method handle,
      * after dropping the given argument(s) at the given position.
      * The type of the new method handle will insert the given argument
      * type(s), at that position, into the original handle's type.
@@ -1470,6 +1746,9 @@
      * @param pos position of first argument to drop (zero for the leftmost)
      * @return a method handle which drops arguments of the given types,
      *         before calling the original method handle
+     * @throws NullPointerException if the {@code target} argument is null,
+     *                              or if the {@code valueTypes} list or any of its elements is null
+     * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
      */
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
@@ -1487,7 +1766,7 @@
     }
 
     /**
-     * Produce a method handle which calls the original method handle,
+     * Produces a method handle which calls the original method handle,
      * after dropping the given argument(s) at the given position.
      * The type of the new method handle will insert the given argument
      * type(s), at that position, into the original handle's type.
@@ -1500,6 +1779,9 @@
      * @param pos position of first argument to drop (zero for the leftmost)
      * @return a method handle which drops arguments of the given types,
      *         before calling the original method handle
+     * @throws NullPointerException if the {@code target} argument is null,
+     *                              or if the {@code valueTypes} array or any of its elements is null
+     * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
      */
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
@@ -1514,7 +1796,8 @@
      * <p>
      * The pre-processing is performed by one or more method handles,
      * specified in the elements of the {@code filters} array.
-     * (If there are no elements in the array, the original target is returned.)
+     * Null arguments in the array are ignored, and the corresponding arguments left unchanged.
+     * (If there are no non-null elements in the array, the original target is returned.)
      * Each filter is applied to the corresponding argument of the adapter.
      * <p>
      * If a filter {@code F} applies to the {@code N}th argument of
@@ -1544,12 +1827,16 @@
 MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
 assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
      * </pre></blockquote>
+     *
      * @param target the method handle to invoke after arguments are filtered
      * @param pos the position of the first argument to filter
      * @param filters method handles to call initially on filtered arguments
      * @return method handle which incorporates the specified argument filtering logic
-     * @throws IllegalArgumentException if an element of {@code filters} is null or
-     *          does not match a corresponding argument type of {@code target} as described above
+     * @throws NullPointerException if the {@code target} argument is null
+     *                              or if the {@code filters} array is null
+     * @throws IllegalArgumentException if a non-null element of {@code filters}
+     *          does not match a corresponding argument type of {@code target} as described above,
+     *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
      */
     public static
     MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
@@ -1557,17 +1844,18 @@
         MethodHandle adapter = target;
         MethodType adapterType = targetType;
         int maxPos = targetType.parameterCount();
-        int curPos = pos;
+        if (pos + filters.length > maxPos)
+            throw newIllegalArgumentException("too many filters");
+        int curPos = pos-1;  // pre-incremented
         for (MethodHandle filter : filters) {
-            if (curPos >= maxPos)
-                throw newIllegalArgumentException("too many filters");
+            curPos += 1;
+            if (filter == null)  continue;  // ignore null elements of filters
             MethodType filterType = filter.type();
             if (filterType.parameterCount() != 1
                 || filterType.returnType() != targetType.parameterType(curPos))
                 throw newIllegalArgumentException("target and filter types do not match");
             adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
             adapter = MethodHandleImpl.filterArgument(IMPL_TOKEN, adapter, curPos, filter);
-            curPos += 1;
         }
         MethodType midType = adapter.type();
         if (midType != adapterType)
@@ -1602,7 +1890,8 @@
      * @param target the method handle to invoke before filtering the return value
      * @param filter method handle to call on the return value
      * @return method handle which incorporates the specified return value filtering logic
-     * @throws IllegalArgumentException if {@code filter} is null or
+     * @throws NullPointerException if either argument is null
+     * @throws IllegalArgumentException if {@code filter}
      *          does not match the return type of {@code target} as described above
      */
     public static
@@ -1612,9 +1901,11 @@
         if (filterType.parameterCount() != 1
             || filterType.parameterType(0) != targetType.returnType())
             throw newIllegalArgumentException("target and filter types do not match");
+        // result = fold( lambda(retval, arg...) { filter(retval) },
+        //                lambda(        arg...) { target(arg...) } )
         // FIXME: Too many nodes here.
-        MethodHandle returner = dropArguments(filter, 0, targetType.parameterList());
-        return foldArguments(returner, exactInvoker(target.type()).bindTo(target));
+        MethodHandle returner = dropArguments(filter, 1, targetType.parameterList());
+        return foldArguments(returner, target);
     }
 
     /**
@@ -1637,7 +1928,7 @@
      * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
      * that either the {@code combiner} or {@code target} does not wish to receive.
      * If some of the incoming arguments are destined only for the combiner,
-     * consider using {@link MethodHandle#asCollector} instead, since those
+     * consider using {@link MethodHandle#asCollector asCollector} instead, since those
      * arguments will not need to be live on the stack on entry to the
      * target.)
      * <p>
@@ -1656,6 +1947,7 @@
      * @param target the method handle to invoke after arguments are combined
      * @param combiner method handle to call initially on the incoming arguments
      * @return method handle which incorporates the specified argument folding logic
+     * @throws NullPointerException if either argument is null
      * @throws IllegalArgumentException if the first argument type of
      *          {@code target} is not the same as {@code combiner}'s return type,
      *          or if the following argument types of {@code target}
@@ -1704,6 +1996,7 @@
      * @param target method handle to call if test passes
      * @param fallback method handle to call if test fails
      * @return method handle which incorporates the specified if/then/else logic
+     * @throws NullPointerException if any argument is null
      * @throws IllegalArgumentException if {@code test} does not return boolean,
      *          or if all three method types do not match (with the return
      *          type of {@code test} changed to match that of {@code target}).
@@ -1772,6 +2065,7 @@
      * @param exType the type of exception which the handler will catch
      * @param handler method handle to call if a matching exception is thrown
      * @return method handle which incorporates the specified try/catch logic
+     * @throws NullPointerException if any argument is null
      * @throws IllegalArgumentException if {@code handler} does not accept
      *          the given exception type, or if the method handle types do
      *          not match in their return types and their
@@ -1802,12 +2096,14 @@
     }
 
     /**
-     * Produce a method handle which will throw exceptions of the given {@code exType}.
+     * Produces a method handle which will throw exceptions of the given {@code exType}.
      * The method handle will accept a single argument of {@code exType},
      * and immediately throw it as an exception.
      * The method type will nominally specify a return of {@code returnType}.
      * The return type may be anything convenient:  It doesn't matter to the
      * method handle's behavior, since it will never return normally.
+     * @return method handle which can throw the given exceptions
+     * @throws NullPointerException if either argument is null
      */
     public static
     MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
@@ -1815,18 +2111,43 @@
     }
 
     /**
-     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
-     * Produce a wrapper instance of the given "SAM" interface which redirects
+     * Produces an instance of the given "SAM" interface which redirects
      * its calls to the given method handle.
+     * <p>
      * A SAM interface is an interface which declares a single abstract method.
-     * The type must be public.  (No additional access checks are performed.)
+     * When determining the unique abstract method of a SAM interface,
+     * the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode})
+     * are disregarded.  For example, {@link java.util.Comparator} is a SAM interface,
+     * 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>
+     * The type must be public.  No additional access checks are performed.
      * <p>
      * The resulting instance of the required SAM type will respond to
      * invocation of the SAM type's single abstract method by calling
      * the given {@code target} on the incoming arguments,
      * and returning or throwing whatever the {@code target}
      * returns or throws.  The invocation will be as if by
-     * {@code target.invokeExact}.
+     * {@code target.invokeGeneric}.
+     * The target's type will be checked before the SAM
+     * instance is created, as if by a call to {@code asType},
+     * which may result in a {@code WrongMethodTypeException}.
+     * <p>
+     * The wrapper instance will implement the requested SAM interface
+     * and its super-types, but no other SAM types.
+     * This means that the SAM instance will not unexpectedly
+     * pass an {@code instanceof} test for any unrequested type.
+     * <p style="font-size:smaller;">
+     * <em>Implementation Note:</em>
+     * Therefore, each SAM instance must implement a unique SAM type.
+     * Implementations may not bundle together
+     * multiple SAM types onto single implementation classes
+     * in the style of {@link java.awt.AWTEventMulticaster}.
      * <p>
      * The method handle may throw an <em>undeclared exception</em>,
      * which means any checked exception (or other checked throwable)
@@ -1835,54 +2156,46 @@
      * {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException}
      * and thrown in that wrapped form.
      * <p>
-     * The wrapper instance is guaranteed to be of a non-public
-     * implementation class C in a package containing no classes
-     * or methods except system-defined classes and methods.
-     * The implementation class C will have no public supertypes
-     * or public methods beyond the following:
-     * <ul>
-     * <li>the SAM type itself and any methods in the SAM type
-     * <li>the supertypes of the SAM type (if any) and their methods
-     * <li>{@link Object} and its methods
-     * <li>{@link java.dyn.AsInstanceObject AsInstanceObject} and its methods</li>
-     * </ul>
+     * Like {@link java.lang.Integer#valueOf Integer.valueOf},
+     * {@code asInstance} is a factory method whose results are defined
+     * by their behavior.
+     * It is not guaranteed to return a new instance for every call.
      * <p>
-     * (Note: When determining the unique abstract method of a SAM interface,
-     * the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode})
-     * are disregarded.  For example, {@link java.util.Comparator} is a SAM interface,
-     * even though it re-declares the {@code Object.equals} method.)
-     * <p>
-     * No stable mapping is promised between the SAM type and
-     * the implementation class C.  Over time, several implementation
-     * classes might be used for the same SAM type.
-     * <p>
-     * This method is not guaranteed to return a distinct
-     * wrapper object for each separate call.  If the implementation is able
-     * to prove that a wrapper of the required SAM type
-     * has already been created for a given
-     * method handle, or for another method handle with the
-     * same behavior, the implementation may return that wrapper in place of
-     * a new wrapper.
-     * <p>
-     * This method is designed to apply to common use cases
-     * where a single method handle must interoperate with
-     * a type (class or interface) that implements a function-like
-     * API.  Additional variations, such as SAM classes with
-     * private constructors, or interfaces with multiple but related
-     * entry points, must be covered by hand-written or automatically
-     * generated adapter classes.  In those cases, consider implementing
-     * {@link java.dyn.MethodHandles.AsInstanceObject AsInstanceObject}
-     * in the adapters, so that generic code can extract the underlying
-     * method handle without knowing where the SAM adapter came from.
+     * Future versions of this API may accept additional types,
+     * such as abstract classes with single abstract methods.
+     * Future versions of this API may also equip wrapper instances
+     * with one or more additional public "marker" interfaces.
+     *
      * @param target the method handle to invoke from the wrapper
      * @param samType the desired type of the wrapper, a SAM type
      * @return a correctly-typed wrapper for the given {@code target}
-     * @throws IllegalArgumentException if the {@code target} throws
-     *         an undeclared exception
+     * @throws NullPointerException if either argument is null
+     * @throws IllegalArgumentException if the {@code samType} is not a
+     *         valid argument to this method
+     * @throws WrongMethodTypeException if the {@code target} cannot
+     *         be converted to the type required by the SAM type
      */
-    // ISSUE: Should we delegate equals/hashCode to the targets?
-    // Not useful unless there is a stable equals/hashCode behavior
-    // for MethodHandle, but there isn't.
+    // Other notes to implementors:
+    // <p>
+    // No stable mapping is promised between the SAM type and
+    // the implementation class C.  Over time, several implementation
+    // classes might be used for the same SAM type.
+    // <p>
+    // If the implementation is able
+    // to prove that a wrapper of the required SAM type
+    // has already been created for a given
+    // method handle, or for another method handle with the
+    // same behavior, the implementation may return that wrapper in place of
+    // a new wrapper.
+    // <p>
+    // This method is designed to apply to common use cases
+    // where a single method handle must interoperate with
+    // an interface that implements a function-like
+    // API.  Additional variations, such as SAM classes with
+    // private constructors, or interfaces with multiple but related
+    // entry points, must be covered by hand-written or automatically
+    // generated adapter classes.
+    //
     public static
     <T> T asInstance(final MethodHandle target, final Class<T> samType) {
         // POC implementation only; violates the above contract several ways
@@ -1890,22 +2203,23 @@
         if (sam == null)
             throw new IllegalArgumentException("not a SAM type: "+samType.getName());
         MethodType samMT = MethodType.methodType(sam.getReturnType(), sam.getParameterTypes());
-        if (!samMT.equals(target.type()))
-            throw new IllegalArgumentException("wrong method type: "+target+" should match "+sam);
+        MethodHandle checkTarget = target.asType(samMT);  // make throw WMT
+        checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
+        final MethodHandle vaTarget = checkTarget.asSpreader(Object[].class, samMT.parameterCount());
         return samType.cast(Proxy.newProxyInstance(
                 samType.getClassLoader(),
-                new Class[]{ samType, AsInstanceObject.class },
+                new Class[]{ samType, WrapperInstance.class },
                 new InvocationHandler() {
                     private Object getArg(String name) {
-                        if ((Object)name == "getAsInstanceTarget")  return target;
-                        if ((Object)name == "getAsInstanceType")    return samType;
+                        if ((Object)name == "getWrapperInstanceTarget")  return target;
+                        if ((Object)name == "getWrapperInstanceType")    return samType;
                         throw new AssertionError();
                     }
                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                        if (method.getDeclaringClass() == AsInstanceObject.class)
+                        if (method.getDeclaringClass() == WrapperInstance.class)
                             return getArg(method.getName());
                         if (method.equals(sam))
-                            return target.invokeVarargs(args);
+                            return vaTarget.invokeExact(args);
                         if (isObjectMethod(method))
                             return callObjectMethod(this, method, args);
                         throw new InternalError();
@@ -1914,21 +2228,49 @@
     }
 
     /**
-     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
-     * Interface implemented by every object which is produced by {@link #asInstance asInstance}.
-     * The methods of this interface allow a caller to recover the parameters
-     * to {@code asInstance}.
-     * This allows applications to repeatedly convert between method handles
-     * and SAM objects, without the risk of creating unbounded delegation chains.
+     * Determine if the given object was produced by a call to {@link #asInstance asInstance}.
+     * @param x any reference
+     * @return true if the reference is not null and points to an object produced by {@code asInstance}
      */
-    public interface AsInstanceObject {
-        /** Produce or recover a target method handle which is behaviorally
-         *  equivalent to the SAM method of this object.
-         */
-        public MethodHandle getAsInstanceTarget();
-        /** Recover the SAM type for which this object was created.
-         */
-        public Class<?> getAsInstanceType();
+    public static
+    boolean isWrapperInstance(Object x) {
+        return x instanceof WrapperInstance;
+    }
+
+    private static WrapperInstance asWrapperInstance(Object x) {
+        try {
+            if (x != null)
+                return (WrapperInstance) x;
+        } catch (ClassCastException ex) {
+        }
+        throw new IllegalArgumentException("not a wrapper instance");
+    }
+
+    /**
+     * Produces or recovers a target method handle which is behaviorally
+     * equivalent to the SAM method of this wrapper instance.
+     * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
+     * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
+     * @param x any reference
+     * @return a method handle implementing the SAM method
+     * @throws IllegalArgumentException if the reference x is not to a wrapper instance
+     */
+    public static
+    MethodHandle wrapperInstanceTarget(Object x) {
+        return asWrapperInstance(x).getWrapperInstanceTarget();
+    }
+
+    /**
+     * Recover the SAM type for which this wrapper instance was created.
+     * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
+     * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
+     * @param x any reference
+     * @return the SAM type for which the wrapper was created
+     * @throws IllegalArgumentException if the reference x is not to a wrapper instance
+     */
+    public static
+    Class<?> wrapperInstanceType(Object x) {
+        return asWrapperInstance(x).getWrapperInstanceType();
     }
 
     private static
@@ -1991,7 +2333,7 @@
     }
 
     /*non-public*/
-    static MethodHandle withTypeHandler(MethodHandle target, MethodHandle typeHandler) {
-        return MethodHandleImpl.withTypeHandler(IMPL_TOKEN, target, typeHandler);
+    static MethodHandle asVarargsCollector(MethodHandle target, Class<?> arrayType) {
+        return MethodHandleImpl.asVarargsCollector(IMPL_TOKEN, target, arrayType);
     }
 }
--- a/src/share/classes/java/dyn/MethodType.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/MethodType.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 import java.util.List;
 import sun.dyn.Access;
 import sun.dyn.Invokers;
+import sun.dyn.MethodHandleImpl;
 import sun.dyn.MethodTypeImpl;
 import sun.dyn.util.BytecodeDescriptor;
 import static sun.dyn.MemberName.newIllegalArgumentException;
@@ -41,8 +42,8 @@
  * and expected  by a method handle caller.  Method types must be properly
  * matched between a method handle and all its callers,
  * and the JVM's operations enforce this matching at, specifically
- * during calls to {@link MethodHandle#invokeExact}
- * and {@link MethodHandle#invokeGeneric}, and during execution
+ * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
+ * and {@link MethodHandle#invokeGeneric MethodHandle.invokeGeneric}, and during execution
  * of {@code invokedynamic} instructions.
  * <p>
  * The structure is a return type accompanied by any number of parameter types.
@@ -70,8 +71,9 @@
  * with the instructions in a class file's constant pool.
  * <p>
  * Like classes and strings, method types can also be represented directly
- * in a class file's constant pool as constants. The may be loaded by an {@code ldc}
- * instruction which refers to a suitable {@code CONSTANT_MethodType} constant pool entry.
+ * in a class file's constant pool as constants.
+ * A method type may be loaded by an {@code ldc} instruction which refers
+ * to a suitable {@code CONSTANT_MethodType} constant pool entry.
  * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
  * For more details, see the <a href="package-summary.html#mtcon">package summary</a>.
  * <p>
@@ -82,9 +84,14 @@
  * @author John Rose, JSR 292 EG
  */
 public final
-class MethodType {
+class MethodType implements java.io.Serializable {
+    private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
+
+    // The rtype and ptypes fields define the structural identity of the method type:
     private final Class<?>   rtype;
     private final Class<?>[] ptypes;
+
+    // The remaining fields are caches of various sorts:
     private MethodTypeForm form; // erased form, plus cached data about primitives
     private MethodType wrapAlt;  // alternative wrapped/unwrapped version
     private Invokers invokers;   // cache of handy higher-order adapters
@@ -117,6 +124,9 @@
         });
     }
 
+    /**
+     * Check the given parameters for validity and store them into the final fields.
+     */
     private MethodType(Class<?> rtype, Class<?>[] ptypes) {
         checkRtype(rtype);
         checkPtypes(ptypes);
@@ -124,15 +134,32 @@
         this.ptypes = ptypes;
     }
 
-    private void checkRtype(Class<?> rtype) {
+    private static void checkRtype(Class<?> rtype) {
         rtype.equals(rtype);  // null check
     }
-    private void checkPtypes(Class<?>[] ptypes) {
+    private static int checkPtype(Class<?> ptype) {
+        ptype.getClass();  //NPE
+        if (ptype == void.class)
+            throw newIllegalArgumentException("parameter type cannot be void");
+        if (ptype == double.class || ptype == long.class)  return 1;
+        return 0;
+    }
+    /** Return number of extra slots (count of long/double args). */
+    private static int checkPtypes(Class<?>[] ptypes) {
+        int slots = 0;
         for (Class<?> ptype : ptypes) {
-            ptype.equals(ptype);  // null check
-            if (ptype == void.class)
-                throw newIllegalArgumentException("parameter type cannot be void");
+            slots += checkPtype(ptype);
         }
+        checkSlotCount(ptypes.length + slots);
+        return slots;
+    }
+    private static void checkSlotCount(int count) {
+        if ((count & 0xFF) != count)
+            throw newIllegalArgumentException("bad parameter count "+count);
+    }
+    private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
+        if (num instanceof Integer)  num = "bad index: "+num;
+        return new IndexOutOfBoundsException(num.toString());
     }
 
     static final HashMap<MethodType,MethodType> internTable
@@ -140,27 +167,39 @@
 
     static final Class<?>[] NO_PTYPES = {};
 
-    /** Find or create an instance of the given method type.
+    /**
+     * Find or create an instance of the given method type.
      * @param rtype  the return type
      * @param ptypes the parameter types
-     * @return a method type with the given parts
-     * @throws NullPointerException if rtype or any ptype is null
-     * @throws IllegalArgumentException if any of the ptypes is void
+     * @return a method type with the given components
+     * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+     * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
      */
     public static
     MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
         return makeImpl(rtype, ptypes, false);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}. */
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @return a method type with the given components
+     * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+     * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+     */
     public static
-    MethodType methodType(Class<?> rtype, List<? extends Class<?>> ptypes) {
+    MethodType methodType(Class<?> rtype, List<Class<?>> ptypes) {
         boolean notrust = false;  // random List impl. could return evil ptypes array
         return makeImpl(rtype, ptypes.toArray(NO_PTYPES), notrust);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     *  The leading parameter type is prepended to the remaining array.
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The leading parameter type is prepended to the remaining array.
+     * @return a method type with the given components
+     * @throws NullPointerException if {@code rtype} or {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is null
+     * @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
      */
     public static
     MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
@@ -170,25 +209,37 @@
         return makeImpl(rtype, ptypes1, true);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     *  The resulting method has no parameter types.
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The resulting method has no parameter types.
+     * @return a method type with the given return value
+     * @throws NullPointerException if {@code rtype} is null
      */
     public static
     MethodType methodType(Class<?> rtype) {
         return makeImpl(rtype, NO_PTYPES, true);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     *  The resulting method has the single given parameter type.
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The resulting method has the single given parameter type.
+     * @return a method type with the given return value and parameter type
+     * @throws NullPointerException if {@code rtype} or {@code ptype0} is null
+     * @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
      */
     public static
     MethodType methodType(Class<?> rtype, Class<?> ptype0) {
         return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     *  The resulting method has the same parameter types as {@code ptypes},
-     *  and the specified return type.
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The resulting method has the same parameter types as {@code ptypes},
+     * and the specified return type.
+     * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
      */
     public static
     MethodType methodType(Class<?> rtype, MethodType ptypes) {
@@ -237,17 +288,20 @@
     private static final MethodType[] objectOnlyTypes = new MethodType[20];
 
     /**
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+     * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * All parameters and the return type will be {@code Object},
      * except the final varargs parameter if any, which will be {@code Object[]}.
      * @param objectArgCount number of parameters (excluding the varargs parameter if any)
      * @param varargs whether there will be a varargs parameter, of type {@code Object[]}
      * @return a totally generic method type, given only its count of parameters and varargs
+     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
      * @see #genericMethodType(int)
      */
     public static
     MethodType genericMethodType(int objectArgCount, boolean varargs) {
         MethodType mt;
+        checkSlotCount(objectArgCount);
         int ivarargs = (!varargs ? 0 : 1);
         int ootIndex = objectArgCount*2 + ivarargs;
         if (ootIndex < objectOnlyTypes.length) {
@@ -265,9 +319,12 @@
     }
 
     /**
+     * Finds or creates a method type whose components are all {@code Object}.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * All parameters and the return type will be Object.
      * @param objectArgCount number of parameters
      * @return a totally generic method type, given only its count of parameters
+     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
      * @see #genericMethodType(int, boolean)
      */
     public static
@@ -275,27 +332,41 @@
         return genericMethodType(objectArgCount, false);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+    /**
+     * Finds or creates a method type with a single different parameter type.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * @param num    the index (zero-based) of the parameter type to change
      * @param nptype a new parameter type to replace the old one with
      * @return the same type, except with the selected parameter changed
+     * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
+     * @throws IllegalArgumentException if {@code nptype} is {@code void.class}
+     * @throws NullPointerException if {@code nptype} is null
      */
     public MethodType changeParameterType(int num, Class<?> nptype) {
         if (parameterType(num) == nptype)  return this;
+        checkPtype(nptype);
         Class<?>[] nptypes = ptypes.clone();
         nptypes[num] = nptype;
         return makeImpl(rtype, nptypes, true);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * @param num    the position (zero-based) of the inserted parameter type(s)
-     * @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
+     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
      * @return the same type, except with the selected parameter(s) inserted
+     * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
      */
     public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) {
         int len = ptypes.length;
         if (num < 0 || num > len)
-            throw newIllegalArgumentException("num="+num); //SPECME
+            throw newIndexOutOfBoundsException(num);
+        int ins = checkPtypes(ptypesToInsert);
+        checkSlotCount(parameterSlotCount() + ptypesToInsert.length + ins);
         int ilen = ptypesToInsert.length;
         if (ilen == 0)  return this;
         Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
@@ -304,40 +375,61 @@
         return makeImpl(rtype, nptypes, true);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     * @param ptypesToInsert zero or more a new parameter types to insert after the end of the parameter list
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
      * @return the same type, except with the selected parameter(s) appended
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
      */
     public MethodType appendParameterTypes(Class<?>... ptypesToInsert) {
         return insertParameterTypes(parameterCount(), ptypesToInsert);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     * @param ptypesToInsert zero or more a new parameter types to insert after the end of the parameter list
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param num    the position (zero-based) of the inserted parameter type(s)
+     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+     * @return the same type, except with the selected parameter(s) inserted
+     * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+     */
+    public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
+        return insertParameterTypes(num, ptypesToInsert.toArray(NO_PTYPES));
+    }
+
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
      * @return the same type, except with the selected parameter(s) appended
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
      */
     public MethodType appendParameterTypes(List<Class<?>> ptypesToInsert) {
         return insertParameterTypes(parameterCount(), ptypesToInsert);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     * @param num    the position (zero-based) of the inserted parameter type(s)
-     * @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
-     * @return the same type, except with the selected parameter(s) inserted
-     */
-    public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
-        return insertParameterTypes(num, ptypesToInsert.toArray(NO_PTYPES));
-    }
-
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+    /**
+     * Finds or creates a method type with some parameter types omitted.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * @param start  the index (zero-based) of the first parameter type to remove
      * @param end    the index (greater than {@code start}) of the first parameter type after not to remove
      * @return the same type, except with the selected parameter(s) removed
+     * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code end} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code start} is greater than {@code end}
      */
     public MethodType dropParameterTypes(int start, int end) {
         int len = ptypes.length;
         if (!(0 <= start && start <= end && end <= len))
-            throw newIllegalArgumentException("start="+start+" end="+end); //SPECME
+            throw newIndexOutOfBoundsException("start="+start+" end="+end);
         if (start == end)  return this;
         Class<?>[] nptypes;
         if (start == 0) {
@@ -361,17 +453,20 @@
         return makeImpl(rtype, nptypes, true);
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+    /**
+     * Finds or creates a method type with a different return type.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * @param nrtype a return parameter type to replace the old one with
      * @return the same type, except with the return type change
+     * @throws NullPointerException if {@code nrtype} is null
      */
     public MethodType changeReturnType(Class<?> nrtype) {
         if (returnType() == nrtype)  return this;
         return makeImpl(nrtype, ptypes, true);
     }
 
-    /** Convenience method.
-     * Report if this type contains a primitive argument or return value.
+    /**
+     * Reports if this type contains a primitive argument or return value.
      * The return type {@code void} counts as a primitive.
      * @return true if any of the types are primitives
      */
@@ -379,8 +474,8 @@
         return form.hasPrimitives();
     }
 
-    /** Convenience method.
-     * Report if this type contains a wrapper argument or return value.
+    /**
+     * Reports if this type contains a wrapper argument or return value.
      * Wrappers are types which box primitive values, such as {@link Integer}.
      * The reference type {@code java.lang.Void} counts as a wrapper.
      * @return true if any of the types are wrappers
@@ -389,8 +484,9 @@
         return unwrap() != this;
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     * Erase all reference types to {@code Object}.
+    /**
+     * Erases all reference types to {@code Object}.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * All primitive types (including {@code void}) will remain unchanged.
      * @return a version of the original type with all reference types replaced
      */
@@ -398,8 +494,9 @@
         return form.erasedType();
     }
 
-    /** Convenience method for {@link #genericMethodType(int)}.
-     * Convert all types, both reference and primitive, to {@code Object}.
+    /**
+     * Converts all types, both reference and primitive, to {@code Object}.
+     * Convenience method for {@link #genericMethodType(int) genericMethodType}.
      * The expression {@code type.wrap().erase()} produces the same value
      * as {@code type.generic()}.
      * @return a version of the original type with all types replaced
@@ -408,8 +505,9 @@
         return genericMethodType(parameterCount());
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     * Convert all primitive types to their corresponding wrapper types.
+    /**
+     * Converts all primitive types to their corresponding wrapper types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * All reference types (including wrapper types) will remain unchanged.
      * A {@code void} return type is changed to the type {@code java.lang.Void}.
      * The expression {@code type.wrap().erase()} produces the same value
@@ -420,8 +518,9 @@
         return hasPrimitives() ? wrapWithPrims(this) : this;
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
+    /**
      * Convert all wrapper types to their corresponding primitive types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * All primitive types (including {@code void}) will remain unchanged.
      * A return type of {@code java.lang.Void} is changed to {@code void}.
      * @return a version of the original type with all wrapper types replaced
@@ -456,23 +555,33 @@
         return uwt;
     }
 
-    /** @param num the index (zero-based) of the desired parameter type
-     *  @return the selected parameter type
+    /**
+     * Returns the parameter type at the specified index, within this method type.
+     * @param num the index (zero-based) of the desired parameter type
+     * @return the selected parameter type
+     * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
      */
     public Class<?> parameterType(int num) {
         return ptypes[num];
     }
-    /** @return the number of parameter types */
+    /**
+     * Returns the number of parameter types in this method type.
+     * @return the number of parameter types
+     */
     public int parameterCount() {
         return ptypes.length;
     }
-    /** @return the return type */
+    /**
+     * Returns the return type of this method type.
+     * @return the return type
+     */
     public Class<?> returnType() {
         return rtype;
     }
 
     /**
-     * Convenience method to present the arguments as a list.
+     * Presents the parameter types as a list (a convenience method).
+     * The list will be immutable.
      * @return the parameter types (as an immutable list)
      */
     public List<Class<?>> parameterList() {
@@ -480,7 +589,7 @@
     }
 
     /**
-     * Convenience method to present the arguments as an array.
+     * Presents the parameter types as an array (a convenience method).
      * Changes to the array will not result in changes to the type.
      * @return the parameter types (as a fresh copy if necessary)
      */
@@ -524,14 +633,14 @@
     }
 
     /**
+     * Returns a string representation of the method type,
+     * of the form {@code "(PT0,PT1...)RT"}.
      * The string representation of a method type is a
      * parenthesis enclosed, comma separated list of type names,
      * followed immediately by the return type.
      * <p>
      * Each type is represented by its
      * {@link java.lang.Class#getSimpleName simple name}.
-     * If a type name name is array, it the base type followed
-     * by [], rather than the Class.getName of the array type.
      */
     @Override
     public String toString() {
@@ -548,21 +657,22 @@
 
     /// Queries which have to do with the bytecode architecture
 
-    /** 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
      * a second stack slot to pass long and double arguments.
-     * So this method returns {@link #parameterCount()} plus the
+     * So this method returns {@link #parameterCount() parameterCount} plus the
      * number of long and double parameters (if any).
      * <p>
      * This method is included for the benfit of applications that must
      * generate bytecodes that process method handles and invokedynamic.
      * @return the number of JVM stack slots for this type's parameters
+     * @deprecated Will be removed for PFD.
      */
     public int parameterSlotCount() {
         return form.parameterSlotCount();
     }
 
-    /** 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
      * {@code parameterCount} inclusive.  Successive parameters are
      * more shallowly stacked, and parameters are indexed in the bytecodes
@@ -583,6 +693,8 @@
      * @param num an index (zero-based, inclusive) within the parameter types
      * @return the index of the (shallowest) JVM stack slot transmitting the
      *         given parameter
+     * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
+     * @deprecated Will be removed for PFD.
      */
     public int parameterSlotDepth(int num) {
         if (num < 0 || num > ptypes.length)
@@ -590,7 +702,7 @@
         return form.parameterToArgSlot(num-1);
     }
 
-    /** The number of JVM stack slots required to receive a return value
+    /** Reports the number of JVM stack slots required to receive a return value
      * from a method of this type.
      * If the {@link #returnType() return type} is void, it will be zero,
      * else if the return type is long or double, it will be two, else one.
@@ -598,13 +710,15 @@
      * This method is included for the benfit of applications that must
      * 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
+     * @deprecated Will be removed for PFD.
      */
     public int returnSlotCount() {
         return form.returnSlotCount();
     }
 
-    /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
-     * Find or create an instance of the given method type.
+    /**
+     * Find or create 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}.
      * Any class or interface name embedded in the descriptor string
      * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
      * on the given loader (or if it is null, on the system class loader).
@@ -614,10 +728,10 @@
      * not all reachable from a common class loader.
      * <p>
      * This method is included for the benfit of applications that must
-     * generate bytecodes that process method handles and invokedynamic.
-     * @param descriptor a bytecode-level signature string "(T...)T"
+     * generate bytecodes that process method handles and {@code invokedynamic}.
+     * @param descriptor a bytecode-level type descriptor string "(T...)T"
      * @param loader the class loader in which to look up the types
-     * @return a method type matching the bytecode-level signature
+     * @return a method type matching the bytecode-level type descriptor
      * @throws IllegalArgumentException if the string is not well-formed
      * @throws TypeNotPresentException if a named type cannot be found
      */
@@ -631,19 +745,121 @@
     }
 
     /**
-     * Create a bytecode descriptor representation of the method type.
+     * Produces a bytecode descriptor representation of the method type.
      * <p>
-     * Note that this is not a strict inverse of {@link #fromMethodDescriptorString}.
+     * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
      * Two distinct classes which share a common name but have different class loaders
      * will appear identical when viewed within descriptor strings.
      * <p>
      * This method is included for the benfit of applications that must
-     * generate bytecodes that process method handles and invokedynamic.
-     * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader)},
+     * generate bytecodes that process method handles and {@code invokedynamic}.
+     * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
      * because the latter requires a suitable class loader argument.
-     * @return the bytecode signature representation
+     * @return the bytecode type descriptor representation
      */
     public String toMethodDescriptorString() {
         return BytecodeDescriptor.unparse(this);
     }
+
+    /// Serialization.
+
+    /**
+     * There are no serializable fields for {@code MethodType}.
+     */
+    private static final java.io.ObjectStreamField[] serialPersistentFields = { };
+
+    /**
+     * Save the {@code MethodType} instance to a stream.
+     *
+     * @serialData
+     * For portability, the serialized format does not refer to named fields.
+     * Instead, the return type and parameter type arrays are written directly
+     * from the {@code writeObject} method, using two calls to {@code s.writeObject}
+     * as follows:
+     * <blockquote><pre>
+s.writeObject(this.returnType());
+s.writeObject(this.parameterArray());
+     * </pre></blockquote>
+     * <p>
+     * The deserialized field values are checked as if they were
+     * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
+     * For example, null values, or {@code void} parameter types,
+     * will lead to exceptions during deserialization.
+     * @param the stream to write the object to
+     */
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        s.defaultWriteObject();  // requires serialPersistentFields to be an empty array
+        s.writeObject(returnType());
+        s.writeObject(parameterArray());
+    }
+
+    /**
+     * Reconstitute the {@code MethodType} instance from a stream (that is,
+     * deserialize it).
+     * This instance is a scratch object with bogus final fields.
+     * It provides the parameters to the factory method called by
+     * {@link #readResolve readResolve}.
+     * After that call it is discarded.
+     * @param the stream to read the object from
+     * @see #MethodType()
+     * @see #readResolve
+     * @see #writeObject
+     */
+    private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();  // requires serialPersistentFields to be an empty array
+
+        Class<?>   returnType     = (Class<?>)   s.readObject();
+        Class<?>[] parameterArray = (Class<?>[]) s.readObject();
+
+        // Probably this object will never escape, but let's check
+        // the field values now, just to be sure.
+        checkRtype(returnType);
+        checkPtypes(parameterArray);
+
+        parameterArray = parameterArray.clone();  // make sure it is unshared
+        MethodType_init(returnType, parameterArray);
+    }
+
+    /**
+     * For serialization only.
+     * Sets the final fields to null, pending {@code Unsafe.putObject}.
+     */
+    private MethodType() {
+        this.rtype = null;
+        this.ptypes = null;
+    }
+    private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) {
+        // In order to communicate these values to readResolve, we must
+        // store them into the implementation-specific final fields.
+        checkRtype(rtype);
+        checkPtypes(ptypes);
+        unsafe.putObject(this, rtypeOffset, rtype);
+        unsafe.putObject(this, ptypesOffset, ptypes);
+    }
+
+    // Support for resetting final fields while deserializing
+    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+    private static final long rtypeOffset, ptypesOffset;
+    static {
+        try {
+            rtypeOffset = unsafe.objectFieldOffset
+                (MethodType.class.getDeclaredField("rtype"));
+            ptypesOffset = unsafe.objectFieldOffset
+                (MethodType.class.getDeclaredField("ptypes"));
+        } catch (Exception ex) {
+            throw new Error(ex);
+        }
+    }
+
+    /**
+     * Resolves and initializes a {@code MethodType} object
+     * after serialization.
+     * @return the fully initialized {@code MethodType} object
+     */
+    private Object readResolve() {
+        // Do not use a trusted path for deserialization:
+        //return makeImpl(rtype, ptypes, true);
+        // Verify all operands, and make sure ptypes is unshared:
+        return methodType(rtype, ptypes);
+    }
 }
--- a/src/share/classes/java/dyn/MutableCallSite.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/MutableCallSite.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,7 @@
  * (This is a normal consequence of the Java Memory Model as applied
  * to object fields.)
  * <p>
- * The {@link #sync sync} operation provides a way to force threads
+ * The {@link #syncAll syncAll} operation provides a way to force threads
  * to accept a new target value, even if there is no other synchronization.
  * <p>
  * For target values which will be frequently updated, consider using
@@ -82,13 +82,17 @@
  */
 public class MutableCallSite extends CallSite {
     /**
-     * Make a blank call site object with the given method type.
-     * An initial target method is supplied which will throw
-     * an {@link IllegalStateException} if called.
+     * Creates a blank call site object with the given method type.
+     * The initial target is set to a method handle of the given type
+     * which will throw an {@link IllegalStateException} if called.
+     * <p>
+     * The type of the call site is permanently set to the given type.
      * <p>
      * Before this {@code CallSite} object is returned from a bootstrap method,
+     * or invoked in some other manner,
      * it is usually provided with a more useful target method,
      * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+     * @param type the method type that this call site will have
      * @throws NullPointerException if the proposed type is null
      */
     public MutableCallSite(MethodType type) {
@@ -96,8 +100,9 @@
     }
 
     /**
-     * Make a blank call site object, possibly equipped with an initial target method handle.
-     * @param target the method handle which will be the initial target of the call site
+     * Creates a call site object with an initial target method handle.
+     * The type of the call site is permanently set to the initial target's type.
+     * @param target the method handle that will be the initial target of the call site
      * @throws NullPointerException if the proposed target is null
      */
     public MutableCallSite(MethodHandle target) {
@@ -105,7 +110,59 @@
     }
 
     /**
-     * Perform a synchronization operation on each call site in the given array,
+     * Returns the target method of the call site, which behaves
+     * like a normal field of the {@code MutableCallSite}.
+     * <p>
+     * The interactions of {@code getTarget} with memory are the same
+     * as of a read from an ordinary variable, such as an array element or a
+     * non-volatile, non-final field.
+     * <p>
+     * In particular, the current thread may choose to reuse the result
+     * of a previous read of the target from memory, and may fail to see
+     * a recent update to the target by another thread.
+     *
+     * @return the linkage state of this call site, a method handle which can change over time
+     * @see #setTarget
+     */
+    @Override public final MethodHandle getTarget() {
+        return target;
+    }
+
+    /**
+     * Updates the target method of this call site, as a normal variable.
+     * The type of the new target must agree with the type of the old target.
+     * <p>
+     * The interactions with memory are the same
+     * as of a write to an ordinary variable, such as an array element or a
+     * non-volatile, non-final field.
+     * <p>
+     * In particular, unrelated threads may fail to see the updated target
+     * until they perform a read from memory.
+     * Stronger guarantees can be created by putting appropriate operations
+     * into the bootstrap method and/or the target methods used
+     * at any given call site.
+     *
+     * @param newTarget the new target
+     * @throws NullPointerException if the proposed new target is null
+     * @throws WrongMethodTypeException if the proposed new target
+     *         has a method type that differs from the previous target
+     * @see #getTarget
+     */
+    @Override public void setTarget(MethodHandle newTarget) {
+        checkTargetChange(this.target, newTarget);
+        setTargetNormal(newTarget);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final MethodHandle dynamicInvoker() {
+        return makeDynamicInvoker();
+    }
+
+    /**
+     * Performs a synchronization operation on each call site in the given array,
      * forcing all other threads to throw away any cached values previously
      * loaded from the target of any of the call sites.
      * <p>
@@ -115,19 +172,29 @@
      * <p>
      * The overall effect is to force all future readers of each call site's target
      * to accept the most recently stored value.
-     * ("Most recently" is reckoned relative to the {@code sync} itself.)
-     * Conversely, the {@code sync} call may block until all readers have
+     * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
+     * Conversely, the {@code syncAll} call may block until all readers have
      * (somehow) decached all previous versions of each call site's target.
      * <p>
-     * To avoid race conditions, calls to {@code setTarget} and {@code sync}
+     * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
      * should generally be performed under some sort of mutual exclusion.
      * Note that reader threads may observe an updated target as early
      * as the {@code setTarget} call that install the value
-     * (and before the {@code sync} that confirms the value).
+     * (and before the {@code syncAll} that confirms the value).
      * On the other hand, reader threads may observe previous versions of
-     * the target until the {@code sync} call returns
+     * the target until the {@code syncAll} call returns
      * (and after the {@code setTarget} that attempts to convey the updated version).
      * <p>
+     * This operation is likely to be expensive and should be used sparingly.
+     * If possible, it should be buffered for batch processing on sets of call sites.
+     * <p>
+     * If {@code sites} contains a null element,
+     * a {@code NullPointerException} will be raised.
+     * In this case, some non-null elements in the array may be
+     * processed before the method returns abnormally.
+     * Which elements these are (if any) is implementation-dependent.
+     *
+     * <h3>Java Memory Model details</h3>
      * In terms of the Java Memory Model, this operation performs a synchronization
      * action which is comparable in effect to the writing of a volatile variable
      * by the current thread, and an eventual volatile read by every other thread
@@ -171,18 +238,17 @@
      * thereby ensuring communication of the new target value.
      * <p>
      * As long as the constraints of the Java Memory Model are obeyed,
-     * implementations may delay the completion of a {@code sync}
+     * implementations may delay the completion of a {@code syncAll}
      * operation while other threads ({@code T} above) continue to
      * use previous values of {@code S}'s target.
      * However, implementations are (as always) encouraged to avoid
      * livelock, and to eventually require all threads to take account
      * of the updated target.
-     * <p>
-     * This operation is likely to be expensive and should be used sparingly.
-     * If possible, it should be buffered for batch processing on sets of call sites.
+     *
      * <p style="font-size:smaller;">
-     * (This is a static method on a set of call sites, not a
-     * virtual method on a single call site, for performance reasons.
+     * <em>Discussion:</em>
+     * For performance reasons, {@code syncAll} is not a virtual method
+     * on a single call site, but rather applies to a set of call sites.
      * Some implementations may incur a large fixed overhead cost
      * for processing one or more synchronization operations,
      * but a small incremental cost for each additional call site.
@@ -191,15 +257,25 @@
      * in order to make them notice the updated target value.
      * However, it may be observed that a single call to synchronize
      * several sites has the same formal effect as many calls,
-     * each on just one of the sites.)
-     * <p>
+     * each on just one of the sites.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Implementation Note:</em>
      * Simple implementations of {@code MutableCallSite} may use
      * a volatile variable for the target of a mutable call site.
-     * In such an implementation, the {@code sync} method can be a no-op,
+     * In such an implementation, the {@code syncAll} method can be a no-op,
      * and yet it will conform to the JMM behavior documented above.
+     *
+     * @param sites an array of call sites to be synchronized
+     * @throws NullPointerException if the {@code sites} array reference is null
+     *                              or the array contains a null
      */
-    public static void sync(MutableCallSite[] sites) {
+    public static void syncAll(MutableCallSite[] sites) {
+        if (sites.length == 0)  return;
         STORE_BARRIER.lazySet(0);
+        for (int i = 0; i < sites.length; i++) {
+            sites[i].getClass();  // trigger NPE on first null
+        }
         // FIXME: NYI
     }
     private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
--- a/src/share/classes/java/dyn/NoAccessException.java	Wed Mar 02 13:18:36 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +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;
-
-/**
- * Thrown to indicate that a caller has attempted to create a method handle
- * which accesses a field, method, or class to which the caller does not have access.
- * This unchecked exception is analogous to {@link IllegalAccessException},
- * which is a checked exception thrown when reflective invocation fails
- * because of an access check.  With method handles, this same access
- * checking is performed by the {@link MethodHandles.Lookup lookup object}
- * on behalf of the method handle creator,
- * at the time of creation.
- * @author John Rose, JSR 292 EG
- * @since 1.7
- */
-public class NoAccessException extends ReflectiveOperationException {
-    private static final long serialVersionUID = 292L;
-
-    /**
-     * Constructs a {@code NoAccessException} with no detail message.
-     */
-    public NoAccessException() {
-        super();
-    }
-
-    /**
-     * Constructs a {@code NoAccessException} with the specified
-     * detail message.
-     *
-     * @param s the detail message
-     */
-    public NoAccessException(String s) {
-        super(s);
-    }
-
-    /**
-     * Constructs a {@code NoAccessException} with the specified cause.
-     *
-     * @param cause the underlying cause of the exception
-     */
-    public NoAccessException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructs a {@code NoAccessException} with the specified
-     * detail message and cause.
-     *
-     * @param s the detail message
-     * @param cause the underlying cause of the exception
-     */
-    public NoAccessException(String s, Throwable cause) {
-        super(s, cause);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/dyn/SwitchPoint.java	Thu Mar 03 07:02:30 2011 -0800
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2010, 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.dyn;
+
+/**
+ * <p>
+ * A {@code SwitchPoint} is an object which can publish state transitions to other threads.
+ * A switch point is initially in the <em>valid</em> state, but may at any time be
+ * changed to the <em>invalid</em> state.  Invalidation cannot be reversed.
+ * A switch point can combine a <em>guarded pair</em> of method handles into a
+ * <em>guarded delegator</em>.
+ * The guarded delegator is a method handle which delegates to one of the old method handles.
+ * The state of the switch point determines which of the two gets the delegation.
+ * <p>
+ * A single switch point may be used to control any number of method handles.
+ * (Indirectly, therefore, it can control any number of call sites.)
+ * This is done by using the single switch point as a factory for combining
+ * any number of guarded method handle pairs into guarded delegators.
+ * <p>
+ * When a guarded delegator is created from a guarded pair, the pair
+ * is wrapped in a new method handle {@code M},
+ * which is permanently associated with the switch point that created it.
+ * Each pair consists of a target {@code T} and a fallback {@code F}.
+ * While the switch point is valid, invocations to {@code M} are delegated to {@code T}.
+ * After it is invalidated, invocations are delegated to {@code F}.
+ * <p>
+ * Invalidation is global and immediate, as if the switch point contained a
+ * volatile boolean variable consulted on every call to {@code M}.
+ * The invalidation is also permanent, which means the switch point
+ * can change state only once.
+ * The switch point will always delegate to {@code F} after being invalidated.
+ * At that point {@code guardWithTest} may ignore {@code T} and return {@code F}.
+ * <p>
+ * Here is an example of a switch point in action:
+ * <blockquote><pre>
+MethodType MT_str2 = MethodType.methodType(String.class, String.class);
+MethodHandle MH_strcat = MethodHandles.lookup()
+    .findVirtual(String.class, "concat", MT_str2);
+SwitchPoint spt = new SwitchPoint();
+// the following steps may be repeated to re-use the same switch point:
+MethodHandle worker1 = strcat;
+MethodHandle worker2 = MethodHandles.permuteArguments(strcat, MT_str2, 1, 0);
+MethodHandle worker = spt.guardWithTest(worker1, worker2);
+assertEquals("method", (String) worker.invokeExact("met", "hod"));
+SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
+assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
+ * </pre></blockquote>
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * Switch points are useful without subclassing.  They may also be subclassed.
+ * This may be useful in order to associate application-specific invalidation logic
+ * with the switch point.
+ * <p style="font-size:smaller;">
+ * <em>Implementation Note:</em>
+ * A switch point behaves as if implemented on top of {@link MutableCallSite},
+ * approximately as follows:
+ * <blockquote><pre>
+public class SwitchPoint {
+  private static final MethodHandle
+    K_true  = MethodHandles.constant(boolean.class, true),
+    K_false = MethodHandles.constant(boolean.class, false);
+  private final MutableCallSite mcs;
+  private final MethodHandle mcsInvoker;
+  public SwitchPoint() {
+    this.mcs = new MutableCallSite(K_true);
+    this.mcsInvoker = mcs.dynamicInvoker();
+  }
+  public MethodHandle guardWithTest(
+                MethodHandle target, MethodHandle fallback) {
+    // Note:  mcsInvoker is of type ()boolean.
+    // Target and fallback may take any arguments, but must have the same type.
+    return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback);
+  }
+  public static void invalidateAll(SwitchPoint[] spts) {
+    List&lt;MutableCallSite&gt; mcss = new ArrayList&lt;&gt;();
+    for (SwitchPoint spt : spts)  mcss.add(spt.mcs);
+    for (MutableCallSite mcs : mcss)  mcs.setTarget(K_false);
+    MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
+  }
+}
+ * </pre></blockquote>
+ * @author Remi Forax, JSR 292 EG
+ */
+public class SwitchPoint {
+    private static final MethodHandle
+        K_true  = MethodHandles.constant(boolean.class, true),
+        K_false = MethodHandles.constant(boolean.class, false);
+
+    private final MutableCallSite mcs;
+    private final MethodHandle mcsInvoker;
+
+    /**
+     * Creates a new switch point.
+     */
+    public SwitchPoint() {
+        this.mcs = new MutableCallSite(K_true);
+        this.mcsInvoker = mcs.dynamicInvoker();
+    }
+
+    /**
+     * Returns a method handle which always delegates either to the target or the fallback.
+     * The method handle will delegate to the target exactly as long as the switch point is valid.
+     * After that, it will permanently delegate to the fallback.
+     * <p>
+     * The target and fallback must be of exactly the same method type,
+     * and the resulting combined method handle will also be of this type.
+     *
+     * @param target the method handle selected by the switch point as long as it is valid
+     * @param fallback the method handle selected by the switch point after it is invalidated
+     * @return a combined method handle which always calls either the target or fallback
+     * @throws NullPointerException if either argument is null
+     * @see MethodHandles#guardWithTest
+     */
+    public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback) {
+        if (mcs.getTarget() == K_false)
+            return fallback;  // already invalid
+        return MethodHandles.guardWithTest(mcsInvoker, target, fallback);
+    }
+
+    /**
+     * Sets all of the given switch points into the invalid state.
+     * After this call executes, no thread will observe any of the
+     * switch points to be in a valid state.
+     * <p>
+     * This operation is likely to be expensive and should be used sparingly.
+     * If possible, it should be buffered for batch processing on sets of switch points.
+     * <p>
+     * If {@code switchPoints} contains a null element,
+     * a {@code NullPointerException} will be raised.
+     * In this case, some non-null elements in the array may be
+     * processed before the method returns abnormally.
+     * Which elements these are (if any) is implementation-dependent.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * For performance reasons, {@code invalidateAll} is not a virtual method
+     * on a single switch point, but rather applies to a set of switch points.
+     * Some implementations may incur a large fixed overhead cost
+     * for processing one or more invalidation operations,
+     * but a small incremental cost for each additional invalidation.
+     * In any case, this operation is likely to be costly, since
+     * other threads may have to be somehow interrupted
+     * in order to make them notice the updated switch point state.
+     * However, it may be observed that a single call to invalidate
+     * several switch points has the same formal effect as many calls,
+     * each on just one of the switch points.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Implementation Note:</em>
+     * Simple implementations of {@code SwitchPoint} may use
+     * a private {@link MutableCallSite} to publish the state of a switch point.
+     * In such an implementation, the {@code invalidateAll} method can
+     * simply change the call site's target, and issue one call to
+     * {@linkplain MutableCallSite#syncAll synchronize} all the
+     * private call sites.
+     *
+     * @param switchPoints an array of call sites to be synchronized
+     * @throws NullPointerException if the {@code switchPoints} array reference is null
+     *                              or the array contains a null
+     */
+    public static void invalidateAll(SwitchPoint[] switchPoints) {
+        if (switchPoints.length == 0)  return;
+        MutableCallSite[] sites = new MutableCallSite[switchPoints.length];
+        for (int i = 0; i < switchPoints.length; i++) {
+            SwitchPoint spt = switchPoints[i];
+            if (spt == null)  break;  // MSC.syncAll will trigger a NPE
+            sites[i] = spt.mcs;
+            spt.mcs.setTarget(K_false);
+        }
+        MutableCallSite.syncAll(sites);
+    }
+}
--- a/src/share/classes/java/dyn/Switcher.java	Wed Mar 02 13:18:36 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.dyn;
-
-/**
- * <p>
- * A {@code Switcher} is an object which can publish state transitions to other threads.
- * A switcher is initially in the <em>valid</em> state, but may at any time be
- * changed to the <em>invalid</em> state.  Invalidation cannot be reversed.
- * <p>
- * A single switcher may be used to create any number of guarded method handle pairs.
- * Each guarded pair is wrapped in a new method handle {@code M},
- * which is permanently associated with the switcher that created it.
- * Each pair consists of a target {@code T} and a fallback {@code F}.
- * While the switcher is valid, invocations to {@code M} are delegated to {@code T}.
- * After it is invalidated, invocations are delegated to {@code F}.
- * <p>
- * Invalidation is global and immediate, as if the switcher contained a
- * volatile boolean variable consulted on every call to {@code M}.
- * The invalidation is also permanent, which means the switcher
- * can change state only once.
- * <p>
- * Here is an example of a switcher in action:
- * <blockquote><pre>
-MethodType MT_str2 = MethodType.methodType(String.class, String.class);
-MethodHandle MH_strcat = MethodHandles.lookup()
-    .findVirtual(String.class, "concat", MT_str2);
-Switcher switcher = new Switcher();
-// the following steps may be repeated to re-use the same switcher:
-MethodHandle worker1 = strcat;
-MethodHandle worker2 = MethodHandles.permuteArguments(strcat, MT_str2, 1, 0);
-MethodHandle worker = switcher.guardWithTest(worker1, worker2);
-assertEquals("method", (String) worker.invokeExact("met", "hod"));
-switcher.invalidate();
-assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
- * </pre></blockquote>
- * <p>
- * <em>Implementation Note:</em>
- * A switcher behaves as if implemented on top of {@link MutableCallSite},
- * approximately as follows:
- * <blockquote><pre>
-public class Switcher {
-  private static final MethodHandle
-    K_true  = MethodHandles.constant(boolean.class, true),
-    K_false = MethodHandles.constant(boolean.class, false);
-  private final MutableCallSite mcs;
-  private final MethodHandle mcsInvoker;
-  public Switcher() {
-    this.mcs = new MutableCallSite(K_true);
-    this.mcsInvoker = mcs.dynamicInvoker();
-  }
-  public MethodHandle guardWithTest(
-                MethodHandle target, MethodHandle fallback) {
-    // Note:  mcsInvoker is of type boolean().
-    // Target and fallback may take any arguments, but must have the same type.
-    return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback);
-  }
-  public static void invalidateAll(Switcher[] switchers) {
-    List<MutableCallSite> mcss = new ArrayList<>();
-    for (Switcher s : switchers)  mcss.add(s.mcs);
-    for (MutableCallSite mcs : mcss)  mcs.setTarget(K_false);
-    MutableCallSite.sync(mcss.toArray(new MutableCallSite[0]));
-  }
-}
- * </pre></blockquote>
- * @author Remi Forax, JSR 292 EG
- */
-public class Switcher {
-    private static final MethodHandle
-        K_true  = MethodHandles.constant(boolean.class, true),
-        K_false = MethodHandles.constant(boolean.class, false);
-
-    private final MutableCallSite mcs;
-    private final MethodHandle mcsInvoker;
-
-    /** Create a switcher. */
-    public Switcher() {
-        this.mcs = new MutableCallSite(K_true);
-        this.mcsInvoker = mcs.dynamicInvoker();
-    }
-
-    /**
-     * Return a method handle which always delegates either to the target or the fallback.
-     * The method handle will delegate to the target exactly as long as the switcher is valid.
-     * After that, it will permanently delegate to the fallback.
-     * <p>
-     * The target and fallback must be of exactly the same method type,
-     * and the resulting combined method handle will also be of this type.
-     * @see MethodHandles#guardWithTest
-     */
-    public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback) {
-        if (mcs.getTarget() == K_false)
-            return fallback;  // already invalid
-        return MethodHandles.guardWithTest(mcsInvoker, target, fallback);
-    }
-
-    /** Set all of the given switchers into the invalid state. */
-    public static void invalidateAll(Switcher[] switchers) {
-        MutableCallSite[] sites = new MutableCallSite[switchers.length];
-        int fillp = 0;
-        for (Switcher switcher : switchers) {
-            sites[fillp++] = switcher.mcs;
-            switcher.mcs.setTarget(K_false);
-        }
-        MutableCallSite.sync(sites);
-    }
-}
--- a/src/share/classes/java/dyn/VolatileCallSite.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/VolatileCallSite.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
  * There may be a performance penalty for such tight coupling between threads.
  * <p>
  * Unlike {@code MutableCallSite}, there is no
- * {@linkplain MutableCallSite#sync sync operation} on volatile
+ * {@linkplain MutableCallSite#syncAll syncAll operation} on volatile
  * call sites, since every write to a volatile variable is implicitly
  * synchronized with reader threads.
  * <p>
@@ -44,36 +44,68 @@
  * @author John Rose, JSR 292 EG
  */
 public class VolatileCallSite extends CallSite {
-    /** Create a call site with a volatile target.
-     *  The initial target is set to a method handle
-     *  of the given type which will throw {@code IllegalStateException}.
+    /**
+     * Creates a call site with a volatile binding to its target.
+     * The initial target is set to a method handle
+     * of the given type which will throw an {@code IllegalStateException} if called.
+     * @param type the method type that this call site will have
      * @throws NullPointerException if the proposed type is null
      */
     public VolatileCallSite(MethodType type) {
         super(type);
     }
 
-    /** Create a call site with a volatile target.
-     *  The target is set to the given value.
+    /**
+     * Creates a call site with a volatile binding to its target.
+     * The target is set to the given value.
+     * @param target the method handle that will be the initial target of the call site
      * @throws NullPointerException if the proposed target is null
      */
     public VolatileCallSite(MethodHandle target) {
         super(target);
     }
 
-    /** Internal override to nominally final getTarget. */
-    @Override
-    MethodHandle getTarget0() {
+    /**
+     * Returns the target method of the call site, which behaves
+     * like a {@code volatile} field of the {@code VolatileCallSite}.
+     * <p>
+     * The interactions of {@code getTarget} with memory are the same
+     * as of a read from a {@code volatile} field.
+     * <p>
+     * In particular, the current thread is required to issue a fresh
+     * read of the target from memory, and must not fail to see
+     * a recent update to the target by another thread.
+     *
+     * @return the linkage state of this call site, a method handle which can change over time
+     * @see #setTarget
+     */
+    @Override public final MethodHandle getTarget() {
         return getTargetVolatile();
     }
 
     /**
-     * Set the target method of this call site, as a volatile variable.
-     * Has the same effect as {@link CallSite#setTarget CallSite.setTarget}, with the additional
-     * effects associated with volatiles, in the Java Memory Model.
+     * Updates the target method of this call site, as a volatile variable.
+     * The type of the new target must agree with the type of the old target.
+     * <p>
+     * The interactions with memory are the same as of a write to a volatile field.
+     * In particular, any threads is guaranteed to see the updated target
+     * the next time it calls {@code getTarget}.
+     * @param newTarget the new target
+     * @throws NullPointerException if the proposed new target is null
+     * @throws WrongMethodTypeException if the proposed new target
+     *         has a method type that differs from the previous target
+     * @see #getTarget
      */
     @Override public void setTarget(MethodHandle newTarget) {
         checkTargetChange(getTargetVolatile(), newTarget);
         setTargetVolatile(newTarget);
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final MethodHandle dynamicInvoker() {
+        return makeDynamicInvoker();
+    }
 }
--- a/src/share/classes/java/dyn/WrongMethodTypeException.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/WrongMethodTypeException.java	Thu Mar 03 07:02:30 2011 -0800
@@ -29,7 +29,7 @@
  * Thrown to indicate that code has attempted to call a method handle
  * via the wrong method type.  As with the bytecode representation of
  * normal Java method calls, method handle calls are strongly typed
- * to a specific signature associated with a call site.
+ * to a specific type descriptor associated with a call site.
  * <p>
  * This exception may also be thrown when two method handles are
  * composed, and the system detects that their types cannot be
--- a/src/share/classes/java/dyn/package-info.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/dyn/package-info.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,21 +24,20 @@
  */
 
 /**
- * This package contains dynamic language support provided directly by
+ * The {@code java.lang.invoke} package contains dynamic language support provided directly by
  * the Java core class libraries and virtual machine.
+ *
+ * <p style="font-size:smaller;">
+ * <em>Historic Note:</em> In some early versions of Java SE 7,
+ * the name of this package is {@code java.dyn}.
  * <p>
  * Certain types in this package have special relations to dynamic
  * language support in the virtual machine:
  * <ul>
- * <li>In source code, a call to
- * {@link java.dyn.MethodHandle#invokeExact   MethodHandle.invokeExact} or
- * {@link java.dyn.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
- * will compile and link, regardless of the requested type signature.
- * As usual, the Java compiler emits an {@code invokevirtual}
- * instruction with the given signature against the named method.
- * The JVM links any such call (regardless of signature) to a dynamically
- * typed method handle invocation.  In the case of {@code invokeGeneric},
- * argument and return value conversions are applied.
+ * <li>The class {@link java.dyn.MethodHandle MethodHandle} contains
+ * <a href="MethodHandle.html#sigpoly">signature polymorphic methods</a>
+ * which can be linked regardless of their type descriptor.
+ * Normally, method linkage requires exact matching of type descriptors.
  * </li>
  *
  * <li>The JVM bytecode format supports immediate constants of
@@ -58,12 +57,11 @@
  * The final two bytes are reserved for future use and required to be zero.
  * The constant pool reference of an {@code invokedynamic} instruction is to a entry
  * with tag {@code CONSTANT_InvokeDynamic} (decimal 18).  See below for its format.
- * (The tag value 17 is also temporarily allowed.  See below.)
  * The entry specifies the following information:
  * <ul>
  * <li>a bootstrap method (a {@link java.dyn.MethodHandle MethodHandle} constant)</li>
  * <li>the dynamic invocation name (a UTF8 string)</li>
- * <li>the argument and return types of the call (encoded as a signature in a UTF8 string)</li>
+ * <li>the argument and return types of the call (encoded as a type descriptor in a UTF8 string)</li>
  * <li>optionally, a sequence of additional <em>static arguments</em> to the bootstrap method ({@code ldc}-type constants)</li>
  * </ul>
  * <p>
@@ -78,9 +76,9 @@
  * as <a href="#bsm">described below</a>.
  *
  * <p style="font-size:smaller;">
- * (Historic Note: Some older JVMs may allow the index of a {@code CONSTANT_NameAndType}
+ * <em>Historic Note:</em> Some older JVMs may allow the index of a {@code CONSTANT_NameAndType}
  * instead of a {@code CONSTANT_InvokeDynamic}.  In earlier, obsolete versions of this API, the
- * bootstrap method was specified dynamically, in a per-class basis, during class initialization.)
+ * bootstrap method was specified dynamically, in a per-class basis, during class initialization.
  *
  * <h3><a name="indycon"></a>constant pool entries for {@code invokedynamic} instructions</h3>
  * If a constant pool entry has the tag {@code CONSTANT_InvokeDynamic} (decimal 18),
@@ -90,33 +88,21 @@
  * <em>bootstrap method table</em>, which is stored in the {@code BootstrapMethods}
  * attribute as <a href="#bsmattr">described below</a>.
  * The second pair of bytes must be an index to a {@code CONSTANT_NameAndType}.
- * This table is not part of the constant pool.  Instead, it is stored
- * in a class attribute named {@code BootstrapMethods}, described below.
  * <p>
  * The first index specifies a bootstrap method used by the associated dynamic call sites.
  * The second index specifies the method name, argument types, and return type of the dynamic call site.
  * The structure of such an entry is therefore analogous to a {@code CONSTANT_Methodref},
  * except that the bootstrap method specifier reference replaces
  * the {@code CONSTANT_Class} reference of a {@code CONSTANT_Methodref} entry.
- * <p>
- * Some older JVMs may allow an older constant pool entry tag of decimal 17.
- * The format and behavior of a constant pool entry with this tag is identical to
- * an entry with a tag of decimal 18, except that the first index refers directly
- * to a {@code CONSTANT_MethodHandle} to use as the bootstrap method.
- * This format does not require the bootstrap method table.
- *
- * <p style="font-size:smaller;">
- * <em>(Note: The Proposed Final Draft of this specification is likely to support
- * only the tag 18, not the tag 17.)</em>
  *
  * <h3><a name="mtcon"></a>constant pool entries for {@linkplain java.dyn.MethodType method types}</h3>
  * If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
  * it must contain exactly two more bytes, which must be an index to a {@code CONSTANT_Utf8}
- * entry which represents a method type signature.
+ * entry which represents a method type descriptor.
  * <p>
  * The JVM will ensure that on first
  * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType MethodType}
- * will be created which represents the signature.
+ * will be created which represents the type descriptor.
  * Any classes mentioned in the {@code MethodType} will be loaded if necessary,
  * but not initialized.
  * Access checking and error reporting is performed exactly as it is for
@@ -141,38 +127,75 @@
  * type is created.  Any classes mentioned in this reification will be loaded if necessary,
  * but not initialized, and access checking and error reporting performed as usual.
  * <p>
+ * Unlike the reflective {@code Lookup} API, there are no security manager calls made
+ * when these constants are resolved.
+ * <p>
  * The method handle itself will have a type and behavior determined by the subtag as follows:
  * <code>
  * <table border=1 cellpadding=5 summary="CONSTANT_MethodHandle subtypes">
- * <tr><th>N</th><th>subtag name</th><th>member</th><th>MH type</th><th>MH behavior</th></tr>
- * <tr><td>1</td><td>REF_getField</td><td>C.f:T</td><td>(C)T</td><td>getfield C.f:T</td></tr>
- * <tr><td>2</td><td>REF_getStatic</td><td>C.f:T</td><td>(&nbsp;)T</td><td>getstatic C.f:T</td></tr>
- * <tr><td>3</td><td>REF_putField</td><td>C.f:T</td><td>(C,T)void</td><td>putfield C.f:T</td></tr>
- * <tr><td>4</td><td>REF_putStatic</td><td>C.f:T</td><td>(T)void</td><td>putstatic C.f:T</td></tr>
- * <tr><td>5</td><td>REF_invokeVirtual</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokevirtual C.m(A*)T</td></tr>
- * <tr><td>6</td><td>REF_invokeStatic</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokestatic C.m(A*)T</td></tr>
- * <tr><td>7</td><td>REF_invokeSpecial</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokespecial C.m(A*)T</td></tr>
- * <tr><td>8</td><td>REF_newInvokeSpecial</td><td>C.&lt;init&gt;(A*)void</td><td>(A*)C</td><td>new C; dup; invokespecial C.&lt;init&gt;(A*)void</td></tr>
- * <tr><td>9</td><td>REF_invokeInterface</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokeinterface C.m(A*)T</td></tr>
+ * <tr><th>N</th><th>subtag name</th><th>member</th><th>MH type</th><th>bytecode behavior</th><th>lookup expression</th></tr>
+ * <tr><td>1</td><td>REF_getField</td><td>C.f:T</td><td>(C)T</td><td>getfield C.f:T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findGetter findGetter(C.class,"f",T.class)}</td></tr>
+ * <tr><td>2</td><td>REF_getStatic</td><td>C.f:T</td><td>(&nbsp;)T</td><td>getstatic C.f:T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticGetter findStaticGetter(C.class,"f",T.class)}</td></tr>
+ * <tr><td>3</td><td>REF_putField</td><td>C.f:T</td><td>(C,T)void</td><td>putfield C.f:T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findSetter findSetter(C.class,"f",T.class)}</td></tr>
+ * <tr><td>4</td><td>REF_putStatic</td><td>C.f:T</td><td>(T)void</td><td>putstatic C.f:T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticSetter findStaticSetter(C.class,"f",T.class)}</td></tr>
+ * <tr><td>5</td><td>REF_invokeVirtual</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokevirtual C.m(A*)T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}</td></tr>
+ * <tr><td>6</td><td>REF_invokeStatic</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokestatic C.m(A*)T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findStatic findStatic(C.class,"m",MT)}</td></tr>
+ * <tr><td>7</td><td>REF_invokeSpecial</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokespecial C.m(A*)T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findSpecial findSpecial(C.class,"m",MT,this.class)}</td></tr>
+ * <tr><td>8</td><td>REF_newInvokeSpecial</td><td>C.&lt;init&gt;(A*)void</td><td>(A*)C</td><td>new C; dup; invokespecial C.&lt;init&gt;(A*)void</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findConstructor findConstructor(C.class,MT)}</td></tr>
+ * <tr><td>9</td><td>REF_invokeInterface</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokeinterface C.m(A*)T</td>
+ *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}</td></tr>
  * </table>
  * </code>
+ * Here, the type {@code C} is taken from the {@code CONSTANT_Class} reference associated
+ * with the {@code CONSTANT_NameAndType} descriptor.
+ * The field name {@code f} or method name {@code m} is taken from the {@code CONSTANT_NameAndType}
+ * as is the result type {@code T} and (in the case of a method or constructor) the argument type sequence
+ * {@code A*}.
+ * <p>
+ * Each method handle constant has an equivalent instruction sequence called its <em>bytecode behavior</em>.
+ * In general, creating a method handle constant can be done in exactly the same circumstances that
+ * the JVM would successfully resolve the symbolic references in the bytecode behavior.
+ * Also, the type of a method handle constant is such that a valid {@code invokeExact} call
+ * on the method handle has exactly the same JVM stack effects as the <em>bytecode behavior</em>.
+ * Finally, calling a method handle constant on a valid set of arguments has exactly the same effect
+ * and returns the same result (if any) as the corresponding <em>bytecode behavior</em>.
+ * <p>
+ * Each method handle constant also has an equivalent reflective <em>lookup expression</em>,
+ * which is a query to a method in {@link java.dyn.MethodHandles.Lookup}.
+ * In the example lookup method expression given in the table above, the name {@code MT}
+ * stands for a {@code MethodType} built from {@code T} and the sequence of argument types {@code A*}.
+ * (Note that the type {@code C} is not prepended to the query type {@code MT} even if the member is non-static.)
+ * In the case of {@code findSpecial}, the name {@code this.class} refers to the class containing
+ * the bytecodes.
  * <p>
  * The special name {@code <clinit>} is not allowed.
  * The special name {@code <init>} is not allowed except for subtag 8 as shown.
  * <p>
  * The JVM verifier and linker apply the same access checks and restrictions for these references as for the hypothetical
- * bytecode instructions specified in the last column of the table.  In particular, method handles to
+ * bytecode instructions specified in the last column of the table.
+ * A method handle constant will successfully resolve to a method handle if the symbolic references
+ * of the corresponding bytecode instruction(s) would also resolve successfully.
+ * Otherwise, an attempt to resolve the constant will throw equivalent linkage errors.
+ * In particular, method handles to
  * private and protected members can be created in exactly those classes for which the corresponding
  * normal accesses are legal.
  * <p>
  * A constant may refer to a method or constructor with the {@code varargs}
- * bit (hexadecimal {@code 80}) set in its modifier bitmask.
- * The method handle constant produced for such a method behaves the same
+ * bit (hexadecimal {@code 0x0080}) set in its modifier bitmask.
+ * The method handle constant produced for such a method behaves as if
+ * it were created by {@link java.dyn.MethodHandle#asVarargsCollector asVarargsCollector}.
+ * In other words, the constant method handle will exhibit variable arity,
+ * when invoked via {@code invokeGeneric}.
+ * On the other hand, its behavior with respect to {@code invokeExact} will be the same
  * as if the {@code varargs} bit were not set.
- * The argument-collecting behavior of {@code varargs} can be emulated by
- * adapting the method handle constant with
- * {@link java.dyn.MethodHandle#asCollector asCollector}.
- * There is no provision for doing this automatically.
  * <p>
  * Although the {@code CONSTANT_MethodHandle} and {@code CONSTANT_MethodType} constant types
  * resolve class names, they do not force class initialization.
@@ -186,14 +209,14 @@
  * by the execution of {@code invokedynamic} and {@code ldc} instructions.
  * (Roughly speaking, this means that every use of a constant pool entry
  * must lead to the same outcome.
- * If the resoultion succeeds, the same object reference is produced
+ * If the resolution succeeds, the same object reference is produced
  * by every subsequent execution of the same instruction.
  * If the resolution of the constant causes an error to occur,
  * the same error will be re-thrown on every subsequent attempt
  * to use this particular constant.)
  * <p>
  * Constants created by the resolution of these constant pool types are not necessarily
- * interned.  Except for {@link CONSTANT_Class} and {@link CONSTANT_String} entries,
+ * interned.  Except for {@code CONSTANT_Class} and {@code CONSTANT_String} entries,
  * two distinct constant pool entries might not resolve to the same reference
  * even if they contain the same symbolic reference.
  *
@@ -207,31 +230,31 @@
  * <p>
  * Each {@code invokedynamic} instruction statically specifies its own
  * bootstrap method as a constant pool reference.
- * The constant pool reference also specifies the call site's name and type signature,
+ * The constant pool reference also specifies the call site's name and type descriptor,
  * just like {@code invokevirtual} and the other invoke instructions.
  * <p>
  * Linking starts with resolving the constant pool entry for the
  * bootstrap method, and resolving a {@link java.dyn.MethodType MethodType} object for
- * the type signature of the dynamic call site.
+ * the type descriptor of the dynamic call site.
  * This resolution process may trigger class loading.
  * It may therefore throw an error if a class fails to load.
  * This error becomes the abnormal termination of the dynamic
  * call site execution.
  * Linkage does not trigger class initialization.
  * <p>
- * Next, the bootstrap method call is started, with four or five values being stacked:
+ * Next, the bootstrap method call is started, with at least four values being stacked:
  * <ul>
  * <li>a {@code MethodHandle}, the resolved bootstrap method itself </li>
  * <li>a {@code MethodHandles.Lookup}, a lookup object on the <em>caller class</em> in which dynamic call site occurs </li>
  * <li>a {@code String}, the method name mentioned in the call site </li>
- * <li>a {@code MethodType}, the resolved type signature of the call </li>
- * <li>optionally, a single object representing one or more <a href="#args">additional static arguments</a> </li>
+ * <li>a {@code MethodType}, the resolved type descriptor of the call </li>
+ * <li>optionally, one or more <a href="#args">additional static arguments</a> </li>
  * </ul>
  * The method handle is then applied to the other values as if by
  * {@link java.dyn.MethodHandle#invokeGeneric invokeGeneric}.
  * The returned result must be a {@link java.dyn.CallSite CallSite} (or a subclass).
  * The type of the call site's target must be exactly equal to the type
- * derived from the dynamic call site signature and passed to
+ * derived from the dynamic call site's type descriptor and passed to
  * the bootstrap method.
  * The call site then becomes permanently linked to the dynamic call site.
  * <p>
@@ -299,11 +322,11 @@
  * chosen target object.
  *
  * <p style="font-size:smaller;">
- * (Historic Note: Unlike some previous versions of this specification,
+ * <em>Historic Note:</em> Unlike some previous versions of this specification,
  * these rules do not enable the JVM to duplicate dynamic call sites,
  * or to issue &ldquo;causeless&rdquo; bootstrap method calls.
  * Every dynamic call site transitions at most once from unlinked to linked,
- * just before its first invocation.)
+ * just before its first invocation.
  *
  * <h3><a name="bsmattr">the {@code BootstrapMethods} attribute </h3>
  * Each {@code CONSTANT_InvokeDynamic} entry contains an index which references
@@ -349,7 +372,6 @@
  * Static arguments are specified constant pool indexes stored in the {@code BootstrapMethods} attribute.
  * Before the bootstrap method is invoked, each index is used to compute an {@code Object}
  * reference to the indexed value in the constant pool.
- * If the value is a primitive type, it is converted to a reference by boxing conversion.
  * The valid constant pool entries are listed in this table:
  * <code>
  * <table border=1 cellpadding=5 summary="Static argument types">
@@ -369,21 +391,43 @@
  * the instruction's bootstrap method will be invoked on three arguments,
  * conveying the instruction's caller class, name, and method type.
  * If the {@code invokedynamic} instruction specifies one or more static arguments,
- * a fourth argument will be passed to the bootstrap argument,
- * either an {@code Object} reference to the sole extra argument (if there is one)
- * or an {@code Object} array of references to all the arguments (if there are two or more),
- * as if the bootstrap method is a variable-arity method.
+ * those values will be passed as additional arguments to the method handle.
+ * (Note that because there is a limit of 255 arguments to any method,
+ * at most 252 extra arguments can be supplied.)
+ * The bootstrap method will be invoked as if by either {@code invokeGeneric}
+ * or {@code invokeWithArguments}.  (There is no way to tell the difference.)
+ * <p>
+ * The normal argument conversion rules for {@code invokeGeneric} apply to all stacked arguments.
+ * For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
+ * If the bootstrap method is a variable arity method (its modifier bit {@code 0x0080} is set),
+ * then some or all of the arguments specified here may be collected into a trailing array parameter.
+ * (This is not a special rule, but rather a useful consequence of the interaction
+ * between {@code CONSTANT_MethodHandle} constants, the modifier bit for variable arity methods,
+ * and the {@code java.dyn.MethodHandle#asVarargsCollector asVarargsCollector} transformation.)
+ * <p>
+ * Given these rules, here are examples of legal bootstrap method declarations,
+ * given various numbers {@code N} of extra arguments.
+ * The first rows (marked {@code *}) will work for any number of extra arguments.
  * <code>
  * <table border=1 cellpadding=5 summary="Static argument types">
  * <tr><th>N</th><th>sample bootstrap method</th></tr>
+ * <tr><td>*</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)</code></td></tr>
+ * <tr><td>*</td><td><code>CallSite bootstrap(Object... args)</code></td></tr>
+ * <tr><td>*</td><td><code>CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)</code></td></tr>
  * <tr><td>0</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type)</code></td></tr>
+ * <tr><td>0</td><td><code>CallSite bootstrap(Lookup caller, Object... nameAndType)</code></td></tr>
  * <tr><td>1</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)</code></td></tr>
  * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)</code></td></tr>
+ * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)</code></td></tr>
+ * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)</code></td></tr>
  * </table>
  * </code>
+ * The last example assumes that the extra arguments are of type
+ * {@code CONSTANT_String} and {@code CONSTANT_Integer}, respectively.
+ * The second-to-last example assumes that all extra arguments are of type
+ * {@code CONSTANT_String}.
+ * The other examples work with all types of extra arguments.
  * <p>
- * The argument and return types listed here are used by the {@code invokeGeneric}
- * call to the bootstrap method.
  * As noted above, the actual method type of the bootstrap method can vary.
  * For example, the fourth argument could be {@code MethodHandle},
  * if that is the type of the corresponding constant in
@@ -391,14 +435,8 @@
  * In that case, the {@code invokeGeneric} call will pass the extra method handle
  * constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric}
  * will cast the reference back to {@code MethodHandle} before invoking the bootstrap method.
- * (If a string constant were passed instead, by badly generated code, that cast would then fail.)
- * <p>
- * If the fourth argument is an array, the array element type must be {@code Object},
- * since object arrays (as produced by the JVM at this point) cannot be converted
- * to other array types.
- * <p>
- * If an array is provided, it will appear to be freshly allocated.
- * That is, the same array will not appear to two bootstrap method calls.
+ * (If a string constant were passed instead, by badly generated code, that cast would then fail,
+ * resulting in an {@code InvokeDynamicBootstrapError}.)
  * <p>
  * Extra bootstrap method arguments are intended to allow language implementors
  * to safely and compactly encode metadata.
@@ -406,24 +444,6 @@
  * since each call site could be given its own unique bootstrap method.
  * Such a practice is likely to produce large class files and constant pools.
  *
- * <p style="font-size:smaller;">
- * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
- * (Usage Note: There is no mechanism for specifying five or more positional arguments to the bootstrap method.
- * If there are two or more arguments, the Java code of the bootstrap method is required to extract them from
- * a varargs-style object array.
- * This design uses varargs because it anticipates some use cases where bootstrap arguments
- * contribute components of variable-length structures, such as virtual function tables
- * or interpreter token streams.
- * Such parameters would be awkward or impossible to manage if represented
- * as normal positional method arguments,
- * since there would need to be one Java method per length.
- * On balance, leaving out the varargs feature would cause more trouble to users than keeping it.
- * Also, this design allows bootstrap methods to be called in a limited JVM stack depth.
- * At both the user and JVM level, the difference between varargs and non-varargs
- * calling sequences can easily be bridged via the
- * {@link java.dyn.MethodHandle#asSpreader asSpreader}
- * and {@link java.dyn.MethodHandle#asSpreader asCollector} methods.)
- *
  * <h2><a name="structs"></a>Structure Summary</h2>
  * <blockquote><pre>// summary of constant and attribute structures
 struct CONSTANT_MethodHandle_info {
@@ -435,11 +455,6 @@
   u1 tag = 16;
   u2 descriptor_index;    // index to CONSTANT_Utf8, as in NameAndType
 }
-struct CONSTANT_InvokeDynamic_17_info {
-  u1 tag = 17;
-  u2 bootstrap_method_index;   // index to CONSTANT_MethodHandle
-  u2 name_and_type_index;      // same as for CONSTANT_Methodref, etc.
-}
 struct CONSTANT_InvokeDynamic_info {
   u1 tag = 18;
   u2 bootstrap_method_attr_index;  // index into BootstrapMethods_attr
@@ -456,9 +471,6 @@
  } bootstrap_methods[bootstrap_method_count];
 }
  * </pre></blockquote>
- * <p>
- * <em>Note: The Proposed Final Draft of JSR 292 may remove the constant tag 17,
- * for the sake of simplicity.</em>
  *
  * @author John Rose, JSR 292 EG
  */
--- a/src/share/classes/java/io/Console.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/io/Console.java	Thu Mar 03 07:02:30 2011 -0800
@@ -308,17 +308,29 @@
         char[] passwd = null;
         synchronized (writeLock) {
             synchronized(readLock) {
-                if (fmt.length() != 0)
-                    pw.format(fmt, args);
                 try {
                     echoOff = echo(false);
+                } catch (IOException x) {
+                    throw new IOError(x);
+                }
+                IOError ioe = null;
+                try {
+                    if (fmt.length() != 0)
+                        pw.format(fmt, args);
                     passwd = readline(true);
                 } catch (IOException x) {
-                    throw new IOError(x);
+                    ioe = new IOError(x);
                 } finally {
                     try {
                         echoOff = echo(true);
-                    } catch (IOException xx) {}
+                    } catch (IOException x) {
+                        if (ioe == null)
+                            ioe = new IOError(x);
+                        else
+                            ioe.addSuppressed(x);
+                    }
+                    if (ioe != null)
+                        throw ioe;
                 }
                 pw.println();
             }
--- a/src/share/classes/java/lang/System.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/lang/System.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1102,6 +1102,18 @@
      * Initialize the system class.  Called after thread initialization.
      */
     private static void initializeSystemClass() {
+
+        // VM might invoke JNU_NewStringPlatform() to set those encoding
+        // sensitive properties (user.home, user.name, boot.class.path, etc.)
+        // during "props" initialization, in which it may need access, via
+        // System.getProperty(), to the related system encoding property that
+        // have been initialized (put into "props") at early stage of the
+        // initialization. So make sure the "props" is available at the
+        // very beginning of the initialization and all system properties to
+        // be put into it directly.
+        props = new Properties();
+        initProperties(props);  // initialized by the VM
+
         // There are certain system configurations that may be controlled by
         // VM options such as the maximum amount of direct memory and
         // Integer cache size used to support the object identity semantics
@@ -1112,7 +1124,12 @@
         //
         // See java.lang.Integer.IntegerCache and the
         // sun.misc.VM.saveAndRemoveProperties method for example.
-        props = initSystemProperties();
+        //
+        // Save a private copy of the system properties object that
+        // can only be accessed by the internal implementation.  Remove
+        // certain system properties that are not intended for public access.
+        sun.misc.VM.saveAndRemoveProperties(props);
+
 
         lineSeparator = props.getProperty("line.separator");
         sun.misc.Version.init();
@@ -1123,7 +1140,6 @@
         setIn0(new BufferedInputStream(fdIn));
         setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
         setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
-
         // Load the zip library now in order to keep java.util.zip.ZipFile
         // from trying to use itself to load this library later.
         loadLibrary("zip");
@@ -1151,18 +1167,6 @@
         setJavaLangAccess();
     }
 
-    private static Properties initSystemProperties() {
-        Properties props = new Properties();
-        initProperties(props);  // initialized by the VM
-
-        // Save a private copy of the system properties object that
-        // can only be accessed by the internal implementation.  Remove
-        // certain system properties that are not intended for public access.
-        sun.misc.VM.saveAndRemoveProperties(props);
-
-        return props;
-    }
-
     private static void setJavaLangAccess() {
         // Allow privileged classes outside of java.lang
         sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
--- a/src/share/classes/java/lang/Thread.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/lang/Thread.java	Thu Mar 03 07:02:30 2011 -0800
@@ -254,12 +254,6 @@
      */
     public final static int MAX_PRIORITY = 10;
 
-    /* If stop was called before start */
-    private boolean stopBeforeStart;
-
-    /* Remembered Throwable from stop before start */
-    private Throwable throwableFromStop;
-
     /**
      * Returns a reference to the currently executing thread object.
      *
@@ -706,10 +700,6 @@
                   it will be passed up the call stack */
             }
         }
-
-        if (stopBeforeStart) {
-            stop0(throwableFromStop);
-        }
     }
 
     private native void start0();
@@ -820,12 +810,7 @@
      */
     @Deprecated
     public final void stop() {
-        // If the thread is already dead, return.
-        // A zero status value corresponds to "NEW".
-        if ((threadStatus != 0) && !isAlive()) {
-            return;
-        }
-        stop1(new ThreadDeath());
+        stop(new ThreadDeath());
     }
 
     /**
@@ -879,36 +864,25 @@
      */
     @Deprecated
     public final synchronized void stop(Throwable obj) {
-        stop1(obj);
-    }
+        if (obj == null)
+            throw new NullPointerException();
 
-    /**
-     * Common impl for stop() and stop(Throwable).
-     */
-    private final synchronized void stop1(Throwable th) {
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             checkAccess();
             if ((this != Thread.currentThread()) ||
-                (!(th instanceof ThreadDeath))) {
+                (!(obj instanceof ThreadDeath))) {
                 security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
             }
         }
-        // A zero status value corresponds to "NEW"
+        // A zero status value corresponds to "NEW", it can't change to
+        // not-NEW because we hold the lock.
         if (threadStatus != 0) {
             resume(); // Wake up thread if it was suspended; no-op otherwise
-            stop0(th);
-        } else {
+        }
 
-            // Must do the null arg check that the VM would do with stop0
-            if (th == null) {
-                throw new NullPointerException();
-            }
-
-            // Remember this stop attempt for if/when start is used
-            stopBeforeStart = true;
-            throwableFromStop = th;
-        }
+        // The VM can handle all thread states
+        stop0(obj);
     }
 
     /**
--- a/src/share/classes/java/util/Hashtable.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/util/Hashtable.java	Thu Mar 03 07:02:30 2011 -0800
@@ -845,24 +845,36 @@
      *             for each key-value mapping represented by the Hashtable
      *             The key-value mappings are emitted in no particular order.
      */
-    private synchronized void writeObject(java.io.ObjectOutputStream s)
-        throws IOException
-    {
-        // Write out the length, threshold, loadfactor
-        s.defaultWriteObject();
+    private void writeObject(java.io.ObjectOutputStream s)
+            throws IOException {
+        Entry<Object, Object> entryStack = null;
 
-        // Write out length, count of elements and then the key/value objects
-        s.writeInt(table.length);
-        s.writeInt(count);
-        for (int index = table.length-1; index >= 0; index--) {
-            Entry entry = table[index];
+        synchronized (this) {
+            // Write out the length, threshold, loadfactor
+            s.defaultWriteObject();
 
-            while (entry != null) {
-                s.writeObject(entry.key);
-                s.writeObject(entry.value);
-                entry = entry.next;
+            // Write out length, count of elements
+            s.writeInt(table.length);
+            s.writeInt(count);
+
+            // Stack copies of the entries in the table
+            for (int index = 0; index < table.length; index++) {
+                Entry entry = table[index];
+
+                while (entry != null) {
+                    entryStack =
+                        new Entry<>(0, entry.key, entry.value, entryStack);
+                    entry = entry.next;
+                }
             }
         }
+
+        // Write out the key/value objects from the stacked entries
+        while (entryStack != null) {
+            s.writeObject(entryStack.key);
+            s.writeObject(entryStack.value);
+            entryStack = entryStack.next;
+        }
     }
 
     /**
--- a/src/share/classes/java/util/SimpleTimeZone.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/util/SimpleTimeZone.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, 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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -825,10 +825,7 @@
      * @since 1.2
      */
     public int getDSTSavings() {
-        if (useDaylight) {
-            return dstSavings;
-        }
-        return 0;
+        return useDaylight ? dstSavings : 0;
     }
 
     /**
@@ -842,6 +839,20 @@
     }
 
     /**
+     * Returns {@code true} if this {@code SimpleTimeZone} observes
+     * Daylight Saving Time. This method is equivalent to {@link
+     * #useDaylightTime()}.
+     *
+     * @return {@code true} if this {@code SimpleTimeZone} observes
+     * Daylight Saving Time; {@code false} otherwise.
+     * @since 1.7
+     */
+    @Override
+    public boolean observesDaylightTime() {
+        return useDaylightTime();
+    }
+
+    /**
      * Queries if the given date is in daylight saving time.
      * @return true if daylight saving time is in effective at the
      * given date; false otherwise.
--- a/src/share/classes/java/util/TimeZone.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/util/TimeZone.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -455,17 +455,28 @@
     /**
      * Returns the amount of time to be added to local standard time
      * to get local wall clock time.
-     * <p>
-     * The default implementation always returns 3600000 milliseconds
-     * (i.e., one hour) if this time zone observes Daylight Saving
-     * Time. Otherwise, 0 (zero) is returned.
-     * <p>
-     * If an underlying TimeZone implementation subclass supports
-     * historical Daylight Saving Time changes, this method returns
-     * the known latest daylight saving value.
+     *
+     * <p>The default implementation returns 3600000 milliseconds
+     * (i.e., one hour) if a call to {@link #useDaylightTime()}
+     * returns {@code true}. Otherwise, 0 (zero) is returned.
+     *
+     * <p>If an underlying {@code TimeZone} implementation subclass
+     * supports historical and future Daylight Saving Time schedule
+     * changes, this method returns the amount of saving time of the
+     * last known Daylight Saving Time rule that can be a future
+     * prediction.
+     *
+     * <p>If the amount of saving time at any given time stamp is
+     * required, construct a {@link Calendar} with this {@code
+     * TimeZone} and the time stamp, and call {@link Calendar#get(int)
+     * Calendar.get}{@code (}{@link Calendar#DST_OFFSET}{@code )}.
      *
      * @return the amount of saving time in milliseconds
      * @since 1.4
+     * @see #inDaylightTime(Date)
+     * @see #getOffset(long)
+     * @see #getOffset(int,int,int,int,int,int)
+     * @see Calendar#ZONE_OFFSET
      */
     public int getDSTSavings() {
         if (useDaylightTime()) {
@@ -475,24 +486,51 @@
     }
 
     /**
-     * Queries if this time zone uses daylight savings time.
-     * <p>
-     * If an underlying <code>TimeZone</code> implementation subclass
-     * supports historical Daylight Saving Time schedule changes, the
-     * method refers to the latest Daylight Saving Time schedule
-     * information.
+     * Queries if this {@code TimeZone} uses Daylight Saving Time.
      *
-     * @return true if this time zone uses daylight savings time,
-     * false, otherwise.
+     * <p>If an underlying {@code TimeZone} implementation subclass
+     * supports historical and future Daylight Saving Time schedule
+     * changes, this method refers to the last known Daylight Saving Time
+     * rule that can be a future prediction and may not be the same as
+     * the current rule. Consider calling {@link #observesDaylightTime()}
+     * if the current rule should also be taken into account.
+     *
+     * @return {@code true} if this {@code TimeZone} uses Daylight Saving Time,
+     *         {@code false}, otherwise.
+     * @see #inDaylightTime(Date)
+     * @see Calendar#DST_OFFSET
      */
     public abstract boolean useDaylightTime();
 
     /**
-     * Queries if the given date is in daylight savings time in
-     * this time zone.
-     * @param date the given Date.
-     * @return true if the given date is in daylight savings time,
-     * false, otherwise.
+     * Returns {@code true} if this {@code TimeZone} is currently in
+     * Daylight Saving Time, or if a transition from Standard Time to
+     * Daylight Saving Time occurs at any future time.
+     *
+     * <p>The default implementation returns {@code true} if
+     * {@code useDaylightTime()} or {@code inDaylightTime(new Date())}
+     * returns {@code true}.
+     *
+     * @return {@code true} if this {@code TimeZone} is currently in
+     * Daylight Saving Time, or if a transition from Standard Time to
+     * Daylight Saving Time occurs at any future time; {@code false}
+     * otherwise.
+     * @since 1.7
+     * @see #useDaylightTime()
+     * @see #inDaylightTime(Date)
+     * @see Calendar#DST_OFFSET
+     */
+    public boolean observesDaylightTime() {
+        return useDaylightTime() || inDaylightTime(new Date());
+    }
+
+    /**
+     * Queries if the given {@code date} is in Daylight Saving Time in
+     * this {@code TimeZone}.
+     *
+     * @param date the given {@code Date}.
+     * @return {@code true} if the given {@code date} is in Daylight Saving Time,
+     *         {@code false}, otherwise.
      */
     abstract public boolean inDaylightTime(Date date);
 
--- a/src/share/classes/java/util/Vector.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/util/Vector.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1050,13 +1050,21 @@
 
     /**
      * Save the state of the {@code Vector} instance to a stream (that
-     * is, serialize it).  This method is present merely for synchronization.
-     * It just calls the default writeObject method.
+     * is, serialize it).
+     * This method performs synchronization to ensure the consistency
+     * of the serialized data.
      */
-    private synchronized void writeObject(java.io.ObjectOutputStream s)
-        throws java.io.IOException
-    {
-        s.defaultWriteObject();
+    private void writeObject(java.io.ObjectOutputStream s)
+            throws java.io.IOException {
+        final java.io.ObjectOutputStream.PutField fields = s.putFields();
+        final Object[] data;
+        synchronized (this) {
+            fields.put("capacityIncrement", capacityIncrement);
+            fields.put("elementCount", elementCount);
+            data = elementData.clone();
+        }
+        fields.put("elementData", data);
+        s.writeFields();
     }
 
     /**
--- a/src/share/classes/java/util/jar/JarFile.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/util/jar/JarFile.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,11 +27,13 @@
 
 import java.io.*;
 import java.lang.ref.SoftReference;
+import java.net.URL;
 import java.util.*;
 import java.util.zip.*;
 import java.security.CodeSigner;
 import java.security.cert.Certificate;
 import java.security.AccessController;
+import java.security.CodeSource;
 import sun.security.action.GetPropertyAction;
 import sun.security.util.ManifestEntryVerifier;
 import sun.misc.SharedSecrets;
@@ -262,7 +264,7 @@
                 throw new RuntimeException(e);
             }
             if (certs == null && jv != null) {
-                certs = jv.getCerts(getName());
+                certs = jv.getCerts(JarFile.this, this);
             }
             return certs == null ? null : certs.clone();
         }
@@ -273,7 +275,7 @@
                 throw new RuntimeException(e);
             }
             if (signers == null && jv != null) {
-                signers = jv.getCodeSigners(getName());
+                signers = jv.getCodeSigners(JarFile.this, this);
             }
             return signers == null ? null : signers.clone();
         }
@@ -544,4 +546,191 @@
         }
         return false;
     }
+
+    private synchronized void ensureInitialization() {
+        try {
+            maybeInstantiateVerifier();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        if (jv != null && !jvInitialized) {
+            initializeVerifier();
+            jvInitialized = true;
+        }
+    }
+
+    JarEntry newEntry(ZipEntry ze) {
+        return new JarFileEntry(ze);
+    }
+
+    Enumeration<String> entryNames(CodeSource[] cs) {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.entryNames(this, cs);
+        }
+
+        /*
+         * JAR file has no signed content. Is there a non-signing
+         * code source?
+         */
+        boolean includeUnsigned = false;
+        for (int i = 0; i < cs.length; i++) {
+            if (cs[i].getCodeSigners() == null) {
+                includeUnsigned = true;
+                break;
+            }
+        }
+        if (includeUnsigned) {
+            return unsignedEntryNames();
+        } else {
+            return new Enumeration<String>() {
+
+                public boolean hasMoreElements() {
+                    return false;
+                }
+
+                public String nextElement() {
+                    throw new NoSuchElementException();
+                }
+            };
+        }
+    }
+
+    /**
+     * Returns an enumeration of the zip file entries
+     * excluding internal JAR mechanism entries and including
+     * signed entries missing from the ZIP directory.
+     */
+    Enumeration<JarEntry> entries2() {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.entries2(this, super.entries());
+        }
+
+        // screen out entries which are never signed
+        final Enumeration enum_ = super.entries();
+        return new Enumeration<JarEntry>() {
+
+            ZipEntry entry;
+
+            public boolean hasMoreElements() {
+                if (entry != null) {
+                    return true;
+                }
+                while (enum_.hasMoreElements()) {
+                    ZipEntry ze = (ZipEntry) enum_.nextElement();
+                    if (JarVerifier.isSigningRelated(ze.getName())) {
+                        continue;
+                    }
+                    entry = ze;
+                    return true;
+                }
+                return false;
+            }
+
+            public JarFileEntry nextElement() {
+                if (hasMoreElements()) {
+                    ZipEntry ze = entry;
+                    entry = null;
+                    return new JarFileEntry(ze);
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+
+    CodeSource[] getCodeSources(URL url) {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.getCodeSources(this, url);
+        }
+
+        /*
+         * JAR file has no signed content. Is there a non-signing
+         * code source?
+         */
+        Enumeration unsigned = unsignedEntryNames();
+        if (unsigned.hasMoreElements()) {
+            return new CodeSource[]{JarVerifier.getUnsignedCS(url)};
+        } else {
+            return null;
+        }
+    }
+
+    private Enumeration<String> unsignedEntryNames() {
+        final Enumeration entries = entries();
+        return new Enumeration<String>() {
+
+            String name;
+
+            /*
+             * Grab entries from ZIP directory but screen out
+             * metadata.
+             */
+            public boolean hasMoreElements() {
+                if (name != null) {
+                    return true;
+                }
+                while (entries.hasMoreElements()) {
+                    String value;
+                    ZipEntry e = (ZipEntry) entries.nextElement();
+                    value = e.getName();
+                    if (e.isDirectory() || JarVerifier.isSigningRelated(value)) {
+                        continue;
+                    }
+                    name = value;
+                    return true;
+                }
+                return false;
+            }
+
+            public String nextElement() {
+                if (hasMoreElements()) {
+                    String value = name;
+                    name = null;
+                    return value;
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+
+    CodeSource getCodeSource(URL url, String name) {
+        ensureInitialization();
+        if (jv != null) {
+            if (jv.eagerValidation) {
+                CodeSource cs = null;
+                JarEntry je = getJarEntry(name);
+                if (je != null) {
+                    cs = jv.getCodeSource(url, this, je);
+                } else {
+                    cs = jv.getCodeSource(url, name);
+                }
+                return cs;
+            } else {
+                return jv.getCodeSource(url, name);
+            }
+        }
+
+        return JarVerifier.getUnsignedCS(url);
+    }
+
+    void setEagerValidation(boolean eager) {
+        try {
+            maybeInstantiateVerifier();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        if (jv != null) {
+            jv.setEagerValidation(eager);
+        }
+    }
+
+    List getManifestDigests() {
+        ensureInitialization();
+        if (jv != null) {
+            return jv.getManifestDigests();
+        }
+        return new ArrayList();
+    }
 }
--- a/src/share/classes/java/util/jar/JarVerifier.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/util/jar/JarVerifier.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,11 @@
 package java.util.jar;
 
 import java.io.*;
+import java.net.URL;
 import java.util.*;
 import java.security.*;
 import java.security.cert.CertificateException;
+import java.util.zip.ZipEntry;
 
 import sun.security.util.ManifestDigester;
 import sun.security.util.ManifestEntryVerifier;
@@ -81,6 +83,15 @@
     /** the bytes for the manDig object */
     byte manifestRawBytes[] = null;
 
+    /** controls eager signature validation */
+    boolean eagerValidation;
+
+    /** makes code source singleton instances unique to us */
+    private Object csdomain = new Object();
+
+    /** collect -DIGEST-MANIFEST values for blacklist */
+    private List manifestDigests;
+
     public JarVerifier(byte rawBytes[]) {
         manifestRawBytes = rawBytes;
         sigFileSigners = new Hashtable();
@@ -88,6 +99,7 @@
         sigFileData = new Hashtable(11);
         pendingBlocks = new ArrayList();
         baos = new ByteArrayOutputStream();
+        manifestDigests = new ArrayList();
     }
 
     /**
@@ -247,7 +259,7 @@
                             }
 
                             sfv.setSignatureFile(bytes);
-                            sfv.process(sigFileSigners);
+                            sfv.process(sigFileSigners, manifestDigests);
                         }
                     }
                     return;
@@ -290,7 +302,7 @@
                         sfv.setSignatureFile(bytes);
                     }
                 }
-                sfv.process(sigFileSigners);
+                sfv.process(sigFileSigners, manifestDigests);
 
             } catch (IOException ioe) {
                 // e.g. sun.security.pkcs.ParsingException
@@ -312,12 +324,18 @@
     /**
      * Return an array of java.security.cert.Certificate objects for
      * the given file in the jar.
+     * @deprecated
      */
     public java.security.cert.Certificate[] getCerts(String name)
     {
         return mapSignersToCertArray(getCodeSigners(name));
     }
 
+    public java.security.cert.Certificate[] getCerts(JarFile jar, JarEntry entry)
+    {
+        return mapSignersToCertArray(getCodeSigners(jar, entry));
+    }
+
     /**
      * return an array of CodeSigner objects for
      * the given file in the jar. this array is not cloned.
@@ -328,6 +346,28 @@
         return (CodeSigner[])verifiedSigners.get(name);
     }
 
+    public CodeSigner[] getCodeSigners(JarFile jar, JarEntry entry)
+    {
+        String name = entry.getName();
+        if (eagerValidation && sigFileSigners.get(name) != null) {
+            /*
+             * Force a read of the entry data to generate the
+             * verification hash.
+             */
+            try {
+                InputStream s = jar.getInputStream(entry);
+                byte[] buffer = new byte[1024];
+                int n = buffer.length;
+                while (n != -1) {
+                    n = s.read(buffer, 0, buffer.length);
+                }
+                s.close();
+            } catch (IOException e) {
+            }
+        }
+        return getCodeSigners(name);
+    }
+
     /*
      * Convert an array of signers into an array of concatenated certificate
      * arrays.
@@ -444,4 +484,393 @@
         }
 
     }
+
+    // Extended JavaUtilJarAccess CodeSource API Support
+
+    private Map urlToCodeSourceMap = new HashMap();
+    private Map signerToCodeSource = new HashMap();
+    private URL lastURL;
+    private Map lastURLMap;
+
+    /*
+     * Create a unique mapping from codeSigner cache entries to CodeSource.
+     * In theory, multiple URLs origins could map to a single locally cached
+     * and shared JAR file although in practice there will be a single URL in use.
+     */
+    private synchronized CodeSource mapSignersToCodeSource(URL url, CodeSigner[] signers) {
+        Map map;
+        if (url == lastURL) {
+            map = lastURLMap;
+        } else {
+            map = (Map) urlToCodeSourceMap.get(url);
+            if (map == null) {
+                map = new HashMap();
+                urlToCodeSourceMap.put(url, map);
+            }
+            lastURLMap = map;
+            lastURL = url;
+        }
+        CodeSource cs = (CodeSource) map.get(signers);
+        if (cs == null) {
+            cs = new VerifierCodeSource(csdomain, url, signers);
+            signerToCodeSource.put(signers, cs);
+        }
+        return cs;
+    }
+
+    private CodeSource[] mapSignersToCodeSources(URL url, List signers, boolean unsigned) {
+        List sources = new ArrayList();
+
+        for (int i = 0; i < signers.size(); i++) {
+            sources.add(mapSignersToCodeSource(url, (CodeSigner[]) signers.get(i)));
+        }
+        if (unsigned) {
+            sources.add(mapSignersToCodeSource(url, null));
+        }
+        return (CodeSource[]) sources.toArray(new CodeSource[sources.size()]);
+    }
+    private CodeSigner[] emptySigner = new CodeSigner[0];
+
+    /*
+     * Match CodeSource to a CodeSigner[] in the signer cache.
+     */
+    private CodeSigner[] findMatchingSigners(CodeSource cs) {
+        if (cs instanceof VerifierCodeSource) {
+            VerifierCodeSource vcs = (VerifierCodeSource) cs;
+            if (vcs.isSameDomain(csdomain)) {
+                return ((VerifierCodeSource) cs).getPrivateSigners();
+            }
+        }
+
+        /*
+         * In practice signers should always be optimized above
+         * but this handles a CodeSource of any type, just in case.
+         */
+        CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
+        List sourceList = new ArrayList();
+        for (int i = 0; i < sources.length; i++) {
+            sourceList.add(sources[i]);
+        }
+        int j = sourceList.indexOf(cs);
+        if (j != -1) {
+            CodeSigner[] match;
+            match = ((VerifierCodeSource) sourceList.get(j)).getPrivateSigners();
+            if (match == null) {
+                match = emptySigner;
+            }
+            return match;
+        }
+        return null;
+    }
+
+    /*
+     * Instances of this class hold uncopied references to internal
+     * signing data that can be compared by object reference identity.
+     */
+    private static class VerifierCodeSource extends CodeSource {
+
+        URL vlocation;
+        CodeSigner[] vsigners;
+        java.security.cert.Certificate[] vcerts;
+        Object csdomain;
+
+        VerifierCodeSource(Object csdomain, URL location, CodeSigner[] signers) {
+            super(location, signers);
+            this.csdomain = csdomain;
+            vlocation = location;
+            vsigners = signers; // from signerCache
+        }
+
+        VerifierCodeSource(Object csdomain, URL location, java.security.cert.Certificate[] certs) {
+            super(location, certs);
+            this.csdomain = csdomain;
+            vlocation = location;
+            vcerts = certs; // from signerCache
+        }
+
+        /*
+         * All VerifierCodeSource instances are constructed based on
+         * singleton signerCache or signerCacheCert entries for each unique signer.
+         * No CodeSigner<->Certificate[] conversion is required.
+         * We use these assumptions to optimize equality comparisons.
+         */
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof VerifierCodeSource) {
+                VerifierCodeSource that = (VerifierCodeSource) obj;
+
+                /*
+                 * Only compare against other per-signer singletons constructed
+                 * on behalf of the same JarFile instance. Otherwise, compare
+                 * things the slower way.
+                 */
+                if (isSameDomain(that.csdomain)) {
+                    if (that.vsigners != this.vsigners
+                            || that.vcerts != this.vcerts) {
+                        return false;
+                    }
+                    if (that.vlocation != null) {
+                        return that.vlocation.equals(this.vlocation);
+                    } else if (this.vlocation != null) {
+                        return this.vlocation.equals(that.vlocation);
+                    } else { // both null
+                        return true;
+                    }
+                }
+            }
+            return super.equals(obj);
+        }
+
+        boolean isSameDomain(Object csdomain) {
+            return this.csdomain == csdomain;
+        }
+
+        private CodeSigner[] getPrivateSigners() {
+            return vsigners;
+        }
+
+        private java.security.cert.Certificate[] getPrivateCertificates() {
+            return vcerts;
+        }
+    }
+    private Map signerMap;
+
+    private synchronized Map signerMap() {
+        if (signerMap == null) {
+            /*
+             * Snapshot signer state so it doesn't change on us. We care
+             * only about the asserted signatures. Verification of
+             * signature validity happens via the JarEntry apis.
+             */
+            signerMap = new HashMap(verifiedSigners.size() + sigFileSigners.size());
+            signerMap.putAll(verifiedSigners);
+            signerMap.putAll(sigFileSigners);
+        }
+        return signerMap;
+    }
+
+    public synchronized Enumeration<String> entryNames(JarFile jar, final CodeSource[] cs) {
+        final Map map = signerMap();
+        final Iterator itor = map.entrySet().iterator();
+        boolean matchUnsigned = false;
+
+        /*
+         * Grab a single copy of the CodeSigner arrays. Check
+         * to see if we can optimize CodeSigner equality test.
+         */
+        List req = new ArrayList(cs.length);
+        for (int i = 0; i < cs.length; i++) {
+            CodeSigner[] match = findMatchingSigners(cs[i]);
+            if (match != null) {
+                if (match.length > 0) {
+                    req.add(match);
+                } else {
+                    matchUnsigned = true;
+                }
+            }
+        }
+
+        final List signersReq = req;
+        final Enumeration enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration;
+
+        return new Enumeration<String>() {
+
+            String name;
+
+            public boolean hasMoreElements() {
+                if (name != null) {
+                    return true;
+                }
+
+                while (itor.hasNext()) {
+                    Map.Entry e = (Map.Entry) itor.next();
+                    if (signersReq.contains((CodeSigner[]) e.getValue())) {
+                        name = (String) e.getKey();
+                        return true;
+                    }
+                }
+                while (enum2.hasMoreElements()) {
+                    name = (String) enum2.nextElement();
+                    return true;
+                }
+                return false;
+            }
+
+            public String nextElement() {
+                if (hasMoreElements()) {
+                    String value = name;
+                    name = null;
+                    return value;
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+
+    /*
+     * Like entries() but screens out internal JAR mechanism entries
+     * and includes signed entries with no ZIP data.
+     */
+    public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration e) {
+        final Map map = new HashMap();
+        map.putAll(signerMap());
+        final Enumeration enum_ = e;
+        return new Enumeration<JarEntry>() {
+
+            Enumeration signers = null;
+            JarEntry entry;
+
+            public boolean hasMoreElements() {
+                if (entry != null) {
+                    return true;
+                }
+                while (enum_.hasMoreElements()) {
+                    ZipEntry ze = (ZipEntry) enum_.nextElement();
+                    if (JarVerifier.isSigningRelated(ze.getName())) {
+                        continue;
+                    }
+                    entry = jar.newEntry(ze);
+                    return true;
+                }
+                if (signers == null) {
+                    signers = Collections.enumeration(map.keySet());
+                }
+                while (signers.hasMoreElements()) {
+                    String name = (String) signers.nextElement();
+                    entry = jar.newEntry(new ZipEntry(name));
+                    return true;
+                }
+
+                // Any map entries left?
+                return false;
+            }
+
+            public JarEntry nextElement() {
+                if (hasMoreElements()) {
+                    JarEntry je = entry;
+                    map.remove(je.getName());
+                    entry = null;
+                    return je;
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+    private Enumeration emptyEnumeration = new Enumeration<String>() {
+
+        public boolean hasMoreElements() {
+            return false;
+        }
+
+        public String nextElement() {
+            throw new NoSuchElementException();
+        }
+    };
+
+    // true if file is part of the signature mechanism itself
+    static boolean isSigningRelated(String name) {
+        name = name.toUpperCase(Locale.ENGLISH);
+        if (!name.startsWith("META-INF/")) {
+            return false;
+        }
+        name = name.substring(9);
+        if (name.indexOf('/') != -1) {
+            return false;
+        }
+        if (name.endsWith(".DSA")
+                || name.endsWith(".RSA")
+                || name.endsWith(".SF")
+                || name.endsWith(".EC")
+                || name.startsWith("SIG-")
+                || name.equals("MANIFEST.MF")) {
+            return true;
+        }
+        return false;
+    }
+
+    private Enumeration<String> unsignedEntryNames(JarFile jar) {
+        final Map map = signerMap();
+        final Enumeration entries = jar.entries();
+        return new Enumeration<String>() {
+
+            String name;
+
+            /*
+             * Grab entries from ZIP directory but screen out
+             * metadata.
+             */
+            public boolean hasMoreElements() {
+                if (name != null) {
+                    return true;
+                }
+                while (entries.hasMoreElements()) {
+                    String value;
+                    ZipEntry e = (ZipEntry) entries.nextElement();
+                    value = e.getName();
+                    if (e.isDirectory() || isSigningRelated(value)) {
+                        continue;
+                    }
+                    if (map.get(value) == null) {
+                        name = value;
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            public String nextElement() {
+                if (hasMoreElements()) {
+                    String value = name;
+                    name = null;
+                    return value;
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+    private List jarCodeSigners;
+
+    private synchronized List getJarCodeSigners() {
+        CodeSigner[] signers;
+        if (jarCodeSigners == null) {
+            HashSet set = new HashSet();
+            set.addAll(signerMap().values());
+            jarCodeSigners = new ArrayList();
+            jarCodeSigners.addAll(set);
+        }
+        return jarCodeSigners;
+    }
+
+    public synchronized CodeSource[] getCodeSources(JarFile jar, URL url) {
+        boolean hasUnsigned = unsignedEntryNames(jar).hasMoreElements();
+
+        return mapSignersToCodeSources(url, getJarCodeSigners(), hasUnsigned);
+    }
+
+    public CodeSource getCodeSource(URL url, String name) {
+        CodeSigner[] signers;
+
+        signers = (CodeSigner[]) signerMap().get(name);
+        return mapSignersToCodeSource(url, signers);
+    }
+
+    public CodeSource getCodeSource(URL url, JarFile jar, JarEntry je) {
+        CodeSigner[] signers;
+
+        return mapSignersToCodeSource(url, getCodeSigners(jar, je));
+    }
+
+    public void setEagerValidation(boolean eager) {
+        eagerValidation = eager;
+    }
+
+    public synchronized List getManifestDigests() {
+        return Collections.unmodifiableList(manifestDigests);
+    }
+
+    static CodeSource getUnsignedCS(URL url) {
+        return new VerifierCodeSource(null, url, (java.security.cert.Certificate[]) null);
+    }
 }
--- a/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,38 @@
 package java.util.jar;
 
 import java.io.IOException;
+import java.net.URL;
+import java.security.CodeSource;
+import java.util.Enumeration;
+import java.util.List;
 import sun.misc.JavaUtilJarAccess;
 
 class JavaUtilJarAccessImpl implements JavaUtilJarAccess {
     public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException {
         return jar.hasClassPathAttribute();
     }
+
+    public CodeSource[] getCodeSources(JarFile jar, URL url) {
+        return jar.getCodeSources(url);
+    }
+
+    public CodeSource getCodeSource(JarFile jar, URL url, String name) {
+        return jar.getCodeSource(url, name);
+    }
+
+    public Enumeration<String> entryNames(JarFile jar, CodeSource[] cs) {
+        return jar.entryNames(cs);
+    }
+
+    public Enumeration<JarEntry> entries2(JarFile jar) {
+        return jar.entries2();
+    }
+
+    public void setEagerValidation(JarFile jar, boolean eager) {
+        jar.setEagerValidation(eager);
+    }
+
+    public List getManifestDigests(JarFile jar) {
+        return jar.getManifestDigests();
+    }
 }
--- a/src/share/classes/javax/script/ScriptEngineFactory.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/script/ScriptEngineFactory.java	Thu Mar 03 07:02:30 2011 -0800
@@ -115,20 +115,19 @@
      * with respect to concurrent execution of scripts and maintenance of state is also defined.
      * These values for the <code><b>THREADING</b></code> key are:<br><br>
      * <ul>
-     * <p><code>null</code> - The engine implementation is not thread safe, and cannot
+     * <li><code>null</code> - The engine implementation is not thread safe, and cannot
      * be used to execute scripts concurrently on multiple threads.
-     * <p><code>&quot;MULTITHREADED&quot;</code> - The engine implementation is internally
+     * <li><code>&quot;MULTITHREADED&quot;</code> - The engine implementation is internally
      * thread-safe and scripts may execute concurrently although effects of script execution
      * on one thread may be visible to scripts on other threads.
-     * <p><code>&quot;THREAD-ISOLATED&quot;</code> - The implementation satisfies the requirements
+     * <li><code>&quot;THREAD-ISOLATED&quot;</code> - The implementation satisfies the requirements
      * of &quot;MULTITHREADED&quot;, and also, the engine maintains independent values
      * for symbols in scripts executing on different threads.
-     * <p><code>&quot;STATELESS&quot;</code> - The implementation satisfies the requirements of
-     * <code>&quot;THREAD-ISOLATED&quot;</code>.  In addition, script executions do not alter the
+     * <li><code>&quot;STATELESS&quot;</code> - The implementation satisfies the requirements of
+     * <li><code>&quot;THREAD-ISOLATED&quot;</code>.  In addition, script executions do not alter the
      * mappings in the <code>Bindings</code> which is the engine scope of the
      * <code>ScriptEngine</code>.  In particular, the keys in the <code>Bindings</code>
      * and their associated values are the same before and after the execution of the script.
-     * </li>
      * </ul>
      * <br><br>
      * Implementations may define implementation-specific keys.
@@ -145,22 +144,23 @@
      * of the supported scripting language.  For instance, an implementaton for a Javascript
      * engine might be;
      * <p>
-     * <code><pre>
+     * <pre>
+     * <code>
      * public String getMethodCallSyntax(String obj,
      *                                   String m, String... args) {
      *      String ret = obj;
      *      ret += "." + m + "(";
      *      for (int i = 0; i < args.length; i++) {
      *          ret += args[i];
-     *          if (i == args.length - 1) {
-     *              ret += ")";
-     *          } else {
+     *          if (i < args.length - 1) {
      *              ret += ",";
      *          }
      *      }
+     *      ret += ")";
      *      return ret;
      * }
-     *</pre></code>
+     *</code>
+     *</pre>
      * <p>
      *
      * @param obj The name representing the object whose method is to be invoked. The
--- a/src/share/classes/javax/sound/sampled/AudioSystem.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/sound/sampled/AudioSystem.java	Thu Mar 03 07:02:30 2011 -0800
@@ -670,6 +670,12 @@
      * <p>The returned <code>TargetDataLine</code>'s default
      * audio format will be initialized with <code>format</code>.
      *
+     * <p>If the system property
+     * {@code javax.sound.sampled.TargetDataLine}
+     * is defined or it is defined in the file &quot;sound.properties&quot;,
+     * it is used to retrieve the default target data line.
+     * For details, refer to the {@link AudioSystem class description}.
+     *
      * @param format an <code>AudioFormat</code> object specifying
      *        the supported audio format of the returned line,
      *        or <code>null</code> for any audio format
@@ -712,12 +718,6 @@
      * <p>The returned <code>TargetDataLine</code>'s default
      * audio format will be initialized with <code>format</code>.
      *
-     * <p>If the system property
-     * <code>javax.sound.sampled.TargetDataLine</code>
-     * is defined or it is defined in the file &quot;sound.properties&quot;,
-     * it is used to retrieve the default target data line.
-     * For details, refer to the {@link AudioSystem class description}.
-     *
      * @param format an <code>AudioFormat</code> object specifying
      *        the supported audio format of the returned line,
      *        or <code>null</code> for any audio format
--- a/src/share/classes/javax/sql/rowset/serial/SerialClob.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/sql/rowset/serial/SerialClob.java	Thu Mar 03 07:02:30 2011 -0800
@@ -57,10 +57,10 @@
     private char buf[];
 
     /**
-     * Internal Clob representation if SerialClob is intialized with a
-     * Clob
+     * Internal Clob representation if SerialClob is initialized with a
+     * Clob. Null if SerialClob is initialized with a char[].
      */
-    private Clob clob;
+    private final Clob clob;
 
     /**
      * The length in characters of this <code>SerialClob</code> object's
@@ -71,12 +71,12 @@
     private long len;
 
     /**
-     * The original length in characters of tgus <code>SerialClob</code>
-     * objects internal array of characters.
+     * The original length in characters of this <code>SerialClob</code>
+     * object's internal array of characters.
      *
      * @serial
      */
-    private long origLen;
+    private final long origLen;
 
     /**
      * Constructs a <code>SerialClob</code> object that is a serialized version of
@@ -104,6 +104,7 @@
            buf[i] = ch[i];
         }
         origLen = len;
+        clob = null;
     }
 
     /**
@@ -117,19 +118,19 @@
      * the database. Otherwise, the new <code>SerialClob</code> object
      * object will contain no data.
      * <p>
-     * Note: The <code>Clob</code> object supplied to this constructor cannot
-     * return <code>null</code> for the <code>Clob.getCharacterStream()</code>
+     * Note: The <code>Clob</code> object supplied to this constructor must
+     * return non-null for both the <code>Clob.getCharacterStream()</code>
      * and <code>Clob.getAsciiStream</code> methods. This <code>SerialClob</code>
-     * constructor cannot  serialize a <code>Clob</code> object in this instance
+     * constructor cannot serialize a <code>Clob</code> object in this instance
      * and will throw an <code>SQLException</code> object.
      *
      * @param  clob the <code>Clob</code> object from which this
      *     <code>SerialClob</code> object is to be constructed; cannot be null
      * @throws SerialException if an error occurs during serialization
      * @throws SQLException if a SQL error occurs in capturing the CLOB;
-     *     if the <code>Clob</code> object is a null; or if both the
+     *     if the <code>Clob</code> object is a null; or if either of the
      *     <code>Clob.getCharacterStream()</code> and <code>Clob.getAsciiStream()</code>
-     *     methods on the <code>Clob</code> return a null
+     *     methods on the <code>Clob</code> returns a null
      * @see java.sql.Clob
      */
     public SerialClob(Clob clob) throws SerialException, SQLException {
@@ -144,19 +145,27 @@
         int read = 0;
         int offset = 0;
 
-        BufferedReader reader;
-        if ( (((reader = new BufferedReader(clob.getCharacterStream())) == null)) &&
-            (clob.getAsciiStream() == null)) {
-            throw new SQLException("Invalid Clob object. Calls to getCharacterStream " +
-                "and getAsciiStream return null which cannot be serialized.");
-        }
+        try (Reader charStream = clob.getCharacterStream()) {
+            if (charStream == null) {
+                throw new SQLException("Invalid Clob object. The call to getCharacterStream " +
+                    "returned null which cannot be serialized.");
+            }
 
-        try {
-            do {
-                read = reader.read(buf, offset, (int)(len - offset));
-                offset += read;
-            } while (read > 0);
+            // Note: get an ASCII stream in order to null-check it,
+            // even though we don't do anything with it.
+            try (InputStream asciiStream = clob.getAsciiStream()) {
+                if (asciiStream == null) {
+                    throw new SQLException("Invalid Clob object. The call to getAsciiStream " +
+                        "returned null which cannot be serialized.");
+                }
+            }
 
+            try (Reader reader = new BufferedReader(charStream)) {
+                do {
+                    read = reader.read(buf, offset, (int)(len - offset));
+                    offset += read;
+                } while (read > 0);
+            }
         } catch (java.io.IOException ex) {
             throw new SerialException("SerialClob: " + ex.getMessage());
         }
@@ -207,13 +216,13 @@
      *     used to create this <code>SerialClob</code> object
      */
     public java.io.InputStream getAsciiStream() throws SerialException, SQLException {
-       if (this.clob != null) {
-             return this.clob.getAsciiStream();
-         } else {
-             throw new SerialException("Unsupported operation. SerialClob cannot " +
+        if (this.clob != null) {
+            return this.clob.getAsciiStream();
+        } else {
+            throw new SerialException("Unsupported operation. SerialClob cannot " +
                 "return a the CLOB value as an ascii stream, unless instantiated " +
                 "with a fully implemented Clob object.");
-         }
+        }
     }
 
     /**
--- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Thu Mar 03 07:02:30 2011 -0800
@@ -32,6 +32,7 @@
 import javax.sql.*;
 
 import java.io.FileInputStream;
+import java.io.InputStream;
 import java.io.IOException;
 import java.io.FileNotFoundException;
 
@@ -366,7 +367,9 @@
                     // Load user's implementation of SyncProvider
                     // here. -Drowset.properties=/abc/def/pqr.txt
                     ROWSET_PROPERTIES = strRowsetProperties;
-                    properties.load(new FileInputStream(ROWSET_PROPERTIES));
+                    try (FileInputStream fis = new FileInputStream(ROWSET_PROPERTIES)) {
+                        properties.load(fis);
+                    }
                     parseProperties(properties);
                 }
 
@@ -376,12 +379,19 @@
                 ROWSET_PROPERTIES = "javax" + strFileSep + "sql" +
                         strFileSep + "rowset" + strFileSep +
                         "rowset.properties";
-                // properties.load(
-                //                ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES));
 
                 ClassLoader cl = Thread.currentThread().getContextClassLoader();
 
-                properties.load(cl.getResourceAsStream(ROWSET_PROPERTIES));
+                try (InputStream stream =
+                         (cl == null) ? ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES)
+                                      : cl.getResourceAsStream(ROWSET_PROPERTIES)) {
+                    if (stream == null) {
+                        throw new SyncFactoryException(
+                            "Resource " + ROWSET_PROPERTIES + " not found");
+                    }
+                    properties.load(stream);
+                }
+
                 parseProperties(properties);
 
             // removed else, has properties should sum together
--- a/src/share/classes/javax/swing/JComponent.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/JComponent.java	Thu Mar 03 07:02:30 2011 -0800
@@ -4910,14 +4910,17 @@
      * Returns {@code true} if a paint triggered on a child component should cause
      * painting to originate from this Component, or one of its ancestors.
      * <p/>
-     * Calling {@link JComponent#repaint} on a Swing component will be delegated to
-     * the first ancestor which {@code isPaintingOrigin()} returns {@code true},
-     * if there are any.
+     * Calling {@link #repaint} or {@link #paintImmediately(int, int, int, int)}
+     * on a Swing component will result in calling
+     * the {@link JComponent#paintImmediately(int, int, int, int)} method of
+     * the first ancestor which {@code isPaintingOrigin()} returns {@code true}, if there are any.
      * <p/>
-     * {@code JComponent} subclasses that need to be repainted when any of their
+     * {@code JComponent} subclasses that need to be painted when any of their
      * children are repainted should override this method to return {@code true}.
      *
      * @return always returns {@code false}
+     *
+     * @see #paintImmediately(int, int, int, int)
      */
     protected boolean isPaintingOrigin() {
         return false;
@@ -4932,12 +4935,16 @@
      * and can collapse redundant requests into a single paint call.
      * This method is useful if one needs to update the display while
      * the current event is being dispatched.
+     * <p>
+     * This method is to be overridden when the dirty region needs to be changed
+     * for components that are painting origins.
      *
      * @param x  the x value of the region to be painted
      * @param y  the y value of the region to be painted
      * @param w  the width of the region to be painted
      * @param h  the height of the region to be painted
      * @see #repaint
+     * @see #isPaintingOrigin()
      */
     public void paintImmediately(int x,int y,int w, int h) {
         Component c = this;
@@ -4946,6 +4953,15 @@
         if(!isShowing()) {
             return;
         }
+
+        JComponent paintingOigin = SwingUtilities.getPaintingOrigin(this);
+        if (paintingOigin != null) {
+            Rectangle rectangle = SwingUtilities.convertRectangle(
+                    c, new Rectangle(x, y, w, h), paintingOigin);
+            paintingOigin.paintImmediately(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+            return;
+        }
+
         while(!c.isOpaque()) {
             parent = c.getParent();
             if(parent != null) {
--- a/src/share/classes/javax/swing/JLayer.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/JLayer.java	Thu Mar 03 07:02:30 2011 -0800
@@ -156,8 +156,9 @@
     // when layerUI is serializable
     private LayerUI<? super V> layerUI;
     private JPanel glassPane;
-    private boolean isPainting;
     private long eventMask;
+    private transient boolean isPainting;
+    private transient boolean isPaintingImmediately;
 
     private static final LayerEventController eventController =
             new LayerEventController();
@@ -393,17 +394,25 @@
     }
 
     /**
-     * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method.
+     * Delegates its functionality to the
+     * {@link javax.swing.plaf.LayerUI#paintImmediately(int, int, int, int, JLayer)} method,
+     * if {@code LayerUI} is set.
      *
-     * @param tm  this parameter is not used
-     * @param x  the x value of the dirty region
-     * @param y  the y value of the dirty region
-     * @param width  the width of the dirty region
-     * @param height  the height of the dirty region
+     * @param x  the x value of the region to be painted
+     * @param y  the y value of the region to be painted
+     * @param w  the width of the region to be painted
+     * @param h  the height of the region to be painted
      */
-    public void repaint(long tm, int x, int y, int width, int height) {
-        if (getUI() != null) {
-            getUI().repaint(tm, x, y, width, height, this);
+    public void paintImmediately(int x, int y, int w, int h) {
+        if (!isPaintingImmediately && getUI() != null) {
+            isPaintingImmediately = true;
+            try {
+                getUI().paintImmediately(x, y, w, h, this);
+            } finally {
+                isPaintingImmediately = false;
+            }
+        } else {
+            super.paintImmediately(x, y, w, h);
         }
     }
 
@@ -415,8 +424,11 @@
     public void paint(Graphics g) {
         if (!isPainting) {
             isPainting = true;
-            super.paintComponent(g);
-            isPainting = false;
+            try {
+                super.paintComponent(g);
+            } finally {
+                isPainting = false;
+            }
         } else {
             super.paint(g);
         }
--- a/src/share/classes/javax/swing/LookAndFeel.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/LookAndFeel.java	Thu Mar 03 07:02:30 2011 -0800
@@ -332,12 +332,13 @@
     {
         JTextComponent.KeyBinding[] rv = new JTextComponent.KeyBinding[keyBindingList.length / 2];
 
-        for(int i = 0; i < keyBindingList.length; i += 2) {
-            KeyStroke keystroke = (keyBindingList[i] instanceof KeyStroke)
-                ? (KeyStroke)keyBindingList[i]
-                : KeyStroke.getKeyStroke((String)keyBindingList[i]);
-            String action = (String)keyBindingList[i+1];
-            rv[i / 2] = new JTextComponent.KeyBinding(keystroke, action);
+        for(int i = 0; i < rv.length; i ++) {
+            Object o = keyBindingList[2 * i];
+            KeyStroke keystroke = (o instanceof KeyStroke)
+                ? (KeyStroke) o
+                : KeyStroke.getKeyStroke((String) o);
+            String action = (String) keyBindingList[2 * i + 1];
+            rv[i] = new JTextComponent.KeyBinding(keystroke, action);
         }
 
         return rv;
--- a/src/share/classes/javax/swing/RepaintManager.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/RepaintManager.java	Thu Mar 03 07:02:30 2011 -0800
@@ -438,7 +438,6 @@
      * @param y Y coordinate of the region to repaint
      * @param w Width of the region to repaint
      * @param h Height of the region to repaint
-     * @see JComponent#isPaintingOrigin()
      * @see JComponent#repaint
      */
     public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
@@ -448,16 +447,6 @@
             delegate.addDirtyRegion(c, x, y, w, h);
             return;
         }
-        Container p = c;
-        while ((p = p.getParent()) instanceof JComponent) {
-            JComponent jp = (JComponent) p;
-            if (jp.isPaintingOrigin()) {
-                Rectangle rectangle = SwingUtilities.convertRectangle(
-                        c, new Rectangle(x, y, w, h), jp);
-                jp.repaint(0, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
-                return;
-            }
-        }
         addDirtyRegion0(c, x, y, w, h);
     }
 
--- a/src/share/classes/javax/swing/SwingUtilities.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/SwingUtilities.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1532,6 +1532,17 @@
         return applet;
     }
 
+    static JComponent getPaintingOrigin(JComponent c) {
+        Container p = c;
+        while ((p = p.getParent()) instanceof JComponent) {
+            JComponent jp = (JComponent) p;
+            if (jp.isPaintingOrigin()) {
+                return jp;
+            }
+        }
+        return null;
+    }
+
     /**
      * Process the key bindings for the <code>Component</code> associated with
      * <code>event</code>. This method is only useful if
--- a/src/share/classes/javax/swing/plaf/LayerUI.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/plaf/LayerUI.java	Thu Mar 03 07:02:30 2011 -0800
@@ -703,21 +703,19 @@
     }
 
     /**
-     * Adds the specified region to the dirty region list if the component
-     * is showing.  The component will be repainted after all of the
-     * currently pending events have been dispatched.
+     * Paints the specified region in the {@code JLayer} this {@code LayerUI} is set to, immediately.
      * <p/>
      * This method is to be overridden when the dirty region needs to be changed.
+     * The default implementation delegates its functionality to {@link JComponent#paintImmediately(int, int, int, int)}.
      *
-     * @param tm  this parameter is not used
-     * @param x  the x value of the dirty region
-     * @param y  the y value of the dirty region
-     * @param width  the width of the dirty region
-     * @param height  the height of the dirty region
-     * @see java.awt.Component#isShowing
-     * @see RepaintManager#addDirtyRegion
+     * @param x  the x value of the region to be painted
+     * @param y  the y value of the region to be painted
+     * @param w  the width of the region to be painted
+     * @param h  the height of the region to be painted
+     *
+     * @see JComponent#paintImmediately(int, int, int, int)
      */
-    public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) {
-        RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height);
+    public void paintImmediately(int x, int y, int width, int height, JLayer<? extends V> l) {
+        l.paintImmediately(x, y, width, height);
     }
 }
--- a/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1965,18 +1965,18 @@
     }
 
     /** Returns the preferred size to properly display the tree,
-      * this is a cover method for getPreferredSize(c, false).
+      * this is a cover method for getPreferredSize(c, true).
       */
     public Dimension getPreferredSize(JComponent c) {
         return getPreferredSize(c, true);
     }
 
     /** Returns the preferred size to represent the tree in
-      * <I>c</I>.  If <I>checkConsistancy</I> is true
-      * <b>checkConsistancy</b> is messaged first.
+      * <I>c</I>.  If <I>checkConsistency</I> is true
+      * <b>checkConsistency</b> is messaged first.
       */
     public Dimension getPreferredSize(JComponent c,
-                                      boolean checkConsistancy) {
+                                      boolean checkConsistency) {
         Dimension       pSize = this.getPreferredMinSize();
 
         if(!validCachedPreferredSize)
--- a/src/share/classes/javax/swing/plaf/synth/SynthGraphicsUtils.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/javax/swing/plaf/synth/SynthGraphicsUtils.java	Thu Mar 03 07:02:30 2011 -0800
@@ -510,7 +510,6 @@
         Font holdf = g.getFont();
         Color holdc = g.getColor();
 
-        paintBackground(g, lh);
         paintCheckIcon(g, lh, lr);
         paintIcon(g, lh, lr);
         paintText(g, lh, lr);
--- a/src/share/classes/sun/awt/image/ImageFetcher.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/awt/image/ImageFetcher.java	Thu Mar 03 07:02:30 2011 -0800
@@ -61,8 +61,10 @@
     /**
       * Adds an ImageFetchable to the queue of items to fetch.  Instantiates
       * a new ImageFetcher if it's reasonable to do so.
+      * If there is no available fetcher to process an ImageFetchable, then
+      * reports failure to caller.
       */
-    public static void add(ImageFetchable src) {
+    public static boolean add(ImageFetchable src) {
         final FetcherInfo info = FetcherInfo.getFetcherInfo();
         synchronized(info.waitList) {
             if (!info.waitList.contains(src)) {
@@ -71,9 +73,23 @@
                             info.numFetchers < info.fetchers.length) {
                     createFetchers(info);
                 }
-                info.waitList.notify();
+                /* Creation of new fetcher may fail due to high vm load
+                 * or some other reason.
+                 * If there is already exist, but busy, fetcher, we leave
+                 * the src in queue (it will be handled by existing
+                 * fetcher later).
+                 * Otherwise, we report failure: there is no fetcher
+                 * to handle the src.
+                 */
+                if (info.numFetchers > 0) {
+                    info.waitList.notify();
+                } else {
+                    info.waitList.removeElement(src);
+                    return false;
+                }
             }
         }
+        return true;
     }
 
     /**
@@ -291,11 +307,15 @@
          public Object run() {
              for (int i = 0; i < info.fetchers.length; i++) {
                if (info.fetchers[i] == null) {
-                   info.fetchers[i] = new ImageFetcher(
+                   ImageFetcher f = new ImageFetcher(
                            fetcherGroup, i);
-                   info.fetchers[i].start();
-                   info.numFetchers++;
-                   break;
+                   try {
+                       f.start();
+                       info.fetchers[i] = f;
+                       info.numFetchers++;
+                       break;
+                   } catch (Error e) {
+                   }
                }
              }
           return null;
--- a/src/share/classes/sun/awt/image/InputStreamImageSource.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/awt/image/InputStreamImageSource.java	Thu Mar 03 07:02:30 2011 -0800
@@ -164,8 +164,13 @@
 
     private synchronized void startProduction() {
         if (!awaitingFetch) {
-            ImageFetcher.add(this);
-            awaitingFetch = true;
+            if (ImageFetcher.add(this)) {
+                awaitingFetch = true;
+            } else {
+                ImageConsumerQueue cq = consumers;
+                consumers = null;
+                errorAllConsumers(cq, false);
+            }
         }
     }
 
--- a/src/share/classes/sun/dyn/AdapterMethodHandle.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/AdapterMethodHandle.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -478,37 +478,60 @@
         return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
     }
 
-    static MethodHandle makeTypeHandler(Access token,
-                MethodHandle target, MethodHandle typeHandler) {
+    static MethodHandle makeVarargsCollector(Access token,
+                MethodHandle target, Class<?> arrayType) {
         Access.check(token);
-        return new WithTypeHandler(target, typeHandler);
+        return new AsVarargsCollector(target, arrayType);
     }
 
-    static class WithTypeHandler extends AdapterMethodHandle {
-        final MethodHandle target, typeHandler;
-        WithTypeHandler(MethodHandle target, MethodHandle typeHandler) {
+    static class AsVarargsCollector extends AdapterMethodHandle {
+        final MethodHandle target;
+        final Class<?> arrayType;
+        MethodHandle cache;
+
+        AsVarargsCollector(MethodHandle target, Class<?> arrayType) {
             super(target, target.type(), makeConv(OP_RETYPE_ONLY));
             this.target = target;
-            this.typeHandler = typeHandler.asType(TYPE_HANDLER_TYPE);
+            this.arrayType = arrayType;
+            this.cache = target.asCollector(arrayType, 0);
         }
 
+        @Override
+        public boolean isVarargsCollector() {
+            return true;
+        }
+
+        @Override
         public MethodHandle asType(MethodType newType) {
-            if (this.type() == newType)
+            MethodType type = this.type();
+            int collectArg = type.parameterCount() - 1;
+            int newArity = newType.parameterCount();
+            if (newArity == collectArg+1 &&
+                type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
+                // if arity and trailing parameter are compatible, do normal thing
+                return super.asType(newType);
+            }
+            // check cache
+            if (cache.type().parameterCount() == newArity)
+                return cache.asType(newType);
+            // build and cache a collector
+            int arrayLength = newArity - collectArg;
+            MethodHandle collector;
+            try {
+                collector = target.asCollector(arrayType, arrayLength);
+            } catch (IllegalArgumentException ex) {
+                throw new WrongMethodTypeException("cannot build collector");
+            }
+            cache = collector;
+            return collector.asType(newType);
+        }
+
+        public MethodHandle asVarargsCollector(Class<?> arrayType) {
+            MethodType type = this.type();
+            if (type.parameterType(type.parameterCount()-1) == arrayType)
                 return this;
-            try {
-                MethodHandle retyped = (MethodHandle) typeHandler.invokeExact(target, newType);
-                // Contract:  Must return the desired type, or throw WMT
-                if (retyped.type() != newType)
-                    throw new WrongMethodTypeException(retyped.toString());
-                return retyped;
-            } catch (Throwable ex) {
-                if (ex instanceof Error)  throw (Error)ex;
-                if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
-                throw new RuntimeException(ex);
-            }
+            return super.asVarargsCollector(arrayType);
         }
-        private static final MethodType TYPE_HANDLER_TYPE
-            = MethodType.methodType(MethodHandle.class, MethodHandle.class, MethodType.class);
     }
 
     /** Can a checkcast adapter validly convert the target to newType?
@@ -939,7 +962,7 @@
 
     @Override
     public String toString() {
-        return nonAdapter((MethodHandle)vmtarget).toString();
+        return MethodHandleImpl.getNameString(IMPL_TOKEN, nonAdapter((MethodHandle)vmtarget), this);
     }
 
     private static MethodHandle nonAdapter(MethodHandle mh) {
--- a/src/share/classes/sun/dyn/CallSiteImpl.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/CallSiteImpl.java	Thu Mar 03 07:02:30 2011 -0800
@@ -37,17 +37,17 @@
     static CallSite makeSite(MethodHandle bootstrapMethod,
                              // Callee information:
                              String name, MethodType type,
-                             // Call-site attributes, if any:
+                             // Extra arguments for BSM, if any:
                              Object info,
                              // Caller information:
                              MemberName callerMethod, int callerBCI) {
         Class<?> callerClass = callerMethod.getDeclaringClass();
         Object caller;
-        if (bootstrapMethod.type().parameterType(0) == Class.class)
+        if (bootstrapMethod.type().parameterType(0) == Class.class && TRANSITIONAL_BEFORE_PFD)
             caller = callerClass;  // remove for PFD
         else
             caller = MethodHandleImpl.IMPL_LOOKUP.in(callerClass);
-        if (bootstrapMethod == null) {
+        if (bootstrapMethod == null && TRANSITIONAL_BEFORE_PFD) {
             // If there is no bootstrap method, throw IncompatibleClassChangeError.
             // This is a valid generic error type for resolution (JLS 12.3.3).
             throw new IncompatibleClassChangeError
@@ -56,30 +56,35 @@
         CallSite site;
         try {
             Object binding;
+            info = maybeReBox(info);
             if (info == null) {
-                if (false)  // switch when invokeGeneric works
-                    binding = bootstrapMethod.invokeGeneric(caller, name, type);
+                binding = bootstrapMethod.invokeGeneric(caller, name, type);
+            } else if (!info.getClass().isArray()) {
+                binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
+            } else {
+                Object[] argv = (Object[]) info;
+                if (3 + argv.length > 255)
+                    new InvokeDynamicBootstrapError("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 = bootstrapMethod.invokeVarargs(new Object[]{ caller, name, type });
-            } else {
-                info = maybeReBox(info);
-                if (false)  // switch when invokeGeneric works
-                    binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
-                else
-                    binding = bootstrapMethod.invokeVarargs(new Object[]{ caller, name, type, info });
+                    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 if (binding instanceof MethodHandle) {
+            } else if (binding instanceof MethodHandle && TRANSITIONAL_BEFORE_PFD) {
                 // Transitional!
                 MethodHandle target = (MethodHandle) binding;
                 site = new ConstantCallSite(target);
             } else {
-                throw new ClassCastException("bootstrap method failed to produce a MethodHandle or CallSite");
+                throw new ClassCastException("bootstrap method failed to produce a CallSite");
             }
-            PRIVATE_INITIALIZE_CALL_SITE.invokeExact(site, name, type,
-                                                     callerMethod, callerBCI);
+            if (TRANSITIONAL_BEFORE_PFD)
+                PRIVATE_INITIALIZE_CALL_SITE.invokeExact(site, name, type,
+                                                         callerMethod, callerBCI);
             assert(site.getTarget() != null);
             assert(site.getTarget().type().equals(type));
         } catch (Throwable ex) {
@@ -93,6 +98,8 @@
         return site;
     }
 
+    private static boolean TRANSITIONAL_BEFORE_PFD = true;  // FIXME: remove for PFD
+
     private static Object maybeReBox(Object x) {
         if (x instanceof Integer) {
             int xi = (int) x;
@@ -117,11 +124,12 @@
     static {
         try {
             PRIVATE_INITIALIZE_CALL_SITE =
+            !TRANSITIONAL_BEFORE_PFD ? null :
             MethodHandleImpl.IMPL_LOOKUP.findVirtual(CallSite.class, "initializeFromJVM",
                 MethodType.methodType(void.class,
                                       String.class, MethodType.class,
                                       MemberName.class, int.class));
-        } catch (NoAccessException ex) {
+        } catch (ReflectiveOperationException ex) {
             throw uncaughtException(ex);
         }
     }
--- a/src/share/classes/sun/dyn/FilterGeneric.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/FilterGeneric.java	Thu Mar 03 07:02:30 2011 -0800
@@ -187,7 +187,7 @@
             MethodHandle entryPoint = null;
             try {
                 entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
             }
             if (entryPoint == null)  continue;
             Constructor<? extends Adapter> ctor = null;
--- a/src/share/classes/sun/dyn/FilterOneArgument.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/FilterOneArgument.java	Thu Mar 03 07:02:30 2011 -0800
@@ -56,7 +56,7 @@
             INVOKE =
                 MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
                                                          MethodType.genericMethodType(1));
-        } catch (NoAccessException ex) {
+        } catch (ReflectiveOperationException ex) {
             throw uncaughtException(ex);
         }
     }
--- a/src/share/classes/sun/dyn/FromGeneric.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/FromGeneric.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 import java.dyn.*;
 import java.lang.reflect.*;
 import sun.dyn.util.*;
+import static sun.dyn.MethodTypeImpl.invokers;
 
 /**
  * Adapters which mediate between incoming calls which are generic
@@ -128,7 +129,7 @@
             MethodType targetType, MethodType internalType) {
         // All the adapters we have here have reference-untyped internal calls.
         assert(internalType == internalType.erase());
-        MethodHandle invoker = MethodHandles.exactInvoker(targetType);
+        MethodHandle invoker = invokers(targetType).exactInvoker();
         // cast all narrow reference types, unbox all primitive arguments:
         MethodType fixArgsType = internalType.changeReturnType(targetType.returnType());
         MethodHandle fixArgs = AdapterMethodHandle.convertArguments(Access.TOKEN,
@@ -203,7 +204,7 @@
             MethodHandle entryPoint = null;
             try {
                 entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
             }
             if (entryPoint == null)  continue;
             Constructor<? extends Adapter> ctor = null;
--- a/src/share/classes/sun/dyn/InvokeGeneric.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/InvokeGeneric.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 import java.dyn.*;
 import java.lang.reflect.*;
 import sun.dyn.util.*;
+import static sun.dyn.MethodTypeImpl.invokers;
 
 /**
  * Adapters which manage MethodHanndle.invokeGeneric calls.
@@ -43,7 +44,7 @@
     /** Compute and cache information for this adapter, so that it can
      *  call out to targets of the erasure-family of the given erased type.
      */
-    private InvokeGeneric(MethodType erasedCallerType) throws NoAccessException {
+    private InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException {
         this.erasedCallerType = erasedCallerType;
         this.initialInvoker = makeInitialInvoker();
         assert initialInvoker.type().equals(erasedCallerType
@@ -63,14 +64,14 @@
             try {
                 InvokeGeneric gen = new InvokeGeneric(form.erasedType());
                 form.genericInvoker = genericInvoker = gen.initialInvoker;
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 throw new RuntimeException(ex);
             }
         }
         return genericInvoker;
     }
 
-    private MethodHandle makeInitialInvoker() throws NoAccessException {
+    private MethodHandle makeInitialInvoker() throws ReflectiveOperationException {
         // postDispatch = #(MH'; MT, MH; A...){MH'(MT, MH; A)}
         MethodHandle postDispatch = makePostDispatchInvoker();
         MethodHandle invoker;
@@ -87,14 +88,14 @@
     private MethodHandle makePostDispatchInvoker() {
         // Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...).
         MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS);
-        return MethodHandles.exactInvoker(invokerType);
+        return invokers(invokerType).exactInvoker();
     }
     private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) {
         assert(targetInvoker.type().parameterType(0) == MethodHandle.class);
         return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS);
     }
 
-    private MethodHandle dispatcher(String dispatchName) throws NoAccessException {
+    private MethodHandle dispatcher(String dispatchName) throws ReflectiveOperationException {
         return lookup().bind(this, dispatchName,
                              MethodType.methodType(MethodHandle.class,
                                                    MethodType.class, MethodHandle.class));
@@ -108,7 +109,7 @@
      */
     private MethodHandle dispatch(MethodType callerType, MethodHandle target) {
         MethodType targetType = target.type();
-        if (USE_AS_TYPE_PATH || target instanceof AdapterMethodHandle.WithTypeHandler) {
+        if (USE_AS_TYPE_PATH || target.isVarargsCollector()) {
             MethodHandle newTarget = target.asType(callerType);
             targetType = callerType;
             Invokers invokers = MethodTypeImpl.invokers(Access.TOKEN, targetType);
--- a/src/share/classes/sun/dyn/Invokers.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/Invokers.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@
     private /*lazy*/ MethodHandle genericInvoker;
 
     // generic (untyped) invoker for the outgoing call; accepts a single Object[]
-    private final /*lazy*/ MethodHandle[] varargsInvokers;
+    private final /*lazy*/ MethodHandle[] spreadInvokers;
 
     // invoker for an unbound callsite
     private /*lazy*/ MethodHandle uninitializedCallSite;
@@ -55,10 +55,9 @@
     /** Compute and cache information common to all collecting adapters
      *  that implement members of the erasure-family of the given erased type.
      */
-    public Invokers(Access token, MethodType targetType) {
-        Access.check(token);
+    /*non-public*/ Invokers(MethodType targetType) {
         this.targetType = targetType;
-        this.varargsInvokers = new MethodHandle[targetType.parameterCount()+1];
+        this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
     }
 
     public static MethodType invokerType(MethodType targetType) {
@@ -69,8 +68,8 @@
         MethodHandle invoker = exactInvoker;
         if (invoker != null)  return invoker;
         try {
-            invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invoke", targetType);
-        } catch (NoAccessException ex) {
+            invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invokeExact", targetType);
+        } catch (ReflectiveOperationException ex) {
             throw new InternalError("JVM cannot find invoker for "+targetType);
         }
         assert(invokerType(targetType) == invoker.type());
@@ -101,13 +100,12 @@
         return invoker;
     }
 
-    public MethodHandle varargsInvoker(int objectArgCount) {
-        MethodHandle vaInvoker = varargsInvokers[objectArgCount];
+    public MethodHandle spreadInvoker(int objectArgCount) {
+        MethodHandle vaInvoker = spreadInvokers[objectArgCount];
         if (vaInvoker != null)  return vaInvoker;
         MethodHandle gInvoker = genericInvoker();
-        MethodType vaType = MethodType.genericMethodType(objectArgCount, true);
-        vaInvoker = MethodHandles.spreadArguments(gInvoker, invokerType(vaType));
-        varargsInvokers[objectArgCount] = vaInvoker;
+        vaInvoker = gInvoker.asSpreader(Object[].class, targetType.parameterCount() - objectArgCount);
+        spreadInvokers[objectArgCount] = vaInvoker;
         return vaInvoker;
     }
 
@@ -118,7 +116,7 @@
         if (invoker != null)  return invoker;
         if (targetType.parameterCount() > 0) {
             MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount());
-            Invokers invokers0 = MethodTypeImpl.invokers(Access.TOKEN, type0);
+            Invokers invokers0 = MethodTypeImpl.invokers(type0);
             invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(),
                                                   0, targetType.parameterList());
             assert(invoker.type().equals(targetType));
@@ -130,7 +128,7 @@
                 THROW_UCS = MethodHandleImpl.IMPL_LOOKUP
                     .findStatic(CallSite.class, "uninitializedCallSite",
                                 MethodType.methodType(Empty.class));
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 throw new RuntimeException(ex);
             }
         }
--- a/src/share/classes/sun/dyn/MemberName.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/MemberName.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -451,8 +451,6 @@
             return type.toString();  // class java.lang.String
         // else it is a field, method, or constructor
         StringBuilder buf = new StringBuilder();
-        if (!isResolved())
-            buf.append("*.");
         if (getDeclaringClass() != null) {
             buf.append(getName(clazz));
             buf.append('.');
@@ -512,14 +510,24 @@
     public static RuntimeException newIllegalArgumentException(String message) {
         return new IllegalArgumentException(message);
     }
-    public static NoAccessException newNoAccessException(MemberName name, Class<?> lookupClass) {
-        return newNoAccessException("cannot access", name, lookupClass);
+    public static IllegalAccessException newNoAccessException(MemberName name, Object from) {
+        return newNoAccessException("cannot access", name, from);
     }
-    public static NoAccessException newNoAccessException(String message,
-            MemberName name, Class<?> lookupClass) {
+    public static IllegalAccessException newNoAccessException(String message,
+            MemberName name, Object from) {
         message += ": " + name;
-        if (lookupClass != null)  message += ", from " + lookupClass.getName();
-        return new NoAccessException(message);
+        if (from != null)  message += ", from " + from;
+        return new IllegalAccessException(message);
+    }
+    public static ReflectiveOperationException newNoAccessException(MemberName name) {
+        if (name.isResolved())
+            return new IllegalAccessException(name.toString());
+        else if (name.isConstructor())
+            return new NoSuchMethodException(name.toString());
+        else if (name.isMethod())
+            return new NoSuchMethodException(name.toString());
+        else
+            return new NoSuchFieldException(name.toString());
     }
     public static Error uncaughtException(Exception ex) {
         Error err = new InternalError("uncaught exception");
@@ -643,14 +651,20 @@
         /** Produce a resolved version of the given member.
          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
          *  Access checking is performed on behalf of the given {@code lookupClass}.
-         *  If lookup fails or access is not permitted, a {@linkplain NoAccessException} is thrown.
+         *  If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown.
          *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
          */
-        public MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass) throws NoAccessException {
+        public
+        <NoSuchMemberException extends ReflectiveOperationException>
+        MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass,
+                                 Class<NoSuchMemberException> nsmClass)
+                throws IllegalAccessException, NoSuchMemberException {
             MemberName result = resolveOrNull(m, searchSupers, lookupClass);
             if (result != null)
                 return result;
-            throw newNoAccessException(m, lookupClass);
+            ReflectiveOperationException ex = newNoAccessException(m);
+            if (ex instanceof IllegalAccessException)  throw (IllegalAccessException) ex;
+            throw nsmClass.cast(ex);
         }
         /** Return a list of all methods defined by the given class.
          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
--- a/src/share/classes/sun/dyn/MethodHandleImpl.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/MethodHandleImpl.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import sun.dyn.util.VerifyType;
-import java.dyn.NoAccessException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -136,6 +135,8 @@
     }
 
     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)
@@ -167,11 +168,11 @@
      * @param doDispatch whether the method handle will test the receiver type
      * @param lookupClass access-check relative to this class
      * @return a direct handle to the matching method
-     * @throws NoAccessException 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
     MethodHandle findMethod(Access token, MemberName method,
-            boolean doDispatch, Class<?> lookupClass) throws NoAccessException {
+                            boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException {
         Access.check(token);  // only trusted calls
         MethodType mtype = method.getMethodType();
         if (!method.isStatic()) {
@@ -184,7 +185,10 @@
         if (!mh.isValid())
             throw newNoAccessException(method, lookupClass);
         assert(mh.type() == mtype);
-        return mh;
+        if (!method.isVarargs())
+            return mh;
+        else
+            return mh.asVarargsCollector(mtype.parameterType(mtype.parameterCount()-1));
     }
 
     public static
@@ -302,7 +306,7 @@
                 MethodHandle invoke = null;
                 try {
                     invoke = lookup.findVirtual(AllocateObject.class, name, MethodType.genericMethodType(nargs));
-                } catch (NoAccessException ex) {
+                } catch (ReflectiveOperationException ex) {
                 }
                 if (invoke == null)  break;
                 invokes.add(invoke);
@@ -317,7 +321,7 @@
         static {
             try {
                 VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true));
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 throw uncaughtException(ex);
             }
         }
@@ -469,7 +473,7 @@
             MethodHandle mh;
             try {
                 mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 throw uncaughtException(ex);
             }
             if (evclass != vclass || (!isStatic && ecclass != cclass)) {
@@ -537,7 +541,7 @@
             MethodHandle mh;
             try {
                 mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 throw uncaughtException(ex);
             }
             if (caclass != null) {
@@ -1009,7 +1013,7 @@
                 MethodHandle invoke = null;
                 try {
                     invoke = lookup.findVirtual(GuardWithTest.class, name, MethodType.genericMethodType(nargs));
-                } catch (NoAccessException ex) {
+                } catch (ReflectiveOperationException ex) {
                 }
                 if (invoke == null)  break;
                 invokes.add(invoke);
@@ -1024,7 +1028,7 @@
         static {
             try {
                 VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true));
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 throw uncaughtException(ex);
             }
         }
@@ -1145,7 +1149,7 @@
                 MethodHandle invoke = null;
                 try {
                     invoke = lookup.findVirtual(GuardWithCatch.class, name, MethodType.genericMethodType(nargs));
-                } catch (NoAccessException ex) {
+                } catch (ReflectiveOperationException ex) {
                 }
                 if (invoke == null)  break;
                 invokes.add(invoke);
@@ -1160,7 +1164,7 @@
         static {
             try {
                 VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true));
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 throw uncaughtException(ex);
             }
         }
@@ -1207,20 +1211,30 @@
             THROW_EXCEPTION
             = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
                     MethodType.methodType(Empty.class, Throwable.class));
-        } catch (NoAccessException ex) {
+        } catch (ReflectiveOperationException ex) {
             throw new RuntimeException(ex);
         }
     }
     static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
 
-    public static String getNameString(Access token, MethodHandle target) {
+    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" + target.type();
-        return name.getName() + target.type();
+            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) {
@@ -1263,8 +1277,8 @@
         return MethodHandleNatives.getBootstrap(callerClass);
     }
 
-    public static MethodHandle withTypeHandler(Access token, MethodHandle target, MethodHandle typeHandler) {
+    public static MethodHandle asVarargsCollector(Access token, MethodHandle target, Class<?> arrayType) {
         Access.check(token);
-        return AdapterMethodHandle.makeTypeHandler(token, target, typeHandler);
+        return AdapterMethodHandle.makeVarargsCollector(token, target, arrayType);
     }
 }
--- a/src/share/classes/sun/dyn/MethodHandleNatives.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/MethodHandleNatives.java	Thu Mar 03 07:02:30 2011 -0800
@@ -350,7 +350,7 @@
             case REF_invokeInterface:   return lookup.findVirtual(      defc, name, (MethodType) type );
             }
             throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
-        } catch (NoAccessException ex) {
+        } catch (ReflectiveOperationException ex) {
             Error err = new IncompatibleClassChangeError();
             err.initCause(ex);
             throw err;
--- a/src/share/classes/sun/dyn/MethodTypeImpl.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/MethodTypeImpl.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -498,9 +498,12 @@
 
     public static Invokers invokers(Access token, MethodType type) {
         Access.check(token);
+        return invokers(type);
+    }
+    /*non-public*/ static Invokers invokers(MethodType type) {
         Invokers inv = METHOD_TYPE_FRIEND.getInvokers(type);
         if (inv != null)  return inv;
-        inv = new Invokers(token, type);
+        inv = new Invokers(type);
         METHOD_TYPE_FRIEND.setInvokers(type, inv);
         return inv;
     }
--- a/src/share/classes/sun/dyn/SpreadGeneric.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/SpreadGeneric.java	Thu Mar 03 07:02:30 2011 -0800
@@ -167,7 +167,7 @@
             MethodHandle entryPoint = null;
             try {
                 entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
             }
             if (entryPoint == null)  continue;
             Constructor<? extends Adapter> ctor = null;
--- a/src/share/classes/sun/dyn/ToGeneric.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/ToGeneric.java	Thu Mar 03 07:02:30 2011 -0800
@@ -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.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 import sun.dyn.util.ValueConversions;
 import sun.dyn.util.Wrapper;
 import static sun.dyn.MemberName.newIllegalArgumentException;
+import static sun.dyn.MethodTypeImpl.invokers;
 
 /**
  * Adapters which mediate between incoming calls which are not generic
@@ -72,7 +73,7 @@
         assert(entryType.erase() == entryType); // for now
         // incoming call will first "forget" all reference types except Object
         this.entryType = entryType;
-        MethodHandle invoker0 = MethodHandles.exactInvoker(entryType.generic());
+        MethodHandle invoker0 = invokers(entryType.generic()).exactInvoker();
         MethodType rawEntryTypeInit;
         Adapter ad = findAdapter(rawEntryTypeInit = entryType);
         if (ad != null) {
@@ -284,7 +285,7 @@
                 try {
                     entryPoint = MethodHandleImpl.IMPL_LOOKUP.
                                     findSpecial(acls, iname, entryPointType, acls);
-                } catch (NoAccessException ex) {
+                } catch (ReflectiveOperationException ex) {
                 }
                 if (entryPoint == null)  continue;
                 Constructor<? extends Adapter> ctor = null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/dyn/WrapperInstance.java	Thu Mar 03 07:02:30 2011 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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 sun.dyn;
+
+import java.dyn.MethodHandle;
+
+/**
+ * Private API used inside of java.dyn.MethodHandles.
+ * Interface implemented by every object which is produced by
+ * {@link java.dyn.MethodHandles#asInstance MethodHandles.asInstance}.
+ * The methods of this interface allow a caller to recover the parameters
+ * to {@code asInstance}.
+ * This allows applications to repeatedly convert between method handles
+ * and SAM objects, without the risk of creating unbounded delegation chains.
+ */
+public interface WrapperInstance {
+    /** Produce or recover a target method handle which is behaviorally
+     *  equivalent to the SAM method of this object.
+     */
+    public MethodHandle getWrapperInstanceTarget();
+    /** Recover the SAM type for which this object was created.
+     */
+    public Class<?> getWrapperInstanceType();
+}
+
--- a/src/share/classes/sun/dyn/util/ValueConversions.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/util/ValueConversions.java	Thu Mar 03 07:02:30 2011 -0800
@@ -153,7 +153,7 @@
             try {
                 // actually, type is wrong; the Java method takes Object
                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 mh = null;
             }
         } else {
@@ -289,7 +289,7 @@
         if (exact) {
             try {
                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 mh = null;
             }
         } else {
@@ -408,7 +408,7 @@
         if (exact) {
             try {
                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
                 mh = null;
             }
         } else {
@@ -492,7 +492,7 @@
             case INT: case LONG: case FLOAT: case DOUBLE:
                 try {
                     mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "zero"+wrap.simpleName(), type);
-                } catch (NoAccessException ex) {
+                } catch (ReflectiveOperationException ex) {
                     mh = null;
                 }
                 break;
@@ -654,7 +654,7 @@
             type = type.appendParameterTypes(wrap.primitiveType());
         try {
             mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", type);
-        } catch (NoAccessException ex) {
+        } catch (ReflectiveOperationException ex) {
             mh = null;
         }
         if (mh == null && wrap == Wrapper.VOID) {
@@ -723,7 +723,7 @@
             MethodHandle array = null;
             try {
                 array = lookup.findStatic(ValueConversions.class, name, type);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
             }
             if (array == null)  break;
             arrays.add(array);
@@ -784,7 +784,7 @@
             MethodHandle array = null;
             try {
                 array = lookup.findStatic(ValueConversions.class, name, type);
-            } catch (NoAccessException ex) {
+            } catch (ReflectiveOperationException ex) {
             }
             if (array == null)  break;
             arrays.add(array);
--- a/src/share/classes/sun/dyn/util/VerifyAccess.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/dyn/util/VerifyAccess.java	Thu Mar 03 07:02:30 2011 -0800
@@ -25,7 +25,6 @@
 
 package sun.dyn.util;
 
-import java.dyn.NoAccessException;
 import java.lang.reflect.Modifier;
 import sun.dyn.MemberName;
 import sun.dyn.MethodHandleImpl;
@@ -139,6 +138,8 @@
      * <li>C is public.
      * <li>C and D are members of the same runtime package.
      * </ul>
+     * @param refc the symbolic reference class to which access is being checked (C)
+     * @param lookupClass the class performing the lookup (D)
      */
     public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass) {
         int mods = refc.getModifiers();
--- a/src/share/classes/sun/font/FontUtilities.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/font/FontUtilities.java	Thu Mar 03 07:02:30 2011 -0800
@@ -30,6 +30,8 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
+import java.lang.ref.SoftReference;
+import java.util.concurrent.ConcurrentHashMap;
 import java.security.AccessController;
 
 import java.security.PrivilegedAction;
@@ -383,6 +385,10 @@
      * }
      * return fuir;
      */
+    private static volatile
+        SoftReference<ConcurrentHashMap<PhysicalFont, CompositeFont>>
+        compMapRef = new SoftReference(null);
+
     public static FontUIResource getCompositeFontUIResource(Font font) {
 
         FontUIResource fuir = new FontUIResource(font);
@@ -402,12 +408,22 @@
 
         FontManager fm = FontManagerFactory.getInstance();
         CompositeFont dialog2D =
-          (CompositeFont) fm.findFont2D("dialog", font.getStyle(), FontManager.NO_FALLBACK);
+          (CompositeFont) fm.findFont2D("dialog", font.getStyle(),
+                                        FontManager.NO_FALLBACK);
         if (dialog2D == null) { /* shouldn't happen */
             return fuir;
         }
         PhysicalFont physicalFont = (PhysicalFont)font2D;
-        CompositeFont compFont = new CompositeFont(physicalFont, dialog2D);
+        ConcurrentHashMap<PhysicalFont, CompositeFont> compMap = compMapRef.get();
+        if (compMap == null) { // Its been collected.
+            compMap = new ConcurrentHashMap<PhysicalFont, CompositeFont>();
+            compMapRef = new SoftReference(compMap);
+        }
+        CompositeFont compFont = compMap.get(physicalFont);
+        if (compFont == null) {
+            compFont = new CompositeFont(physicalFont, dialog2D);
+            compMap.put(physicalFont, compFont);
+        }
         FontAccess.getFontAccess().setFont2D(fuir, compFont.handle);
         /* marking this as a created font is needed as only created fonts
          * copy their creator's handles.
--- a/src/share/classes/sun/misc/JarIndex.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/misc/JarIndex.java	Thu Mar 03 07:02:30 2011 -0800
@@ -106,6 +106,19 @@
     /**
      * Returns the jar index, or <code>null</code> if none.
      *
+     * This single parameter version of the method is retained
+     * for binary compatibility with earlier releases.
+     *
+     * @param jar the JAR file to get the index from.
+     * @exception IOException if an I/O error has occurred.
+     */
+    public static JarIndex getJarIndex(JarFile jar) throws IOException {
+        return getJarIndex(jar, null);
+    }
+
+    /**
+     * Returns the jar index, or <code>null</code> if none.
+     *
      * @param jar the JAR file to get the index from.
      * @exception IOException if an I/O error has occurred.
      */
--- a/src/share/classes/sun/misc/JavaUtilJarAccess.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/misc/JavaUtilJarAccess.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,19 @@
 package sun.misc;
 
 import java.io.IOException;
+import java.net.URL;
+import java.security.CodeSource;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
 public interface JavaUtilJarAccess {
     public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException;
+    public CodeSource[] getCodeSources(JarFile jar, URL url);
+    public CodeSource getCodeSource(JarFile jar, URL url, String name);
+    public Enumeration<String> entryNames(JarFile jar, CodeSource[] cs);
+    public Enumeration<JarEntry> entries2(JarFile jar);
+    public void setEagerValidation(JarFile jar, boolean eager);
+    public List getManifestDigests(JarFile jar);
 }
--- a/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Thu Mar 03 07:02:30 2011 -0800
@@ -27,6 +27,9 @@
 
 import java.io.*;
 import java.net.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 import java.util.*;
 import java.util.jar.*;
 import java.util.zip.ZipFile;
@@ -208,38 +211,23 @@
             JarFile result = null;
 
             /* get the stream before asserting privileges */
-            final InputStream in =  url.openConnection().getInputStream();
-
-            try {
+            try (final InputStream in = url.openConnection().getInputStream()) {
                 result = AccessController.doPrivileged(
                     new PrivilegedExceptionAction<JarFile>() {
                         public JarFile run() throws IOException {
-                            OutputStream out = null;
-                            File tmpFile = null;
+                            Path tmpFile = Files.createTempFile("jar_cache", null);
                             try {
-                                tmpFile = File.createTempFile("jar_cache", null);
-                                tmpFile.deleteOnExit();
-                                out  = new FileOutputStream(tmpFile);
-                                int read = 0;
-                                byte[] buf = new byte[BUF_SIZE];
-                                while ((read = in.read(buf)) != -1) {
-                                    out.write(buf, 0, read);
+                                Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING);
+                                JarFile jarFile = new URLJarFile(tmpFile.toFile(), closeController);
+                                tmpFile.toFile().deleteOnExit();
+                                return jarFile;
+                            } catch (Throwable thr) {
+                                try {
+                                    Files.delete(tmpFile);
+                                } catch (IOException ioe) {
+                                    thr.addSuppressed(ioe);
                                 }
-                                out.close();
-                                out = null;
-                                return new URLJarFile(tmpFile, closeController);
-                            } catch (IOException e) {
-                                if (tmpFile != null) {
-                                    tmpFile.delete();
-                                }
-                                throw e;
-                            } finally {
-                                if (in != null) {
-                                    in.close();
-                                }
-                                if (out != null) {
-                                    out.close();
-                                }
+                                throw thr;
                             }
                         }
                     });
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Mar 03 07:02:30 2011 -0800
@@ -51,6 +51,7 @@
     // File access mode (immutable)
     private final boolean writable;
     private final boolean readable;
+    private final boolean append;
 
     // Required to prevent finalization of creating stream (immutable)
     private final Object parent;
@@ -67,6 +68,7 @@
         this.fd = fd;
         this.readable = readable;
         this.writable = writable;
+        this.append = append;
         this.parent = parent;
         this.nd = new FileDispatcherImpl(append);
     }
@@ -242,7 +244,8 @@
                 if (!isOpen())
                     return 0;
                 do {
-                    p = position0(fd, -1);
+                    // in append-mode then position is advanced to end before writing
+                    p = (append) ? nd.size(fd) : position0(fd, -1);
                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(p);
             } finally {
--- a/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java	Thu Mar 03 07:02:30 2011 -0800
@@ -87,6 +87,7 @@
                                 gssLibs = new String[]{
                                     "libgssapi.so",
                                     "libgssapi_krb5.so",
+                                    "libgssapi_krb5.so.2",
                                 };
                             }
                         } else {
--- a/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Thu Mar 03 07:02:30 2011 -0800
@@ -231,13 +231,6 @@
         AdaptableX509CertSelector issuerSelector =
                         new AdaptableX509CertSelector();
 
-        // check trusted certificate's key usage
-        boolean[] usages = trustedCert.getKeyUsage();
-        if (usages != null) {
-            usages[5] = true;    // keyCertSign
-            issuerSelector.setKeyUsage(usages);
-        }
-
         // check trusted certificate's subject
         issuerSelector.setSubject(firstCert.getIssuerX500Principal());
 
--- a/src/share/classes/sun/security/util/SignatureFileVerifier.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/security/util/SignatureFileVerifier.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -181,7 +181,8 @@
      *
      *
      */
-    public void process(Hashtable<String, CodeSigner[]> signers)
+    public void process(Hashtable<String, CodeSigner[]> signers,
+            List manifestDigests)
         throws IOException, SignatureException, NoSuchAlgorithmException,
             JarException, CertificateException
     {
@@ -190,14 +191,15 @@
         Object obj = null;
         try {
             obj = Providers.startJarVerification();
-            processImpl(signers);
+            processImpl(signers, manifestDigests);
         } finally {
             Providers.stopJarVerification(obj);
         }
 
     }
 
-    private void processImpl(Hashtable<String, CodeSigner[]> signers)
+    private void processImpl(Hashtable<String, CodeSigner[]> signers,
+            List manifestDigests)
         throws IOException, SignatureException, NoSuchAlgorithmException,
             JarException, CertificateException
     {
@@ -232,7 +234,7 @@
                                 sf.getEntries().entrySet().iterator();
 
         // see if we can verify the whole manifest first
-        boolean manifestSigned = verifyManifestHash(sf, md, decoder);
+        boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests);
 
         // verify manifest main attributes
         if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) {
@@ -275,7 +277,8 @@
      */
     private boolean verifyManifestHash(Manifest sf,
                                        ManifestDigester md,
-                                       BASE64Decoder decoder)
+                                       BASE64Decoder decoder,
+                                       List manifestDigests)
          throws IOException
     {
         Attributes mattr = sf.getMainAttributes();
@@ -290,6 +293,8 @@
                 // 16 is length of "-Digest-Manifest"
                 String algorithm = key.substring(0, key.length()-16);
 
+                manifestDigests.add(key);
+                manifestDigests.add(se.getValue());
                 MessageDigest digest = getDigest(algorithm);
                 if (digest != null) {
                     byte[] computedHash = md.manifestDigest(digest);
--- a/src/share/classes/sun/tools/jps/Jps.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/tools/jps/Jps.java	Thu Mar 03 07:02:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,9 +77,52 @@
                 MonitoredVm vm = null;
                 String vmidString = "//" + lvmid + "?mode=r";
 
+                String errorString = null;
+
                 try {
+                    // Note: The VM associated with the current VM id may
+                    // no longer be running so these queries may fail. We
+                    // already added the VM id to the output stream above.
+                    // If one of the queries fails, then we try to add a
+                    // reasonable message to indicate that the requested
+                    // info is not available.
+
+                    errorString = " -- process information unavailable";
                     VmIdentifier id = new VmIdentifier(vmidString);
                     vm = monitoredHost.getMonitoredVm(id, 0);
+
+                    errorString = " -- main class information unavailable";
+                    output.append(" " + MonitoredVmUtil.mainClass(vm,
+                            arguments.showLongPaths()));
+
+                    if (arguments.showMainArgs()) {
+                        errorString = " -- main args information unavailable";
+                        String mainArgs = MonitoredVmUtil.mainArgs(vm);
+                        if (mainArgs != null && mainArgs.length() > 0) {
+                            output.append(" " + mainArgs);
+                        }
+                    }
+                    if (arguments.showVmArgs()) {
+                        errorString = " -- jvm args information unavailable";
+                        String jvmArgs = MonitoredVmUtil.jvmArgs(vm);
+                        if (jvmArgs != null && jvmArgs.length() > 0) {
+                          output.append(" " + jvmArgs);
+                        }
+                    }
+                    if (arguments.showVmFlags()) {
+                        errorString = " -- jvm flags information unavailable";
+                        String jvmFlags = MonitoredVmUtil.jvmFlags(vm);
+                        if (jvmFlags != null && jvmFlags.length() > 0) {
+                            output.append(" " + jvmFlags);
+                        }
+                    }
+
+                    errorString = " -- detach failed";
+                    monitoredHost.detach(vm);
+
+                    System.out.println(output);
+
+                    errorString = null;
                 } catch (URISyntaxException e) {
                     // unexpected as vmidString is based on a validated hostid
                     lastError = e;
@@ -87,7 +130,7 @@
                 } catch (Exception e) {
                     lastError = e;
                 } finally {
-                    if (vm == null) {
+                    if (errorString != null) {
                         /*
                          * we ignore most exceptions, as there are race
                          * conditions where a JVM in 'jvms' may terminate
@@ -95,7 +138,7 @@
                          * Other errors, such as access and I/O exceptions
                          * should stop us from iterating over the complete set.
                          */
-                        output.append(" -- process information unavailable");
+                        output.append(errorString);
                         if (arguments.isDebug()) {
                             if ((lastError != null)
                                     && (lastError.getMessage() != null)) {
@@ -110,33 +153,6 @@
                         continue;
                     }
                 }
-
-                output.append(" ");
-                output.append(MonitoredVmUtil.mainClass(vm,
-                        arguments.showLongPaths()));
-
-                if (arguments.showMainArgs()) {
-                    String mainArgs = MonitoredVmUtil.mainArgs(vm);
-                    if (mainArgs != null && mainArgs.length() > 0) {
-                        output.append(" ").append(mainArgs);
-                    }
-                }
-                if (arguments.showVmArgs()) {
-                    String jvmArgs = MonitoredVmUtil.jvmArgs(vm);
-                    if (jvmArgs != null && jvmArgs.length() > 0) {
-                      output.append(" ").append(jvmArgs);
-                    }
-                }
-                if (arguments.showVmFlags()) {
-                    String jvmFlags = MonitoredVmUtil.jvmFlags(vm);
-                    if (jvmFlags != null && jvmFlags.length() > 0) {
-                        output.append(" ").append(jvmFlags);
-                    }
-                }
-
-                System.out.println(output);
-
-                monitoredHost.detach(vm);
             }
         } catch (MonitorException e) {
             if (e.getMessage() != null) {
--- a/src/share/classes/sun/util/resources/TimeZoneNames.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
         {"America/Nipigon", EST},
         {"America/Nome", AKST},
         {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
         {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
         {"America/Panama", EST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Thu Mar 03 07:02:30 2011 -0800
@@ -405,6 +405,7 @@
             {"America/Nipigon", EST},
             {"America/Nome", AKST},
             {"America/Noronha", NORONHA},
+            {"America/North_Dakota/Beulah", CST},
             {"America/North_Dakota/Center", CST},
             {"America/North_Dakota/New_Salem", CST},
             {"America/Ojinaga", MST},
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java	Thu Mar 03 07:02:30 2011 -0800
@@ -42,6 +42,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.zip.ZipError;
 import java.util.concurrent.ExecutorService;
 
 /*
@@ -78,39 +79,60 @@
         }
     }
 
+    private boolean ensureFile(Path path) {
+        try {
+            BasicFileAttributes attrs =
+                Files.readAttributes(path, BasicFileAttributes.class);
+            if (!attrs.isRegularFile())
+                throw new UnsupportedOperationException();
+            return true;
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
     @Override
     public FileSystem newFileSystem(URI uri, Map<String, ?> env)
         throws IOException
     {
-        return newFileSystem(uriToPath(uri), env, true);
+        Path path = uriToPath(uri);
+        synchronized(filesystems) {
+            Path realPath = null;
+            if (ensureFile(path)) {
+                realPath = path.toRealPath(true);
+                if (filesystems.containsKey(realPath))
+                    throw new FileSystemAlreadyExistsException();
+            }
+            ZipFileSystem zipfs = null;
+            try {
+                zipfs = new ZipFileSystem(this, path, env);
+            } catch (ZipError ze) {
+                String pname = path.toString();
+                if (pname.endsWith(".zip") || pname.endsWith(".jar"))
+                    throw ze;
+                // assume NOT a zip/jar file
+                throw new UnsupportedOperationException();
+            }
+            filesystems.put(realPath, zipfs);
+            return zipfs;
+        }
     }
 
     @Override
     public FileSystem newFileSystem(Path path, Map<String, ?> env)
         throws IOException
     {
-        if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
+        if (path.getFileSystem() != FileSystems.getDefault()) {
             throw new UnsupportedOperationException();
         }
-        return newFileSystem(path, env, false);
-    }
-
-    private FileSystem newFileSystem(Path path, Map<String, ?> env, boolean checkIfFSExists)
-        throws IOException
-    {
-        synchronized(filesystems) {
-            Path realPath = null;
-            if (checkIfFSExists && Files.exists(path)) {
-                realPath = path.toRealPath(true);
-                if (filesystems.containsKey(realPath))
-                    throw new FileSystemAlreadyExistsException();
-            }
-            ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
-            if (realPath == null)
-                realPath = path.toRealPath(true);
-            if (!filesystems.containsKey(realPath))
-                filesystems.put(realPath, zipfs);
-            return zipfs;
+        ensureFile(path);
+        try {
+            return new ZipFileSystem(this, path, env);
+        } catch (ZipError ze) {
+            String pname = path.toString();
+            if (pname.endsWith(".zip") || pname.endsWith(".jar"))
+                throw ze;
+            throw new UnsupportedOperationException();
         }
     }
 
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Wed Mar 02 13:18:36 2011 -0800
+++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Thu Mar 03 07:02:30 2011 -0800
@@ -109,8 +109,8 @@
     jobject stream;            // ImageInputStream or ImageOutputStream
     jbyteArray hstreamBuffer;  // Handle to a Java buffer for the stream
     JOCTET *buf;               // Pinned buffer pointer */
-    int bufferOffset;          // holds offset between unpin and the next pin
-    int bufferLength;          // Allocated, nut just used
+    size_t bufferOffset;          // holds offset between unpin and the next pin
+    size_t bufferLength;          // Allocated, nut just used
     int suspendable;           // Set to true to suspend input
     long remaining_skip;       // Used only on input
 } streamBuffer, *streamBufferPtr;
@@ -129,7 +129,7 @@
  * Used to signal that no data need be restored from an unpin to a pin.
  * I.e. the buffer is empty.
  */
-#define NO_DATA -1
+#define NO_DATA ((size_t)-1)
 
 // Forward reference
 static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb);
@@ -389,7 +389,6 @@
 static imageIODataPtr initImageioData (JNIEnv *env,
                                        j_common_ptr cinfo,
                                        jobject obj) {
-    int i, j;
 
     imageIODataPtr data = (imageIODataPtr) malloc (sizeof(imageIOData));
     if (data == NULL) {
@@ -982,7 +981,7 @@
     streamBufferPtr sb = &data->streamBuf;
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
     jint ret;
-    int offset, buflen;
+    size_t offset, buflen;
 
     /*
      * The original (jpegdecoder.c) had code here that called
@@ -1520,7 +1519,7 @@
         imageio_dispose((j_common_ptr)cinfo);
         return 0;
     }
-    return (jlong) ret;
+    return ptr_to_jlong(ret);
 }
 
 /*
@@ -1535,7 +1534,7 @@
      jlong ptr,
      jobject source) {
 
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_common_ptr cinfo;
 
     if (data == NULL) {
@@ -1574,7 +1573,7 @@
     int h_samp0, h_samp1, h_samp2;
     int v_samp0, v_samp1, v_samp2;
     jboolean retval = JNI_FALSE;
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_decompress_ptr cinfo;
     struct jpeg_source_mgr *src;
     sun_jpeg_error_ptr jerr;
@@ -1772,7 +1771,7 @@
      jlong ptr,
      jint code) {
 
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_decompress_ptr cinfo;
 
     if (data == NULL) {
@@ -1814,7 +1813,7 @@
     struct jpeg_source_mgr *src;
     JSAMPROW scanLinePtr = NULL;
     jint bands[MAX_BANDS];
-    int i, j;
+    int i;
     jint *body;
     int scanlineLimit;
     int pixelStride;
@@ -1824,14 +1823,12 @@
     pixelBufferPtr pb;
     sun_jpeg_error_ptr jerr;
     boolean done;
-    jint *bandSize;
-    int maxBandValue, halfMaxBandValue;
     boolean mustScale = FALSE;
     boolean progressive = FALSE;
     boolean orderedBands = TRUE;
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_decompress_ptr cinfo;
-    unsigned int numBytes;
+    size_t numBytes;
 
     /* verify the inputs */
 
@@ -1849,7 +1846,7 @@
 
     cinfo = (j_decompress_ptr) data->jpegObj;
 
-    if ((numBands < 1) ||
+    if ((numBands < 1) || (numBands > MAX_BANDS) ||
         (sourceXStart < 0) || (sourceXStart >= (jint)cinfo->image_width) ||
         (sourceYStart < 0) || (sourceYStart >= (jint)cinfo->image_height) ||
         (sourceWidth < 1) || (sourceWidth > (jint)cinfo->image_width) ||
@@ -1863,10 +1860,10 @@
         return JNI_FALSE;
     }
 
-    if (stepX > cinfo->image_width) {
+    if (stepX > (jint)cinfo->image_width) {
         stepX = cinfo->image_width;
     }
-    if (stepY > cinfo->image_height) {
+    if (stepY > (jint)cinfo->image_height) {
         stepY = cinfo->image_height;
     }
 
@@ -2119,7 +2116,7 @@
      jobject this,
      jlong ptr) {
 
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
 
     if (data == NULL) {
         JNU_ThrowByName(env,
@@ -2137,7 +2134,7 @@
     (JNIEnv *env,
      jobject this,
      jlong ptr) {
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_decompress_ptr cinfo;
 
     if (data == NULL) {
@@ -2159,7 +2156,7 @@
      jobject this,
      jlong ptr) {
 
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_decompress_ptr cinfo;
     sun_jpeg_error_ptr jerr;
 
@@ -2232,7 +2229,7 @@
      jclass reader,
      jlong ptr) {
 
-    imageIODataPtr data = (imageIODataPtr) ptr;
+    imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_common_ptr info = destroyImageioData(env, data);
 
     imageio_dispose(info);
@@ -2317,8 +2314,8 @@
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
     /* find out how much needs to be written */
-    jint datacount = sb->bufferLength - dest->free_in_buffer;
-
+    /* this conversion from size_t to jint is safe, because the lenght of the buffer is limited by jint */
+    jint datacount = (jint)(sb->bufferLength - dest->free_in_buffer);
     if (datacount != 0) {
         RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
 
@@ -2485,7 +2482,7 @@
         imageio_dispose((j_common_ptr)cinfo);
         return 0;
     }
-    return (jlong) ret;