Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
5bb0a44f
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
5bb0a44f
编写于
1月 28, 2012
作者:
L
lana
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
2c176d80
d627c9da
变更
31
隐藏空白更改
内联
并排
Showing
31 changed file
with
1474 addition
and
229 deletion
+1474
-229
.hgtags
.hgtags
+2
-0
make/javax/sound/jsoundalsa/Makefile
make/javax/sound/jsoundalsa/Makefile
+1
-1
make/sun/awt/Makefile
make/sun/awt/Makefile
+2
-1
src/share/classes/com/sun/beans/TypeResolver.java
src/share/classes/com/sun/beans/TypeResolver.java
+15
-4
src/share/classes/java/awt/AWTKeyStroke.java
src/share/classes/java/awt/AWTKeyStroke.java
+4
-1
src/share/classes/java/lang/Class.java
src/share/classes/java/lang/Class.java
+5
-0
src/share/classes/java/lang/ClassValue.java
src/share/classes/java/lang/ClassValue.java
+576
-64
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
+4
-0
src/share/classes/java/lang/invoke/MemberName.java
src/share/classes/java/lang/invoke/MemberName.java
+1
-1
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+30
-31
src/share/classes/java/lang/invoke/MethodHandleProxies.java
src/share/classes/java/lang/invoke/MethodHandleProxies.java
+1
-1
src/share/classes/java/lang/invoke/MethodHandles.java
src/share/classes/java/lang/invoke/MethodHandles.java
+13
-6
src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
+16
-14
src/share/classes/sun/invoke/util/ValueConversions.java
src/share/classes/sun/invoke/util/ValueConversions.java
+4
-4
src/share/classes/sun/invoke/util/Wrapper.java
src/share/classes/sun/invoke/util/Wrapper.java
+2
-2
src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java
src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java
+6
-3
src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
+10
-1
test/java/lang/invoke/CallSiteTest.java
test/java/lang/invoke/CallSiteTest.java
+1
-1
test/java/lang/invoke/ClassValueTest.java
test/java/lang/invoke/ClassValueTest.java
+10
-12
test/java/lang/invoke/InvokeGenericTest.java
test/java/lang/invoke/InvokeGenericTest.java
+18
-16
test/java/lang/invoke/JavaDocExamplesTest.java
test/java/lang/invoke/JavaDocExamplesTest.java
+2
-0
test/java/lang/invoke/MethodHandlesTest.java
test/java/lang/invoke/MethodHandlesTest.java
+48
-41
test/java/lang/invoke/MethodTypeTest.java
test/java/lang/invoke/MethodTypeTest.java
+3
-2
test/java/lang/invoke/PermuteArgsTest.java
test/java/lang/invoke/PermuteArgsTest.java
+7
-7
test/java/lang/invoke/RicochetTest.java
test/java/lang/invoke/RicochetTest.java
+9
-9
test/java/lang/invoke/ThrowExceptionsTest.java
test/java/lang/invoke/ThrowExceptionsTest.java
+3
-3
test/javax/swing/JSplitPane/4885629/bug4885629.java
test/javax/swing/JSplitPane/4885629/bug4885629.java
+115
-0
test/javax/swing/JTextArea/4697612/bug4697612.java
test/javax/swing/JTextArea/4697612/bug4697612.java
+208
-0
test/javax/swing/JTextArea/4697612/bug4697612.txt
test/javax/swing/JTextArea/4697612/bug4697612.txt
+223
-0
test/javax/swing/JTree/6505523/bug6505523.java
test/javax/swing/JTree/6505523/bug6505523.java
+132
-0
test/sun/invoke/util/ValueConversionsTest.java
test/sun/invoke/util/ValueConversionsTest.java
+3
-4
未找到文件。
.hgtags
浏览文件 @
5bb0a44f
...
...
@@ -143,3 +143,5 @@ b71d1acfae5240d8c1359443cd02b5ddb587231c jdk8-b17
3778f85773055e81eab6c5ef828935ecca241810 jdk8-b19
39e938cd1b82ec3aab0a9aa66fd8a0457cd0c9c2 jdk8-b20
664fa4fb0ee411ef048903c479f8b962fcdb2f4b jdk8-b21
dda27c73d8db4a9c7a23872b6f0c5106edcb2021 jdk8-b22
54202e0148ec7d4570cab5bc9b00d216a7677569 jdk8-b23
make/javax/sound/jsoundalsa/Makefile
浏览文件 @
5bb0a44f
...
...
@@ -65,7 +65,7 @@ FILES_export = \
$(MIDIFILES_export)
\
$(PORTFILES_export)
LDFLAG
S
+=
-lasound
OTHER_LDLIB
S
+=
-lasound
CPPFLAGS
+=
\
-DUSE_DAUDIO
=
TRUE
\
...
...
make/sun/awt/Makefile
浏览文件 @
5bb0a44f
...
...
@@ -367,7 +367,8 @@ else
FONTCONFIGS_SRC
=
$(CLOSED_SRC)
/solaris/classes/sun/awt/fontconfigs
_FONTCONFIGS
=
\
fontconfig.properties
\
fontconfig.RedHat.5.5.properties
\
fontconfig.RedHat.5.properties
\
fontconfig.RedHat.6.properties
\
fontconfig.Turbo.properties
\
fontconfig.SuSE.10.properties
\
fontconfig.SuSE.11.properties
...
...
src/share/classes/com/sun/beans/TypeResolver.java
浏览文件 @
5bb0a44f
...
...
@@ -154,7 +154,7 @@ public final class TypeResolver {
* @see #resolve(Type)
*/
public
static
Type
resolve
(
Type
actual
,
Type
formal
)
{
return
new
TypeResolver
(
actual
).
resolve
(
formal
);
return
get
TypeResolver
(
actual
).
resolve
(
formal
);
}
/**
...
...
@@ -169,7 +169,7 @@ public final class TypeResolver {
* @see #resolve(Type[])
*/
public
static
Type
[]
resolve
(
Type
actual
,
Type
[]
formals
)
{
return
new
TypeResolver
(
actual
).
resolve
(
formals
);
return
get
TypeResolver
(
actual
).
resolve
(
formals
);
}
/**
...
...
@@ -228,9 +228,20 @@ public final class TypeResolver {
return
classes
;
}
public
static
TypeResolver
getTypeResolver
(
Type
type
)
{
synchronized
(
CACHE
)
{
TypeResolver
resolver
=
CACHE
.
get
(
type
);
if
(
resolver
==
null
)
{
resolver
=
new
TypeResolver
(
type
);
CACHE
.
put
(
type
,
resolver
);
}
return
resolver
;
}
}
private
static
final
WeakCache
<
Type
,
TypeResolver
>
CACHE
=
new
WeakCache
<>();
private
final
Map
<
TypeVariable
<?>,
Type
>
map
=
new
HashMap
<
TypeVariable
<?>,
Type
>();
private
final
Map
<
TypeVariable
<?>,
Type
>
map
=
new
HashMap
<>();
/**
* Constructs the type resolver for the given actual type.
...
...
src/share/classes/java/awt/AWTKeyStroke.java
浏览文件 @
5bb0a44f
...
...
@@ -802,8 +802,11 @@ public class AWTKeyStroke implements Serializable {
*/
protected
Object
readResolve
()
throws
java
.
io
.
ObjectStreamException
{
synchronized
(
AWTKeyStroke
.
class
)
{
return
getCachedStroke
(
keyChar
,
keyCode
,
modifiers
,
onKeyRelease
);
if
(
getClass
().
equals
(
getAWTKeyStrokeClass
()))
{
return
getCachedStroke
(
keyChar
,
keyCode
,
modifiers
,
onKeyRelease
);
}
}
return
this
;
}
private
static
int
mapOldModifiers
(
int
modifiers
)
{
...
...
src/share/classes/java/lang/Class.java
浏览文件 @
5bb0a44f
...
...
@@ -3118,4 +3118,9 @@ public final
AnnotationType
getAnnotationType
()
{
return
annotationType
;
}
/* Backing store of user-defined values pertaining to this class.
* Maintained by the ClassValue class.
*/
transient
ClassValue
.
ClassValueMap
classValueMap
;
}
src/share/classes/java/lang/ClassValue.java
浏览文件 @
5bb0a44f
...
...
@@ -25,9 +25,14 @@
package
java.lang
;
import
java.lang.ClassValue.ClassValueMap
;
import
java.util.WeakHashMap
;
import
java.lang.ref.WeakReference
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
static
java
.
lang
.
ClassValue
.
ClassValueMap
.
probeHomeLocation
;
import
static
java
.
lang
.
ClassValue
.
ClassValueMap
.
probeBackupLocations
;
/**
* Lazily associate a computed value with (potentially) every type.
* For example, if a dynamic language needs to construct a message dispatch
...
...
@@ -92,14 +97,22 @@ public abstract class ClassValue<T> {
* @see #computeValue
*/
public
T
get
(
Class
<?>
type
)
{
ClassValueMap
map
=
getMap
(
type
);
if
(
map
!=
null
)
{
Object
x
=
map
.
get
(
this
);
if
(
x
!=
null
)
{
return
(
T
)
map
.
unmaskNull
(
x
);
}
}
return
setComputedValue
(
type
);
// non-racing this.hashCodeForCache : final int
Entry
<?>[]
cache
;
Entry
<
T
>
e
=
probeHomeLocation
(
cache
=
getCacheCarefully
(
type
),
this
);
// racing e : current value <=> stale value from current cache or from stale cache
// invariant: e is null or an Entry with readable Entry.version and Entry.value
if
(
match
(
e
))
// invariant: No false positive matches. False negatives are OK if rare.
// The key fact that makes this work: if this.version == e.version,
// then this thread has a right to observe (final) e.value.
return
e
.
value
();
// The fast path can fail for any of these reasons:
// 1. no entry has been computed yet
// 2. hash code collision (before or after reduction mod cache.length)
// 3. an entry has been removed (either on this type or another)
// 4. the GC has somehow managed to delete e.version and clear the reference
return
getFromBackup
(
cache
,
type
);
}
/**
...
...
@@ -157,83 +170,582 @@ public abstract class ClassValue<T> {
*/
public
void
remove
(
Class
<?>
type
)
{
ClassValueMap
map
=
getMap
(
type
);
if
(
map
!=
null
)
{
synchronized
(
map
)
{
map
.
remove
(
this
);
}
}
map
.
removeEntry
(
this
);
}
// Possible functionality for JSR 292 MR 1
/*public*/
void
put
(
Class
<?>
type
,
T
value
)
{
ClassValueMap
map
=
getMap
(
type
);
map
.
changeEntry
(
this
,
value
);
}
/// --------
/// Implementation...
// FIXME: Use a data structure here similar that of ThreadLocal (7030453).
/// --------
/** Return the cache, if it exists, else a dummy empty cache. */
private
static
Entry
<?>[]
getCacheCarefully
(
Class
<?>
type
)
{
// racing type.classValueMap{.cacheArray} : null => new Entry[X] <=> new Entry[Y]
ClassValueMap
map
=
type
.
classValueMap
;
if
(
map
==
null
)
return
EMPTY_CACHE
;
Entry
<?>[]
cache
=
map
.
getCache
();
return
cache
;
// invariant: returned value is safe to dereference and check for an Entry
}
/** Initial, one-element, empty cache used by all Class instances. Must never be filled. */
private
static
final
Entry
<?>[]
EMPTY_CACHE
=
{
null
};
/**
* Slow tail of ClassValue.get to retry at nearby locations in the cache,
* or take a slow lock and check the hash table.
* Called only if the first probe was empty or a collision.
* This is a separate method, so compilers can process it independently.
*/
private
T
getFromBackup
(
Entry
<?>[]
cache
,
Class
<?>
type
)
{
Entry
<
T
>
e
=
probeBackupLocations
(
cache
,
this
);
if
(
e
!=
null
)
return
e
.
value
();
return
getFromHashMap
(
type
);
}
private
static
final
AtomicInteger
STORE_BARRIER
=
new
AtomicInteger
();
// Hack to suppress warnings on the (T) cast, which is a no-op.
@SuppressWarnings
(
"unchecked"
)
Entry
<
T
>
castEntry
(
Entry
<?>
e
)
{
return
(
Entry
<
T
>)
e
;
}
/** Slow path for {@link #get}. */
private
T
setComputedValue
(
Class
<?>
type
)
{
/** Called when the fast path of get fails, and cache reprobe also fails.
*/
private
T
getFromHashMap
(
Class
<?>
type
)
{
// The fail-safe recovery is to fall back to the underlying classValueMap.
ClassValueMap
map
=
getMap
(
type
);
if
(
map
==
null
)
{
map
=
initializeMap
(
type
);
}
T
value
=
computeValue
(
type
);
STORE_BARRIER
.
lazySet
(
0
);
// All stores pending from computeValue are completed.
synchronized
(
map
)
{
// Warm up the table with a null entry.
map
.
preInitializeEntry
(
this
);
}
STORE_BARRIER
.
lazySet
(
0
);
// All stores pending from table expansion are completed.
synchronized
(
map
)
{
value
=
(
T
)
map
.
initializeEntry
(
this
,
value
);
// One might fear a possible race condition here
// if the code for map.put has flushed the write
// to map.table[*] before the writes to the Map.Entry
// are done. This is not possible, since we have
// warmed up the table with an empty entry.
}
return
value
;
for
(;;)
{
Entry
<
T
>
e
=
map
.
startEntry
(
this
);
if
(!
e
.
isPromise
())
return
e
.
value
();
try
{
// Try to make a real entry for the promised version.
e
=
makeEntry
(
e
.
version
(),
computeValue
(
type
));
}
finally
{
// Whether computeValue throws or returns normally,
// be sure to remove the empty entry.
e
=
map
.
finishEntry
(
this
,
e
);
}
if
(
e
!=
null
)
return
e
.
value
();
// else try again, in case a racing thread called remove (so e == null)
}
}
/** Check that e is non-null, matches this ClassValue, and is live. */
boolean
match
(
Entry
<?>
e
)
{
// racing e.version : null (blank) => unique Version token => null (GC-ed version)
// non-racing this.version : v1 => v2 => ... (updates are read faithfully from volatile)
return
(
e
!=
null
&&
e
.
get
()
==
this
.
version
);
// invariant: No false positives on version match. Null is OK for false negative.
// invariant: If version matches, then e.value is readable (final set in Entry.<init>)
}
/** Internal hash code for accessing Class.classValueMap.cacheArray. */
final
int
hashCodeForCache
=
nextHashCode
.
getAndAdd
(
HASH_INCREMENT
)
&
HASH_MASK
;
/** Value stream for hashCodeForCache. See similar structure in ThreadLocal. */
private
static
final
AtomicInteger
nextHashCode
=
new
AtomicInteger
();
/** Good for power-of-two tables. See similar structure in ThreadLocal. */
private
static
final
int
HASH_INCREMENT
=
0x61c88647
;
/** Mask a hash code to be positive but not too large, to prevent wraparound. */
static
final
int
HASH_MASK
=
(-
1
>>>
2
);
/**
* Private key for retrieval of this object from ClassValueMap.
*/
static
class
Identity
{
}
/**
* This ClassValue's identity, expressed as an opaque object.
* The main object {@code ClassValue.this} is incorrect since
* subclasses may override {@code ClassValue.equals}, which
* could confuse keys in the ClassValueMap.
*/
final
Identity
identity
=
new
Identity
();
// Replace this map by a per-class slot.
private
static
final
WeakHashMap
<
Class
<?>,
ClassValueMap
>
ROOT
=
new
WeakHashMap
<
Class
<?>,
ClassValueMap
>();
/**
* Current version for retrieving this class value from the cache.
* Any number of computeValue calls can be cached in association with one version.
* But the version changes when a remove (on any type) is executed.
* A version change invalidates all cache entries for the affected ClassValue,
* by marking them as stale. Stale cache entries do not force another call
* to computeValue, but they do require a synchronized visit to a backing map.
* <p>
* All user-visible state changes on the ClassValue take place under
* a lock inside the synchronized methods of ClassValueMap.
* Readers (of ClassValue.get) are notified of such state changes
* when this.version is bumped to a new token.
* This variable must be volatile so that an unsynchronized reader
* will receive the notification without delay.
* <p>
* If version were not volatile, one thread T1 could persistently hold onto
* a stale value this.value == V1, while while another thread T2 advances
* (under a lock) to this.value == V2. This will typically be harmless,
* but if T1 and T2 interact causally via some other channel, such that
* T1's further actions are constrained (in the JMM) to happen after
* the V2 event, then T1's observation of V1 will be an error.
* <p>
* The practical effect of making this.version be volatile is that it cannot
* be hoisted out of a loop (by an optimizing JIT) or otherwise cached.
* Some machines may also require a barrier instruction to execute
* before this.version.
*/
private
volatile
Version
<
T
>
version
=
new
Version
<>(
this
);
Version
<
T
>
version
()
{
return
version
;
}
void
bumpVersion
()
{
version
=
new
Version
<>(
this
);
}
static
class
Version
<
T
>
{
private
final
ClassValue
<
T
>
classValue
;
private
final
Entry
<
T
>
promise
=
new
Entry
<>(
this
);
Version
(
ClassValue
<
T
>
classValue
)
{
this
.
classValue
=
classValue
;
}
ClassValue
<
T
>
classValue
()
{
return
classValue
;
}
Entry
<
T
>
promise
()
{
return
promise
;
}
boolean
isLive
()
{
return
classValue
.
version
()
==
this
;
}
}
/** One binding of a value to a class via a ClassValue.
* States are:<ul>
* <li> promise if value == Entry.this
* <li> else dead if version == null
* <li> else stale if version != classValue.version
* <li> else live </ul>
* Promises are never put into the cache; they only live in the
* backing map while a computeValue call is in flight.
* Once an entry goes stale, it can be reset at any time
* into the dead state.
*/
static
class
Entry
<
T
>
extends
WeakReference
<
Version
<
T
>>
{
final
Object
value
;
// usually of type T, but sometimes (Entry)this
Entry
(
Version
<
T
>
version
,
T
value
)
{
super
(
version
);
this
.
value
=
value
;
// for a regular entry, value is of type T
}
private
void
assertNotPromise
()
{
assert
(!
isPromise
());
}
/** For creating a promise. */
Entry
(
Version
<
T
>
version
)
{
super
(
version
);
this
.
value
=
this
;
// for a promise, value is not of type T, but Entry!
}
/** Fetch the value. This entry must not be a promise. */
@SuppressWarnings
(
"unchecked"
)
// if !isPromise, type is T
T
value
()
{
assertNotPromise
();
return
(
T
)
value
;
}
boolean
isPromise
()
{
return
value
==
this
;
}
Version
<
T
>
version
()
{
return
get
();
}
ClassValue
<
T
>
classValueOrNull
()
{
Version
<
T
>
v
=
version
();
return
(
v
==
null
)
?
null
:
v
.
classValue
();
}
boolean
isLive
()
{
Version
<
T
>
v
=
version
();
if
(
v
==
null
)
return
false
;
if
(
v
.
isLive
())
return
true
;
clear
();
return
false
;
}
Entry
<
T
>
refreshVersion
(
Version
<
T
>
v2
)
{
assertNotPromise
();
@SuppressWarnings
(
"unchecked"
)
// if !isPromise, type is T
Entry
<
T
>
e2
=
new
Entry
<>(
v2
,
(
T
)
value
);
clear
();
// value = null -- caller must drop
return
e2
;
}
static
final
Entry
<?>
DEAD_ENTRY
=
new
Entry
<>(
null
,
null
);
}
/** Return the backing map associated with this type. */
private
static
ClassValueMap
getMap
(
Class
<?>
type
)
{
type
.
getClass
();
// test for null
return
ROOT
.
get
(
type
);
// racing type.classValueMap : null (blank) => unique ClassValueMap
// if a null is observed, a map is created (lazily, synchronously, uniquely)
// all further access to that map is synchronized
ClassValueMap
map
=
type
.
classValueMap
;
if
(
map
!=
null
)
return
map
;
return
initializeMap
(
type
);
}
private
static
final
Object
CRITICAL_SECTION
=
new
Object
();
private
static
ClassValueMap
initializeMap
(
Class
<?>
type
)
{
synchronized
(
ClassValue
.
class
)
{
ClassValueMap
map
=
ROOT
.
get
(
type
);
if
(
map
==
null
)
ROOT
.
put
(
type
,
map
=
new
ClassValueMap
());
ClassValueMap
map
;
synchronized
(
CRITICAL_SECTION
)
{
// private object to avoid deadlocks
// happens about once per type
if
((
map
=
type
.
classValueMap
)
==
null
)
type
.
classValueMap
=
map
=
new
ClassValueMap
(
type
);
}
return
map
;
}
static
<
T
>
Entry
<
T
>
makeEntry
(
Version
<
T
>
explicitVersion
,
T
value
)
{
// Note that explicitVersion might be different from this.version.
return
new
Entry
<>(
explicitVersion
,
value
);
// As soon as the Entry is put into the cache, the value will be
// reachable via a data race (as defined by the Java Memory Model).
// This race is benign, assuming the value object itself can be
// read safely by multiple threads. This is up to the user.
//
// The entry and version fields themselves can be safely read via
// a race because they are either final or have controlled states.
// If the pointer from the entry to the version is still null,
// or if the version goes immediately dead and is nulled out,
// the reader will take the slow path and retry under a lock.
}
static
class
ClassValueMap
extends
WeakHashMap
<
ClassValue
,
Object
>
{
/** Make sure this table contains an Entry for the given key, even if it is empty. */
void
preInitializeEntry
(
ClassValue
key
)
{
if
(!
this
.
containsKey
(
key
))
this
.
put
(
key
,
null
);
}
/** Make sure this table contains a non-empty Entry for the given key. */
Object
initializeEntry
(
ClassValue
key
,
Object
value
)
{
Object
prior
=
this
.
get
(
key
);
if
(
prior
!=
null
)
{
return
unmaskNull
(
prior
);
// The following class could also be top level and non-public:
/** A backing map for all ClassValues, relative a single given type.
* Gives a fully serialized "true state" for each pair (ClassValue cv, Class type).
* Also manages an unserialized fast-path cache.
*/
static
class
ClassValueMap
extends
WeakHashMap
<
ClassValue
.
Identity
,
Entry
<?>>
{
private
final
Class
<?>
type
;
private
Entry
<?>[]
cacheArray
;
private
int
cacheLoad
,
cacheLoadLimit
;
/** Number of entries initially allocated to each type when first used with any ClassValue.
* It would be pointless to make this much smaller than the Class and ClassValueMap objects themselves.
* Must be a power of 2.
*/
private
static
final
int
INITIAL_ENTRIES
=
32
;
/** Build a backing map for ClassValues, relative the given type.
* Also, create an empty cache array and install it on the class.
*/
ClassValueMap
(
Class
<?>
type
)
{
this
.
type
=
type
;
sizeCache
(
INITIAL_ENTRIES
);
}
Entry
<?>[]
getCache
()
{
return
cacheArray
;
}
/** Initiate a query. Store a promise (placeholder) if there is no value yet. */
synchronized
<
T
>
Entry
<
T
>
startEntry
(
ClassValue
<
T
>
classValue
)
{
@SuppressWarnings
(
"unchecked"
)
// one map has entries for all value types <T>
Entry
<
T
>
e
=
(
Entry
<
T
>)
get
(
classValue
.
identity
);
Version
<
T
>
v
=
classValue
.
version
();
if
(
e
==
null
)
{
e
=
v
.
promise
();
// The presence of a promise means that a value is pending for v.
// Eventually, finishEntry will overwrite the promise.
put
(
classValue
.
identity
,
e
);
// Note that the promise is never entered into the cache!
return
e
;
}
else
if
(
e
.
isPromise
())
{
// Somebody else has asked the same question.
// Let the races begin!
if
(
e
.
version
()
!=
v
)
{
e
=
v
.
promise
();
put
(
classValue
.
identity
,
e
);
}
return
e
;
}
else
{
// there is already a completed entry here; report it
if
(
e
.
version
()
!=
v
)
{
// There is a stale but valid entry here; make it fresh again.
// Once an entry is in the hash table, we don't care what its version is.
e
=
e
.
refreshVersion
(
v
);
put
(
classValue
.
identity
,
e
);
}
// Add to the cache, to enable the fast path, next time.
checkCacheLoad
();
addToCache
(
classValue
,
e
);
return
e
;
}
}
/** Finish a query. Overwrite a matching placeholder. Drop stale incoming values. */
synchronized
<
T
>
Entry
<
T
>
finishEntry
(
ClassValue
<
T
>
classValue
,
Entry
<
T
>
e
)
{
@SuppressWarnings
(
"unchecked"
)
// one map has entries for all value types <T>
Entry
<
T
>
e0
=
(
Entry
<
T
>)
get
(
classValue
.
identity
);
if
(
e
==
e0
)
{
// We can get here during exception processing, unwinding from computeValue.
assert
(
e
.
isPromise
());
remove
(
classValue
.
identity
);
return
null
;
}
else
if
(
e0
!=
null
&&
e0
.
isPromise
()
&&
e0
.
version
()
==
e
.
version
())
{
// If e0 matches the intended entry, there has not been a remove call
// between the previous startEntry and now. So now overwrite e0.
Version
<
T
>
v
=
classValue
.
version
();
if
(
e
.
version
()
!=
v
)
e
=
e
.
refreshVersion
(
v
);
put
(
classValue
.
identity
,
e
);
// Add to the cache, to enable the fast path, next time.
checkCacheLoad
();
addToCache
(
classValue
,
e
);
return
e
;
}
else
{
// Some sort of mismatch; caller must try again.
return
null
;
}
}
/** Remove an entry. */
synchronized
void
removeEntry
(
ClassValue
<?>
classValue
)
{
// make all cache elements for this guy go stale:
if
(
remove
(
classValue
.
identity
)
!=
null
)
{
classValue
.
bumpVersion
();
removeStaleEntries
(
classValue
);
}
}
/** Change the value for an entry. */
synchronized
<
T
>
void
changeEntry
(
ClassValue
<
T
>
classValue
,
T
value
)
{
@SuppressWarnings
(
"unchecked"
)
// one map has entries for all value types <T>
Entry
<
T
>
e0
=
(
Entry
<
T
>)
get
(
classValue
.
identity
);
Version
<
T
>
version
=
classValue
.
version
();
if
(
e0
!=
null
)
{
if
(
e0
.
version
()
==
version
&&
e0
.
value
()
==
value
)
// no value change => no version change needed
return
;
classValue
.
bumpVersion
();
removeStaleEntries
(
classValue
);
}
Entry
<
T
>
e
=
makeEntry
(
version
,
value
);
put
(
classValue
.
identity
,
e
);
// Add to the cache, to enable the fast path, next time.
checkCacheLoad
();
addToCache
(
classValue
,
e
);
}
/// --------
/// Cache management.
/// --------
// Statics do not need synchronization.
/** Load the cache entry at the given (hashed) location. */
static
Entry
<?>
loadFromCache
(
Entry
<?>[]
cache
,
int
i
)
{
// non-racing cache.length : constant
// racing cache[i & (mask)] : null <=> Entry
return
cache
[
i
&
(
cache
.
length
-
1
)];
// invariant: returned value is null or well-constructed (ready to match)
}
/** Look in the cache, at the home location for the given ClassValue. */
static
<
T
>
Entry
<
T
>
probeHomeLocation
(
Entry
<?>[]
cache
,
ClassValue
<
T
>
classValue
)
{
return
classValue
.
castEntry
(
loadFromCache
(
cache
,
classValue
.
hashCodeForCache
));
}
/** Given that first probe was a collision, retry at nearby locations. */
static
<
T
>
Entry
<
T
>
probeBackupLocations
(
Entry
<?>[]
cache
,
ClassValue
<
T
>
classValue
)
{
if
(
PROBE_LIMIT
<=
0
)
return
null
;
// Probe the cache carefully, in a range of slots.
int
mask
=
(
cache
.
length
-
1
);
int
home
=
(
classValue
.
hashCodeForCache
&
mask
);
Entry
<?>
e2
=
cache
[
home
];
// victim, if we find the real guy
if
(
e2
==
null
)
{
return
null
;
// if nobody is at home, no need to search nearby
}
// assume !classValue.match(e2), but do not assert, because of races
int
pos2
=
-
1
;
for
(
int
i
=
home
+
1
;
i
<
home
+
PROBE_LIMIT
;
i
++)
{
Entry
<?>
e
=
cache
[
i
&
mask
];
if
(
e
==
null
)
{
break
;
// only search within non-null runs
}
if
(
classValue
.
match
(
e
))
{
// relocate colliding entry e2 (from cache[home]) to first empty slot
cache
[
home
]
=
e
;
if
(
pos2
>=
0
)
{
cache
[
i
&
mask
]
=
Entry
.
DEAD_ENTRY
;
}
else
{
pos2
=
i
;
}
cache
[
pos2
&
mask
]
=
((
entryDislocation
(
cache
,
pos2
,
e2
)
<
PROBE_LIMIT
)
?
e2
// put e2 here if it fits
:
Entry
.
DEAD_ENTRY
);
return
classValue
.
castEntry
(
e
);
}
// Remember first empty slot, if any:
if
(!
e
.
isLive
()
&&
pos2
<
0
)
pos2
=
i
;
}
this
.
put
(
key
,
maskNull
(
value
));
return
value
;
return
null
;
}
Object
maskNull
(
Object
x
)
{
return
x
==
null
?
this
:
x
;
/** How far out of place is e? */
private
static
int
entryDislocation
(
Entry
<?>[]
cache
,
int
pos
,
Entry
<?>
e
)
{
ClassValue
<?>
cv
=
e
.
classValueOrNull
();
if
(
cv
==
null
)
return
0
;
// entry is not live!
int
mask
=
(
cache
.
length
-
1
);
return
(
pos
-
cv
.
hashCodeForCache
)
&
mask
;
}
Object
unmaskNull
(
Object
x
)
{
return
x
==
this
?
null
:
x
;
/// --------
/// Below this line all functions are private, and assume synchronized access.
/// --------
private
void
sizeCache
(
int
length
)
{
assert
((
length
&
(
length
-
1
))
==
0
);
// must be power of 2
cacheLoad
=
0
;
cacheLoadLimit
=
(
int
)
((
double
)
length
*
CACHE_LOAD_LIMIT
/
100
);
cacheArray
=
new
Entry
<?>[
length
];
}
/** Make sure the cache load stays below its limit, if possible. */
private
void
checkCacheLoad
()
{
if
(
cacheLoad
>=
cacheLoadLimit
)
{
reduceCacheLoad
();
}
}
private
void
reduceCacheLoad
()
{
removeStaleEntries
();
if
(
cacheLoad
<
cacheLoadLimit
)
return
;
// win
Entry
<?>[]
oldCache
=
getCache
();
if
(
oldCache
.
length
>
HASH_MASK
)
return
;
// lose
sizeCache
(
oldCache
.
length
*
2
);
for
(
Entry
<?>
e
:
oldCache
)
{
if
(
e
!=
null
&&
e
.
isLive
())
{
addToCache
(
e
);
}
}
}
/** Remove stale entries in the given range.
* Should be executed under a Map lock.
*/
private
void
removeStaleEntries
(
Entry
<?>[]
cache
,
int
begin
,
int
count
)
{
if
(
PROBE_LIMIT
<=
0
)
return
;
int
mask
=
(
cache
.
length
-
1
);
int
removed
=
0
;
for
(
int
i
=
begin
;
i
<
begin
+
count
;
i
++)
{
Entry
<?>
e
=
cache
[
i
&
mask
];
if
(
e
==
null
||
e
.
isLive
())
continue
;
// skip null and live entries
Entry
<?>
replacement
=
null
;
if
(
PROBE_LIMIT
>
1
)
{
// avoid breaking up a non-null run
replacement
=
findReplacement
(
cache
,
i
);
}
cache
[
i
&
mask
]
=
replacement
;
if
(
replacement
==
null
)
removed
+=
1
;
}
cacheLoad
=
Math
.
max
(
0
,
cacheLoad
-
removed
);
}
/** Clearing a cache slot risks disconnecting following entries
* from the head of a non-null run, which would allow them
* to be found via reprobes. Find an entry after cache[begin]
* to plug into the hole, or return null if none is needed.
*/
private
Entry
<?>
findReplacement
(
Entry
<?>[]
cache
,
int
home1
)
{
Entry
<?>
replacement
=
null
;
int
haveReplacement
=
-
1
,
replacementPos
=
0
;
int
mask
=
(
cache
.
length
-
1
);
for
(
int
i2
=
home1
+
1
;
i2
<
home1
+
PROBE_LIMIT
;
i2
++)
{
Entry
<?>
e2
=
cache
[
i2
&
mask
];
if
(
e2
==
null
)
break
;
// End of non-null run.
if
(!
e2
.
isLive
())
continue
;
// Doomed anyway.
int
dis2
=
entryDislocation
(
cache
,
i2
,
e2
);
if
(
dis2
==
0
)
continue
;
// e2 already optimally placed
int
home2
=
i2
-
dis2
;
if
(
home2
<=
home1
)
{
// e2 can replace entry at cache[home1]
if
(
home2
==
home1
)
{
// Put e2 exactly where he belongs.
haveReplacement
=
1
;
replacementPos
=
i2
;
replacement
=
e2
;
}
else
if
(
haveReplacement
<=
0
)
{
haveReplacement
=
0
;
replacementPos
=
i2
;
replacement
=
e2
;
}
// And keep going, so we can favor larger dislocations.
}
}
if
(
haveReplacement
>=
0
)
{
if
(
cache
[(
replacementPos
+
1
)
&
mask
]
!=
null
)
{
// Be conservative, to avoid breaking up a non-null run.
cache
[
replacementPos
&
mask
]
=
(
Entry
<?>)
Entry
.
DEAD_ENTRY
;
}
else
{
cache
[
replacementPos
&
mask
]
=
null
;
cacheLoad
-=
1
;
}
}
return
replacement
;
}
/** Remove stale entries in the range near classValue. */
private
void
removeStaleEntries
(
ClassValue
<?>
classValue
)
{
removeStaleEntries
(
getCache
(),
classValue
.
hashCodeForCache
,
PROBE_LIMIT
);
}
/** Remove all stale entries, everywhere. */
private
void
removeStaleEntries
()
{
Entry
[]
cache
=
getCache
();
removeStaleEntries
(
cache
,
0
,
cache
.
length
+
PROBE_LIMIT
-
1
);
}
/** Add the given entry to the cache, in its home location, unless it is out of date. */
private
<
T
>
void
addToCache
(
Entry
<
T
>
e
)
{
ClassValue
<
T
>
classValue
=
e
.
classValueOrNull
();
if
(
classValue
!=
null
)
addToCache
(
classValue
,
e
);
}
/** Add the given entry to the cache, in its home location. */
private
<
T
>
void
addToCache
(
ClassValue
<
T
>
classValue
,
Entry
<
T
>
e
)
{
if
(
PROBE_LIMIT
<=
0
)
return
;
// do not fill cache
// Add e to the cache.
Entry
<?>[]
cache
=
getCache
();
int
mask
=
(
cache
.
length
-
1
);
int
home
=
classValue
.
hashCodeForCache
&
mask
;
Entry
<?>
e2
=
placeInCache
(
cache
,
home
,
e
,
false
);
if
(
e2
==
null
)
return
;
// done
if
(
PROBE_LIMIT
>
1
)
{
// try to move e2 somewhere else in his probe range
int
dis2
=
entryDislocation
(
cache
,
home
,
e2
);
int
home2
=
home
-
dis2
;
for
(
int
i2
=
home2
;
i2
<
home2
+
PROBE_LIMIT
;
i2
++)
{
if
(
placeInCache
(
cache
,
i2
&
mask
,
e2
,
true
)
==
null
)
{
return
;
}
}
}
// Note: At this point, e2 is just dropped from the cache.
}
/** Store the given entry. Update cacheLoad, and return any live victim.
* 'Gently' means return self rather than dislocating a live victim.
*/
private
Entry
<?>
placeInCache
(
Entry
<?>[]
cache
,
int
pos
,
Entry
<?>
e
,
boolean
gently
)
{
Entry
<?>
e2
=
overwrittenEntry
(
cache
[
pos
]);
if
(
gently
&&
e2
!=
null
)
{
// do not overwrite a live entry
return
e
;
}
else
{
cache
[
pos
]
=
e
;
return
e2
;
}
}
/** Note an entry that is about to be overwritten.
* If it is not live, quietly replace it by null.
* If it is an actual null, increment cacheLoad,
* because the caller is going to store something
* in its place.
*/
private
<
T
>
Entry
<
T
>
overwrittenEntry
(
Entry
<
T
>
e2
)
{
if
(
e2
==
null
)
cacheLoad
+=
1
;
else
if
(
e2
.
isLive
())
return
e2
;
return
null
;
}
/** Percent loading of cache before resize. */
private
static
final
int
CACHE_LOAD_LIMIT
=
67
;
// 0..100
/** Maximum number of probes to attempt. */
private
static
final
int
PROBE_LIMIT
=
6
;
// 1..
// N.B. Set PROBE_LIMIT=0 to disable all fast paths.
}
}
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
浏览文件 @
5bb0a44f
...
...
@@ -378,6 +378,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
}
/** Construct an adapter conversion descriptor for a single-argument conversion. */
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeConv
(
int
convOp
,
int
argnum
,
int
src
,
int
dest
)
{
assert
(
src
==
(
src
&
CONV_TYPE_MASK
));
assert
(
dest
==
(
dest
&
CONV_TYPE_MASK
));
...
...
@@ -390,6 +391,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
insertStackMove
(
stackMove
)
);
}
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeDupConv
(
int
convOp
,
int
argnum
,
int
stackMove
)
{
// simple argument motion, requiring one slot to specify
assert
(
convOp
==
OP_DUP_ARGS
||
convOp
==
OP_DROP_ARGS
);
...
...
@@ -401,6 +403,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
insertStackMove
(
stackMove
)
);
}
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeSwapConv
(
int
convOp
,
int
srcArg
,
byte
srcType
,
int
destSlot
,
byte
destType
)
{
// more complex argument motion, requiring two slots to specify
assert
(
convOp
==
OP_SWAP_ARGS
||
convOp
==
OP_ROT_ARGS
);
...
...
@@ -411,6 +414,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
(
int
)
destSlot
<<
CONV_VMINFO_SHIFT
);
}
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeSpreadConv
(
int
convOp
,
int
argnum
,
int
src
,
int
dest
,
int
stackMove
)
{
// spreading or collecting, at a particular slot location
assert
(
convOp
==
OP_SPREAD_ARGS
||
convOp
==
OP_COLLECT_ARGS
||
convOp
==
OP_FOLD_ARGS
);
...
...
src/share/classes/java/lang/invoke/MemberName.java
浏览文件 @
5bb0a44f
...
...
@@ -353,7 +353,7 @@ import static java.lang.invoke.MethodHandleStatics.*;
assert
(
isResolved
());
}
/** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */
public
MemberName
(
Constructor
ctor
)
{
public
MemberName
(
Constructor
<?>
ctor
)
{
Object
[]
typeInfo
=
{
void
.
class
,
ctor
.
getParameterTypes
()
};
init
(
ctor
.
getDeclaringClass
(),
CONSTRUCTOR_NAME
,
typeInfo
,
flagsMods
(
IS_CONSTRUCTOR
,
ctor
.
getModifiers
()));
// fill in vmtarget, vmindex while we have ctor in hand:
...
...
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
5bb0a44f
...
...
@@ -112,7 +112,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
assert
(
cookedConstructor
.
type
().
equals
(
ctype
));
ctype
=
ctype
.
dropParameterTypes
(
0
,
1
);
cookedConstructor
=
AdapterMethodHandle
.
makeCollectArguments
(
cookedConstructor
,
returner
,
0
,
true
);
MethodHandle
allocator
=
new
AllocateObject
(
allocateClass
);
AllocateObject
allocator
=
new
AllocateObject
(
allocateClass
);
// allocate() => new C(void)
assert
(
allocator
.
type
().
equals
(
MethodType
.
methodType
(
allocateClass
)));
ctype
=
ctype
.
dropParameterTypes
(
0
,
1
);
...
...
@@ -120,19 +120,19 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return
fold
;
}
static
final
class
AllocateObject
<
C
>
extends
BoundMethodHandle
{
static
final
class
AllocateObject
/*<C>*/
extends
BoundMethodHandle
{
private
static
final
Unsafe
unsafe
=
Unsafe
.
getUnsafe
();
private
final
Class
<
C
>
allocateClass
;
private
final
Class
<
?>
/*<C>*/
allocateClass
;
// for allocation only:
private
AllocateObject
(
Class
<
C
>
allocateClass
)
{
private
AllocateObject
(
Class
<
?>
/*<C>*/
allocateClass
)
{
super
(
ALLOCATE
.
asType
(
MethodType
.
methodType
(
allocateClass
,
AllocateObject
.
class
)));
this
.
allocateClass
=
allocateClass
;
}
@SuppressWarnings
(
"unchecked"
)
private
C
allocate
()
throws
InstantiationException
{
return
(
C
)
unsafe
.
allocateInstance
(
allocateClass
);
private
Object
/*C*/
allocate
()
throws
InstantiationException
{
return
unsafe
.
allocateInstance
(
allocateClass
);
}
static
final
MethodHandle
ALLOCATE
;
static
{
...
...
@@ -148,8 +148,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle
accessField
(
MemberName
member
,
boolean
isSetter
,
Class
<?>
lookupClass
)
{
// Use sun. misc.Unsafe to dig up the dirt on the field.
MethodHandle
mh
=
new
FieldAccessor
(
member
,
isSetter
);
return
mh
;
FieldAccessor
accessor
=
new
FieldAccessor
(
member
,
isSetter
);
return
accessor
;
}
static
...
...
@@ -175,7 +175,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return
mhs
[
isSetter
?
1
:
0
];
}
static
final
class
FieldAccessor
<
C
,
V
>
extends
BoundMethodHandle
{
static
final
class
FieldAccessor
/*<C,V>*/
extends
BoundMethodHandle
{
private
static
final
Unsafe
unsafe
=
Unsafe
.
getUnsafe
();
final
Object
base
;
// for static refs only
final
long
offset
;
...
...
@@ -190,26 +190,24 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@Override
String
debugString
()
{
return
addTypeString
(
name
,
this
);
}
int
getFieldI
(
C
obj
)
{
return
unsafe
.
getInt
(
obj
,
offset
);
}
void
setFieldI
(
C
obj
,
int
x
)
{
unsafe
.
putInt
(
obj
,
offset
,
x
);
}
long
getFieldJ
(
C
obj
)
{
return
unsafe
.
getLong
(
obj
,
offset
);
}
void
setFieldJ
(
C
obj
,
long
x
)
{
unsafe
.
putLong
(
obj
,
offset
,
x
);
}
float
getFieldF
(
C
obj
)
{
return
unsafe
.
getFloat
(
obj
,
offset
);
}
void
setFieldF
(
C
obj
,
float
x
)
{
unsafe
.
putFloat
(
obj
,
offset
,
x
);
}
double
getFieldD
(
C
obj
)
{
return
unsafe
.
getDouble
(
obj
,
offset
);
}
void
setFieldD
(
C
obj
,
double
x
)
{
unsafe
.
putDouble
(
obj
,
offset
,
x
);
}
boolean
getFieldZ
(
C
obj
)
{
return
unsafe
.
getBoolean
(
obj
,
offset
);
}
void
setFieldZ
(
C
obj
,
boolean
x
)
{
unsafe
.
putBoolean
(
obj
,
offset
,
x
);
}
byte
getFieldB
(
C
obj
)
{
return
unsafe
.
getByte
(
obj
,
offset
);
}
void
setFieldB
(
C
obj
,
byte
x
)
{
unsafe
.
putByte
(
obj
,
offset
,
x
);
}
short
getFieldS
(
C
obj
)
{
return
unsafe
.
getShort
(
obj
,
offset
);
}
void
setFieldS
(
C
obj
,
short
x
)
{
unsafe
.
putShort
(
obj
,
offset
,
x
);
}
char
getFieldC
(
C
obj
)
{
return
unsafe
.
getChar
(
obj
,
offset
);
}
void
setFieldC
(
C
obj
,
char
x
)
{
unsafe
.
putChar
(
obj
,
offset
,
x
);
}
@SuppressWarnings
(
"unchecked"
)
V
getFieldL
(
C
obj
)
{
return
(
V
)
unsafe
.
getObject
(
obj
,
offset
);
}
@SuppressWarnings
(
"unchecked"
)
void
setFieldL
(
C
obj
,
V
x
)
{
unsafe
.
putObject
(
obj
,
offset
,
x
);
}
int
getFieldI
(
Object
/*C*/
obj
)
{
return
unsafe
.
getInt
(
obj
,
offset
);
}
void
setFieldI
(
Object
/*C*/
obj
,
int
x
)
{
unsafe
.
putInt
(
obj
,
offset
,
x
);
}
long
getFieldJ
(
Object
/*C*/
obj
)
{
return
unsafe
.
getLong
(
obj
,
offset
);
}
void
setFieldJ
(
Object
/*C*/
obj
,
long
x
)
{
unsafe
.
putLong
(
obj
,
offset
,
x
);
}
float
getFieldF
(
Object
/*C*/
obj
)
{
return
unsafe
.
getFloat
(
obj
,
offset
);
}
void
setFieldF
(
Object
/*C*/
obj
,
float
x
)
{
unsafe
.
putFloat
(
obj
,
offset
,
x
);
}
double
getFieldD
(
Object
/*C*/
obj
)
{
return
unsafe
.
getDouble
(
obj
,
offset
);
}
void
setFieldD
(
Object
/*C*/
obj
,
double
x
)
{
unsafe
.
putDouble
(
obj
,
offset
,
x
);
}
boolean
getFieldZ
(
Object
/*C*/
obj
)
{
return
unsafe
.
getBoolean
(
obj
,
offset
);
}
void
setFieldZ
(
Object
/*C*/
obj
,
boolean
x
)
{
unsafe
.
putBoolean
(
obj
,
offset
,
x
);
}
byte
getFieldB
(
Object
/*C*/
obj
)
{
return
unsafe
.
getByte
(
obj
,
offset
);
}
void
setFieldB
(
Object
/*C*/
obj
,
byte
x
)
{
unsafe
.
putByte
(
obj
,
offset
,
x
);
}
short
getFieldS
(
Object
/*C*/
obj
)
{
return
unsafe
.
getShort
(
obj
,
offset
);
}
void
setFieldS
(
Object
/*C*/
obj
,
short
x
)
{
unsafe
.
putShort
(
obj
,
offset
,
x
);
}
char
getFieldC
(
Object
/*C*/
obj
)
{
return
unsafe
.
getChar
(
obj
,
offset
);
}
void
setFieldC
(
Object
/*C*/
obj
,
char
x
)
{
unsafe
.
putChar
(
obj
,
offset
,
x
);
}
Object
/*V*/
getFieldL
(
Object
/*C*/
obj
)
{
return
unsafe
.
getObject
(
obj
,
offset
);
}
void
setFieldL
(
Object
/*C*/
obj
,
Object
/*V*/
x
)
{
unsafe
.
putObject
(
obj
,
offset
,
x
);
}
// cast (V) is OK here, since we wrap convertArguments around the MH.
static
Object
staticBase
(
final
MemberName
field
)
{
...
...
@@ -244,8 +242,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
void
setStaticS
(
short
x
)
{
unsafe
.
putShort
(
base
,
offset
,
x
);
}
char
getStaticC
()
{
return
unsafe
.
getChar
(
base
,
offset
);
}
void
setStaticC
(
char
x
)
{
unsafe
.
putChar
(
base
,
offset
,
x
);
}
V
getStaticL
()
{
return
(
V
)
unsafe
.
getObject
(
base
,
offset
);
}
void
setStaticL
(
V
x
)
{
unsafe
.
putObject
(
base
,
offset
,
x
);
}
@SuppressWarnings
(
"unchecked"
)
// (V) is for internal clarity but triggers warning
Object
/*V*/
getStaticL
()
{
return
unsafe
.
getObject
(
base
,
offset
);
}
void
setStaticL
(
Object
/*V*/
x
)
{
unsafe
.
putObject
(
base
,
offset
,
x
);
}
static
String
fname
(
Class
<?>
vclass
,
boolean
isSetter
,
boolean
isStatic
)
{
String
stem
;
...
...
src/share/classes/java/lang/invoke/MethodHandleProxies.java
浏览文件 @
5bb0a44f
...
...
@@ -150,7 +150,7 @@ public class MethodHandleProxies {
}
return
intfc
.
cast
(
Proxy
.
newProxyInstance
(
intfc
.
getClassLoader
(),
new
Class
[]{
intfc
,
WrapperInstance
.
class
},
new
Class
<?>
[]{
intfc
,
WrapperInstance
.
class
},
new
InvocationHandler
()
{
private
Object
getArg
(
String
name
)
{
if
((
Object
)
name
==
"getWrapperInstanceTarget"
)
return
target
;
...
...
src/share/classes/java/lang/invoke/MethodHandles.java
浏览文件 @
5bb0a44f
...
...
@@ -948,10 +948,11 @@ return mh1;
public
MethodHandle
unreflect
(
Method
m
)
throws
IllegalAccessException
{
MemberName
method
=
new
MemberName
(
m
);
assert
(
method
.
isMethod
());
if
(!
m
.
isAccessible
())
checkMethod
(
method
.
getDeclaringClass
(),
method
,
method
.
isStatic
());
if
(
m
.
isAccessible
())
return
MethodHandleImpl
.
findMethod
(
method
,
true
,
/*no lookupClass*/
null
);
checkMethod
(
method
.
getDeclaringClass
(),
method
,
method
.
isStatic
());
MethodHandle
mh
=
MethodHandleImpl
.
findMethod
(
method
,
true
,
lookupClassOrNull
());
if
(!
m
.
isAccessible
())
mh
=
restrictProtectedReceiver
(
method
,
mh
);
return
mh
;
return
restrictProtectedReceiver
(
method
,
mh
);
}
/**
...
...
@@ -1006,11 +1007,17 @@ return mh1;
* is set and {@code asVarargsCollector} fails
* @throws NullPointerException if the argument is null
*/
@SuppressWarnings
(
"rawtypes"
)
// Will be Constructor<?> after JSR 292 MR
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
(
ctor
,
false
,
lookupClassOrNull
());
MethodHandle
rawCtor
;
if
(
c
.
isAccessible
())
{
rawCtor
=
MethodHandleImpl
.
findMethod
(
ctor
,
false
,
/*no lookupClass*/
null
);
}
else
{
checkAccess
(
c
.
getDeclaringClass
(),
ctor
);
rawCtor
=
MethodHandleImpl
.
findMethod
(
ctor
,
false
,
lookupClassOrNull
());
}
MethodHandle
allocator
=
MethodHandleImpl
.
makeAllocator
(
rawCtor
);
return
fixVarargs
(
allocator
,
rawCtor
);
}
...
...
@@ -1225,7 +1232,7 @@ return mh1;
?
"expected a static field"
:
"expected a non-static field"
,
this
);
if
(
trusted
)
return
MethodHandleImpl
.
accessField
(
field
,
isSetter
,
lookupClassOrNull
()
);
return
MethodHandleImpl
.
accessField
(
field
,
isSetter
,
/*no lookupClass*/
null
);
checkAccess
(
refc
,
field
);
MethodHandle
mh
=
MethodHandleImpl
.
accessField
(
field
,
isSetter
,
lookupClassOrNull
());
return
restrictProtectedReceiver
(
field
,
mh
);
...
...
src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
浏览文件 @
5bb0a44f
...
...
@@ -1932,20 +1932,22 @@ public class BasicTreeUI extends TreeUI
else
{
Rectangle
beginRect
=
getPathBounds
(
tree
,
getPathForRow
(
tree
,
beginRow
));
Rectangle
visRect
=
tree
.
getVisibleRect
();
Rectangle
testRect
=
beginRect
;
int
beginY
=
beginRect
.
y
;
int
maxY
=
beginY
+
visRect
.
height
;
for
(
int
counter
=
beginRow
+
1
;
counter
<=
endRow
;
counter
++)
{
testRect
=
getPathBounds
(
tree
,
getPathForRow
(
tree
,
counter
));
if
((
testRect
.
y
+
testRect
.
height
)
>
maxY
)
counter
=
endRow
;
if
(
beginRect
!=
null
)
{
Rectangle
visRect
=
tree
.
getVisibleRect
();
Rectangle
testRect
=
beginRect
;
int
beginY
=
beginRect
.
y
;
int
maxY
=
beginY
+
visRect
.
height
;
for
(
int
counter
=
beginRow
+
1
;
counter
<=
endRow
;
counter
++)
{
testRect
=
getPathBounds
(
tree
,
getPathForRow
(
tree
,
counter
));
if
((
testRect
.
y
+
testRect
.
height
)
>
maxY
)
counter
=
endRow
;
}
tree
.
scrollRectToVisible
(
new
Rectangle
(
visRect
.
x
,
beginY
,
1
,
testRect
.
y
+
testRect
.
height
-
beginY
));
}
tree
.
scrollRectToVisible
(
new
Rectangle
(
visRect
.
x
,
beginY
,
1
,
testRect
.
y
+
testRect
.
height
-
beginY
));
}
}
}
...
...
@@ -3485,7 +3487,7 @@ public class BasicTreeUI extends TreeUI
}
Rectangle
bounds
=
getPathBounds
(
tree
,
path
);
if
(
y
>
(
bounds
.
y
+
bounds
.
height
))
{
if
(
bounds
==
null
||
y
>
(
bounds
.
y
+
bounds
.
height
))
{
return
false
;
}
...
...
src/share/classes/sun/invoke/util/ValueConversions.java
浏览文件 @
5bb0a44f
...
...
@@ -55,9 +55,9 @@ public class ValueConversions {
private
static
final
Lookup
IMPL_LOOKUP
=
MethodHandles
.
lookup
();
private
static
EnumMap
<
Wrapper
,
MethodHandle
>[]
newWrapperCaches
(
int
n
)
{
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
// generic array creation
EnumMap
<
Wrapper
,
MethodHandle
>[]
caches
=
(
EnumMap
<
Wrapper
,
MethodHandle
>[])
new
EnumMap
[
n
];
// unchecked warning expected here
=
(
EnumMap
<
Wrapper
,
MethodHandle
>[])
new
EnumMap
<?,?>[
n
];
for
(
int
i
=
0
;
i
<
n
;
i
++)
caches
[
i
]
=
new
EnumMap
<>(
Wrapper
.
class
);
return
caches
;
...
...
@@ -1097,7 +1097,7 @@ public class ValueConversions {
}
private
static
MethodHandle
buildNewArray
(
int
nargs
)
{
return
MethodHandles
.
insertArguments
(
NEW_ARRAY
,
0
,
(
int
)
nargs
);
return
MethodHandles
.
insertArguments
(
NEW_ARRAY
,
0
,
nargs
);
}
private
static
final
MethodHandle
[]
FILLERS
=
new
MethodHandle
[
MAX_ARITY
+
1
];
...
...
@@ -1122,7 +1122,7 @@ public class ValueConversions {
}
MethodHandle
leftFill
=
filler
(
leftLen
);
// recursive fill
MethodHandle
rightFill
=
FILL_ARRAYS
[
rightLen
];
rightFill
=
MethodHandles
.
insertArguments
(
rightFill
,
1
,
(
int
)
leftLen
);
// [leftLen..nargs-1]
rightFill
=
MethodHandles
.
insertArguments
(
rightFill
,
1
,
leftLen
);
// [leftLen..nargs-1]
// Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
MethodHandle
mh
=
filler
(
0
);
// identity function produces result
...
...
src/share/classes/sun/invoke/util/Wrapper.java
浏览文件 @
5bb0a44f
...
...
@@ -31,7 +31,7 @@ public enum Wrapper {
BYTE
(
Byte
.
class
,
byte
.
class
,
'B'
,
(
Byte
)(
byte
)
0
,
new
byte
[
0
],
Format
.
signed
(
8
)),
SHORT
(
Short
.
class
,
short
.
class
,
'S'
,
(
Short
)(
short
)
0
,
new
short
[
0
],
Format
.
signed
(
16
)),
CHAR
(
Character
.
class
,
char
.
class
,
'C'
,
(
Character
)(
char
)
0
,
new
char
[
0
],
Format
.
unsigned
(
16
)),
INT
(
Integer
.
class
,
int
.
class
,
'I'
,
(
Integer
)
(
int
)
0
,
new
int
[
0
],
Format
.
signed
(
32
)),
INT
(
Integer
.
class
,
int
.
class
,
'I'
,
(
Integer
)
/*(int)*/
0
,
new
int
[
0
],
Format
.
signed
(
32
)),
LONG
(
Long
.
class
,
long
.
class
,
'J'
,
(
Long
)(
long
)
0
,
new
long
[
0
],
Format
.
signed
(
64
)),
FLOAT
(
Float
.
class
,
float
.
class
,
'F'
,
(
Float
)(
float
)
0
,
new
float
[
0
],
Format
.
floating
(
32
)),
DOUBLE
(
Double
.
class
,
double
.
class
,
'D'
,
(
Double
)(
double
)
0
,
new
double
[
0
],
Format
.
floating
(
64
)),
...
...
@@ -539,7 +539,7 @@ public enum Wrapper {
switch
(
basicTypeChar
)
{
case
'L'
:
throw
newIllegalArgumentException
(
"cannot wrap to object type"
);
case
'V'
:
return
null
;
case
'I'
:
return
Integer
.
valueOf
(
(
int
)
x
);
case
'I'
:
return
Integer
.
valueOf
(
x
);
case
'J'
:
return
Long
.
valueOf
(
x
);
case
'F'
:
return
Float
.
valueOf
(
x
);
case
'D'
:
return
Double
.
valueOf
(
x
);
...
...
src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java
浏览文件 @
5bb0a44f
...
...
@@ -76,9 +76,12 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer {
accessor
.
setFiles
(
fd
,
null
,
null
);
}
else
{
// Fix 6987233: add the trailing slash if it's absent
accessor
.
setDirectory
(
fd
,
directory
+
(
directory
.
endsWith
(
File
.
separator
)
?
""
:
File
.
separator
));
String
with_separator
=
directory
;
if
(
directory
!=
null
)
{
with_separator
=
directory
.
endsWith
(
File
.
separator
)
?
directory
:
(
directory
+
File
.
separator
);
}
accessor
.
setDirectory
(
fd
,
with_separator
);
accessor
.
setFile
(
fd
,
filenames
[
0
]);
accessor
.
setFiles
(
fd
,
directory
,
filenames
);
}
...
...
src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
浏览文件 @
5bb0a44f
...
...
@@ -28,6 +28,9 @@ package sun.java2d.xr;
import
java.awt.*
;
import
java.awt.geom.*
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
sun.font.*
;
import
sun.java2d.*
;
import
sun.java2d.jules.*
;
...
...
@@ -83,7 +86,13 @@ public class XRCompositeManager {
con
=
new
XRBackendNative
();
// con = XRBackendJava.getInstance();
String
gradProp
=
System
.
getProperty
(
"sun.java2d.xrgradcache"
);
String
gradProp
=
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
String
>()
{
public
String
run
()
{
return
System
.
getProperty
(
"sun.java2d.xrgradcache"
);
}
});
enableGradCache
=
gradProp
==
null
||
!(
gradProp
.
equalsIgnoreCase
(
"false"
)
||
gradProp
.
equalsIgnoreCase
(
"f"
));
...
...
test/java/lang/invoke/CallSiteTest.java
浏览文件 @
5bb0a44f
...
...
@@ -43,7 +43,7 @@ import static java.lang.invoke.MethodHandles.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
public
class
CallSiteTest
{
private
final
static
Class
CLASS
=
CallSiteTest
.
class
;
private
final
static
Class
<?>
CLASS
=
CallSiteTest
.
class
;
private
static
CallSite
mcs
;
private
static
CallSite
vcs
;
...
...
test/java/lang/invoke/ClassValueTest.java
浏览文件 @
5bb0a44f
...
...
@@ -38,10 +38,6 @@
package
test.java.lang.invoke
;
import
java.util.*
;
import
java.lang.invoke.*
;
import
org.junit.*
;
import
static
org
.
junit
.
Assert
.*;
...
...
@@ -61,7 +57,7 @@ public class ClassValueTest {
}
}
static
final
Class
[]
CLASSES
=
{
static
final
Class
<?>
[]
CLASSES
=
{
String
.
class
,
Integer
.
class
,
int
.
class
,
...
...
@@ -73,11 +69,11 @@ public class ClassValueTest {
@Test
public
void
testGet
()
{
countForCV1
=
0
;
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCV1
(
c
),
CV1
.
get
(
c
));
}
assertEquals
(
CLASSES
.
length
,
countForCV1
);
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCV1
(
c
),
CV1
.
get
(
c
));
}
assertEquals
(
CLASSES
.
length
,
countForCV1
);
...
...
@@ -85,7 +81,7 @@ public class ClassValueTest {
@Test
public
void
testRemove
()
{
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
CV1
.
get
(
c
);
}
countForCV1
=
0
;
...
...
@@ -94,7 +90,7 @@ public class ClassValueTest {
CV1
.
remove
(
CLASSES
[
i
]);
}
assertEquals
(
0
,
countForCV1
);
// no change
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCV1
(
c
),
CV1
.
get
(
c
));
}
assertEquals
(
REMCOUNT
,
countForCV1
);
...
...
@@ -124,7 +120,7 @@ public class ClassValueTest {
for
(
int
pass
=
0
;
pass
<=
2
;
pass
++)
{
for
(
int
i1
=
0
;
i1
<
CVN_COUNT1
;
i1
++)
{
eachClass:
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
for
(
int
i2
=
0
;
i2
<
CVN_COUNT2
;
i2
++)
{
int
n
=
i1
*
CVN_COUNT2
+
i2
;
assertEquals
(
0
,
countForCVN
);
...
...
@@ -156,8 +152,10 @@ public class ClassValueTest {
}
}
assertEquals
(
countForCVN
,
0
);
for
(
int
n
=
0
;
n
<
cvns
.
length
;
n
++)
{
for
(
Class
c
:
CLASSES
)
{
System
.
out
.
println
(
"[rechecking values]"
);
for
(
int
i
=
0
;
i
<
cvns
.
length
*
10
;
i
++)
{
int
n
=
i
%
cvns
.
length
;
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCVN
(
c
,
n
),
cvns
[
n
].
get
(
c
));
}
}
...
...
test/java/lang/invoke/InvokeGenericTest.java
浏览文件 @
5bb0a44f
...
...
@@ -45,6 +45,7 @@ import static org.junit.Assume.*;
*
* @author jrose
*/
@SuppressWarnings
(
"cast"
)
// various casts help emphasize arguments to invokeExact
public
class
InvokeGenericTest
{
// How much output?
static
int
verbosity
=
0
;
...
...
@@ -129,7 +130,7 @@ public class InvokeGenericTest {
}
}
static
List
<
Object
>
calledLog
=
new
ArrayList
<
Object
>();
static
List
<
Object
>
calledLog
=
new
ArrayList
<>();
static
Object
logEntry
(
String
name
,
Object
...
args
)
{
return
Arrays
.
asList
(
name
,
Arrays
.
asList
(
args
));
}
...
...
@@ -237,8 +238,7 @@ public class InvokeGenericTest {
else
try
{
return
param
.
newInstance
();
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
catch
(
InstantiationException
|
IllegalAccessException
ex
)
{
}
return
null
;
// random class not Object, String, Integer, etc.
}
...
...
@@ -274,9 +274,11 @@ public class InvokeGenericTest {
return
zeroArgs
(
params
.
toArray
(
new
Class
<?>[
0
]));
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
,
E
extends
T
>
T
[]
array
(
Class
<
T
[]>
atype
,
E
...
a
)
{
return
Arrays
.
copyOf
(
a
,
a
.
length
,
atype
);
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
>
T
[]
cat
(
T
[]
a
,
T
...
b
)
{
int
alen
=
a
.
length
,
blen
=
b
.
length
;
if
(
blen
==
0
)
return
a
;
...
...
@@ -311,7 +313,7 @@ public class InvokeGenericTest {
int
beg
,
int
end
,
Class
<?>
argType
)
{
MethodType
targetType
=
target
.
type
();
end
=
Math
.
min
(
end
,
targetType
.
parameterCount
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<
Class
<?>
>(
targetType
.
parameterList
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<>(
targetType
.
parameterList
());
Collections
.
fill
(
argTypes
.
subList
(
beg
,
end
),
argType
);
MethodType
ttype2
=
MethodType
.
methodType
(
targetType
.
returnType
(),
argTypes
);
return
target
.
asType
(
ttype2
);
...
...
@@ -320,7 +322,7 @@ public class InvokeGenericTest {
// This lookup is good for all members in and under InvokeGenericTest.
static
final
Lookup
LOOKUP
=
MethodHandles
.
lookup
();
Map
<
List
<
Class
<?>>,
MethodHandle
>
CALLABLES
=
new
HashMap
<
List
<
Class
<?>>,
MethodHandle
>();
Map
<
List
<
Class
<?>>,
MethodHandle
>
CALLABLES
=
new
HashMap
<>();
MethodHandle
callable
(
List
<
Class
<?>>
params
)
{
MethodHandle
mh
=
CALLABLES
.
get
(
params
);
if
(
mh
==
null
)
{
...
...
@@ -353,8 +355,8 @@ public class InvokeGenericTest {
countTest
();
String
[]
args
=
{
"one"
,
"two"
};
MethodHandle
mh
=
callable
(
Object
.
class
,
String
.
class
);
Object
res
;
List
resl
;
res
=
resl
=
(
List
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
Object
res
;
List
<?>
resl
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
asList
(
args
),
res
);
}
...
...
@@ -365,8 +367,8 @@ public class InvokeGenericTest {
countTest
();
int
[]
args
=
{
1
,
2
};
MethodHandle
mh
=
callable
(
Object
.
class
,
Object
.
class
);
Object
res
;
List
resl
;
res
=
resl
=
(
List
)
mh
.
invoke
(
args
[
0
],
args
[
1
]);
Object
res
;
List
<?>
resl
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
(
args
[
0
],
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
toString
(
args
),
res
.
toString
());
}
...
...
@@ -377,8 +379,8 @@ public class InvokeGenericTest {
countTest
();
String
[]
args
=
{
"one"
,
"two"
};
MethodHandle
mh
=
callable
(
Object
.
class
,
String
.
class
);
Object
res
;
List
resl
;
res
=
resl
=
(
List
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
Object
res
;
List
<?>
resl
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
asList
(
args
),
res
);
}
...
...
@@ -440,9 +442,9 @@ public class InvokeGenericTest {
* A void return type is possible iff the first type is void.class.
*/
static
List
<
MethodType
>
allMethodTypes
(
int
minargc
,
int
maxargc
,
Class
<?>...
types
)
{
ArrayList
<
MethodType
>
result
=
new
ArrayList
<
MethodType
>();
ArrayList
<
MethodType
>
result
=
new
ArrayList
<>();
if
(
types
.
length
>
0
)
{
ArrayList
<
MethodType
>
argcTypes
=
new
ArrayList
<
MethodType
>();
ArrayList
<
MethodType
>
argcTypes
=
new
ArrayList
<>();
// build arity-zero types first
for
(
Class
<?>
rtype
:
types
)
{
argcTypes
.
add
(
MethodType
.
methodType
(
rtype
));
...
...
@@ -456,7 +458,7 @@ public class InvokeGenericTest {
if
(
argc
>=
maxargc
)
break
;
ArrayList
<
MethodType
>
prevTypes
=
argcTypes
;
argcTypes
=
new
ArrayList
<
MethodType
>();
argcTypes
=
new
ArrayList
<>();
for
(
MethodType
prevType
:
prevTypes
)
{
for
(
Class
<?>
ptype
:
types
)
{
argcTypes
.
add
(
prevType
.
insertParameterTypes
(
argc
,
ptype
));
...
...
@@ -524,8 +526,8 @@ public class InvokeGenericTest {
countTest
();
Object
[]
args
=
{
1
,
2
};
MethodHandle
mh
=
callable
(
Object
.
class
,
int
.
class
);
Object
res
;
List
resl
;
int
resi
;
res
=
resl
=
(
List
)
mh
.
invoke
((
int
)
args
[
0
],
(
Object
)
args
[
1
]);
Object
res
;
List
<?>
resl
;
int
resi
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
((
int
)
args
[
0
],
(
Object
)
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
asList
(
args
),
res
);
mh
=
MethodHandles
.
identity
(
int
.
class
);
...
...
test/java/lang/invoke/JavaDocExamplesTest.java
浏览文件 @
5bb0a44f
...
...
@@ -54,6 +54,7 @@ import static org.junit.Assert.*;
/**
* @author jrose
*/
@SuppressWarnings
(
"LocalVariableHidesMemberVariable"
)
public
class
JavaDocExamplesTest
{
/** Wrapper for running the JUnit tests in this module.
* Put JUnit on the classpath!
...
...
@@ -336,6 +337,7 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
}}
}
@SuppressWarnings
(
"rawtypes"
)
@Test
public
void
testAsVarargsCollector
()
throws
Throwable
{
{{
{}
/// JAVADOC
...
...
test/java/lang/invoke/MethodHandlesTest.java
浏览文件 @
5bb0a44f
...
...
@@ -176,7 +176,7 @@ public class MethodHandlesTest {
}
}
static
List
<
Object
>
calledLog
=
new
ArrayList
<
Object
>();
static
List
<
Object
>
calledLog
=
new
ArrayList
<>();
static
Object
logEntry
(
String
name
,
Object
...
args
)
{
return
Arrays
.
asList
(
name
,
Arrays
.
asList
(
args
));
}
...
...
@@ -211,6 +211,7 @@ public class MethodHandlesTest {
return
dst
.
cast
(
value
);
}
@SuppressWarnings
(
"cast"
)
// primitive cast to (long) is part of the pattern
static
Object
castToWrapperOrNull
(
long
value
,
Class
<?>
dst
)
{
if
(
dst
==
int
.
class
||
dst
==
Integer
.
class
)
return
(
int
)(
value
);
...
...
@@ -284,8 +285,7 @@ public class MethodHandlesTest {
else
try
{
return
param
.
newInstance
();
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
catch
(
InstantiationException
|
IllegalAccessException
ex
)
{
}
return
null
;
// random class not Object, String, Integer, etc.
}
...
...
@@ -302,9 +302,11 @@ public class MethodHandlesTest {
return
args
;
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
,
E
extends
T
>
T
[]
array
(
Class
<
T
[]>
atype
,
E
...
a
)
{
return
Arrays
.
copyOf
(
a
,
a
.
length
,
atype
);
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
>
T
[]
cat
(
T
[]
a
,
T
...
b
)
{
int
alen
=
a
.
length
,
blen
=
b
.
length
;
if
(
blen
==
0
)
return
a
;
...
...
@@ -354,14 +356,14 @@ public class MethodHandlesTest {
try
{
LIST_TO_STRING
=
PRIVATE
.
findStatic
(
PRIVATE
.
lookupClass
(),
"listToString"
,
MethodType
.
methodType
(
String
.
class
,
List
.
class
));
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
list
=
MethodHandles
.
filterReturnValue
(
list
,
LIST_TO_STRING
);
}
else
if
(
rtype
.
isPrimitive
())
{
if
(
LIST_TO_INT
==
null
)
try
{
LIST_TO_INT
=
PRIVATE
.
findStatic
(
PRIVATE
.
lookupClass
(),
"listToInt"
,
MethodType
.
methodType
(
int
.
class
,
List
.
class
));
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
list
=
MethodHandles
.
filterReturnValue
(
list
,
LIST_TO_INT
);
list
=
MethodHandles
.
explicitCastArguments
(
list
,
listType
);
}
else
{
...
...
@@ -370,8 +372,8 @@ public class MethodHandlesTest {
return
list
.
asType
(
listType
);
}
private
static
MethodHandle
LIST_TO_STRING
,
LIST_TO_INT
;
private
static
String
listToString
(
List
x
)
{
return
x
.
toString
();
}
private
static
int
listToInt
(
List
x
)
{
return
x
.
toString
().
hashCode
();
}
private
static
String
listToString
(
List
<?>
x
)
{
return
x
.
toString
();
}
private
static
int
listToInt
(
List
<?>
x
)
{
return
x
.
toString
().
hashCode
();
}
static
MethodHandle
changeArgTypes
(
MethodHandle
target
,
Class
<?>
argType
)
{
return
changeArgTypes
(
target
,
0
,
999
,
argType
);
...
...
@@ -380,7 +382,7 @@ public class MethodHandlesTest {
int
beg
,
int
end
,
Class
<?>
argType
)
{
MethodType
targetType
=
target
.
type
();
end
=
Math
.
min
(
end
,
targetType
.
parameterCount
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<
Class
<?>
>(
targetType
.
parameterList
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<>(
targetType
.
parameterList
());
Collections
.
fill
(
argTypes
.
subList
(
beg
,
end
),
argType
);
MethodType
ttype2
=
MethodType
.
methodType
(
targetType
.
returnType
(),
argTypes
);
return
target
.
asType
(
ttype2
);
...
...
@@ -405,6 +407,7 @@ public class MethodHandlesTest {
final
String
name
;
public
Example
()
{
name
=
"Example#"
+
nextArg
();
}
protected
Example
(
String
name
)
{
this
.
name
=
name
;
}
@SuppressWarnings
(
"LeakingThisInConstructor"
)
protected
Example
(
int
x
)
{
this
();
called
(
"protected <init>"
,
this
,
x
);
}
@Override
public
String
toString
()
{
return
name
;
}
...
...
@@ -441,6 +444,7 @@ public class MethodHandlesTest {
static
class
SubExample
extends
Example
{
@Override
public
void
v0
()
{
called
(
"Sub/v0"
,
this
);
}
@Override
void
pkg_v0
()
{
called
(
"Sub/pkg_v0"
,
this
);
}
@SuppressWarnings
(
"LeakingThisInConstructor"
)
private
SubExample
(
int
x
)
{
called
(
"<init>"
,
this
,
x
);
}
public
SubExample
()
{
super
(
"SubExample#"
+
nextArg
());
}
}
...
...
@@ -912,7 +916,7 @@ public class MethodHandlesTest {
static
final
Object
[][]
CASES
;
static
{
ArrayList
<
Object
[]>
cases
=
new
ArrayList
<
Object
[]
>();
ArrayList
<
Object
[]>
cases
=
new
ArrayList
<>();
Object
types
[][]
=
{
{
'L'
,
Object
.
class
},
{
'R'
,
String
.
class
},
{
'I'
,
int
.
class
},
{
'J'
,
long
.
class
},
...
...
@@ -931,12 +935,12 @@ public class MethodHandlesTest {
Field
field
;
try
{
field
=
HasFields
.
class
.
getDeclaredField
(
name
);
}
catch
(
Exception
ex
)
{
}
catch
(
NoSuchFieldException
|
Security
Exception
ex
)
{
throw
new
InternalError
(
"no field HasFields."
+
name
);
}
try
{
value
=
field
.
get
(
fields
);
}
catch
(
Exception
ex
)
{
}
catch
(
IllegalArgumentException
|
IllegalAccess
Exception
ex
)
{
throw
new
InternalError
(
"cannot fetch field HasFields."
+
name
);
}
if
(
type
==
float
.
class
)
{
...
...
@@ -1257,7 +1261,7 @@ public class MethodHandlesTest {
List
<
Object
>
array2list
(
Object
array
)
{
int
length
=
Array
.
getLength
(
array
);
ArrayList
<
Object
>
model
=
new
ArrayList
<
Object
>(
length
);
ArrayList
<
Object
>
model
=
new
ArrayList
<>(
length
);
for
(
int
i
=
0
;
i
<
length
;
i
++)
model
.
add
(
Array
.
get
(
array
,
i
));
return
model
;
...
...
@@ -1288,7 +1292,7 @@ public class MethodHandlesTest {
String
name
=
pfx
+
"id"
;
try
{
return
PRIVATE
.
findStatic
(
Callee
.
class
,
name
,
type
);
}
catch
(
Exception
ex
)
{
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
...
...
@@ -1365,7 +1369,7 @@ public class MethodHandlesTest {
MethodHandle
vac
=
vac0
.
asVarargsCollector
(
Object
[].
class
);
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
0
)),
null
,
"vac"
);
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
0
)),
null
,
"vac"
);
for
(
Class
<?>
at
:
new
Class
[]
{
Object
.
class
,
String
.
class
,
Integer
.
class
})
{
for
(
Class
<?>
at
:
new
Class
<?>
[]
{
Object
.
class
,
String
.
class
,
Integer
.
class
})
{
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
1
)),
null
,
"vac"
,
at
);
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
2
)),
null
,
"vac"
,
at
,
at
);
}
...
...
@@ -1514,7 +1518,7 @@ public class MethodHandlesTest {
public
void
testSpreadArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"spreadArguments"
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
Class
<?>
argType
:
new
Class
<?>
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"spreadArguments "
+
argType
);
for
(
int
nargs
=
0
;
nargs
<
50
;
nargs
++)
{
...
...
@@ -1538,7 +1542,7 @@ public class MethodHandlesTest {
Object
[]
args
=
randomArgs
(
target2
.
type
().
parameterArray
());
// make sure the target does what we think it does:
if
(
pos
==
0
&&
nargs
<
5
&&
!
argType
.
isPrimitive
())
{
Object
[]
check
=
(
Object
[])
(
Object
)
target
.
invokeWithArguments
(
args
);
Object
[]
check
=
(
Object
[])
target
.
invokeWithArguments
(
args
);
assertArrayEquals
(
args
,
check
);
switch
(
nargs
)
{
case
0
:
...
...
@@ -1555,7 +1559,7 @@ public class MethodHandlesTest {
break
;
}
}
List
<
Class
<?>>
newParams
=
new
ArrayList
<
Class
<?>
>(
target2
.
type
().
parameterList
());
List
<
Class
<?>>
newParams
=
new
ArrayList
<>(
target2
.
type
().
parameterList
());
{
// modify newParams in place
List
<
Class
<?>>
spreadParams
=
newParams
.
subList
(
pos
,
nargs
);
spreadParams
.
clear
();
spreadParams
.
add
(
arrayType
);
...
...
@@ -1608,7 +1612,7 @@ public class MethodHandlesTest {
public
void
testCollectArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"collectArguments"
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
Class
<?>
argType
:
new
Class
<?>
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"collectArguments "
+
argType
);
for
(
int
nargs
=
0
;
nargs
<
50
;
nargs
++)
{
...
...
@@ -1670,12 +1674,13 @@ public class MethodHandlesTest {
MethodHandle
target
=
varargsArray
(
nargs
+
ins
);
Object
[]
args
=
randomArgs
(
target
.
type
().
parameterArray
());
List
<
Object
>
resList
=
Arrays
.
asList
(
args
);
List
<
Object
>
argsToPass
=
new
ArrayList
<
Object
>(
resList
);
List
<
Object
>
argsToPass
=
new
ArrayList
<>(
resList
);
List
<
Object
>
argsToInsert
=
argsToPass
.
subList
(
pos
,
pos
+
ins
);
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"insert: "
+
argsToInsert
+
" into "
+
target
);
@SuppressWarnings
(
"cast"
)
// cast to spread Object... is helpful
MethodHandle
target2
=
MethodHandles
.
insertArguments
(
target
,
pos
,
(
Object
[])
argsToInsert
.
toArray
());
(
Object
[]
/*...*/
)
argsToInsert
.
toArray
());
argsToInsert
.
clear
();
// remove from argsToInsert
Object
res2
=
target2
.
invokeWithArguments
(
argsToPass
);
Object
res2List
=
Arrays
.
asList
((
Object
[])
res2
);
...
...
@@ -1693,7 +1698,7 @@ public class MethodHandlesTest {
Class
<?>
classOfVCList
=
varargsList
(
1
).
invokeWithArguments
(
0
).
getClass
();
assertTrue
(
List
.
class
.
isAssignableFrom
(
classOfVCList
));
for
(
int
nargs
=
0
;
nargs
<=
3
;
nargs
++)
{
for
(
Class
<?>
rtype
:
new
Class
[]
{
Object
.
class
,
for
(
Class
<?>
rtype
:
new
Class
<?>
[]
{
Object
.
class
,
List
.
class
,
int
.
class
,
byte
.
class
,
...
...
@@ -1790,7 +1795,7 @@ public class MethodHandlesTest {
System
.
out
.
println
(
"fold "
+
target
+
" with "
+
combine
);
MethodHandle
target2
=
MethodHandles
.
foldArguments
(
target
,
combine
);
// Simulate expected effect of combiner on arglist:
List
<
Object
>
expected
=
new
ArrayList
<
Object
>(
argsToPass
);
List
<
Object
>
expected
=
new
ArrayList
<>(
argsToPass
);
List
<
Object
>
argsToFold
=
expected
.
subList
(
pos
,
pos
+
fold
);
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"fold: "
+
argsToFold
+
" into "
+
target2
);
...
...
@@ -1822,9 +1827,9 @@ public class MethodHandlesTest {
MethodHandle
target
=
varargsArray
(
nargs
);
Object
[]
args
=
randomArgs
(
target
.
type
().
parameterArray
());
MethodHandle
target2
=
MethodHandles
.
dropArguments
(
target
,
pos
,
Collections
.
nCopies
(
drop
,
Object
.
class
).
toArray
(
new
Class
[
0
]));
Collections
.
nCopies
(
drop
,
Object
.
class
).
toArray
(
new
Class
<?>
[
0
]));
List
<
Object
>
resList
=
Arrays
.
asList
(
args
);
List
<
Object
>
argsToDrop
=
new
ArrayList
<
Object
>(
resList
);
List
<
Object
>
argsToDrop
=
new
ArrayList
<>(
resList
);
for
(
int
i
=
drop
;
i
>
0
;
i
--)
{
argsToDrop
.
add
(
pos
,
"blort#"
+
i
);
}
...
...
@@ -1840,11 +1845,11 @@ public class MethodHandlesTest {
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker"
);
// exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
Set
<
MethodType
>
done
=
new
HashSet
<
MethodType
>();
Set
<
MethodType
>
done
=
new
HashSet
<>();
for
(
int
i
=
0
;
i
<=
6
;
i
++)
{
if
(
CAN_TEST_LIGHTLY
&&
i
>
3
)
break
;
MethodType
gtype
=
MethodType
.
genericMethodType
(
i
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
Class
<?>
argType
:
new
Class
<?>
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
int
j
=
-
1
;
j
<
i
;
j
++)
{
MethodType
type
=
gtype
;
if
(
j
<
0
)
...
...
@@ -1873,7 +1878,7 @@ public class MethodHandlesTest {
assertTrue
(
target
.
isVarargsCollector
());
target
=
target
.
asType
(
type
);
Object
[]
args
=
randomArgs
(
type
.
parameterArray
());
List
<
Object
>
targetPlusArgs
=
new
ArrayList
<
Object
>(
Arrays
.
asList
(
args
));
List
<
Object
>
targetPlusArgs
=
new
ArrayList
<>(
Arrays
.
asList
(
args
));
targetPlusArgs
.
add
(
0
,
target
);
int
code
=
(
Integer
)
invokee
(
args
);
Object
log
=
logEntry
(
"invokee"
,
args
);
...
...
@@ -1960,7 +1965,7 @@ public class MethodHandlesTest {
.
appendParameterTypes
(
Object
[].
class
)
.
insertParameterTypes
(
0
,
MethodHandle
.
class
));
assertEquals
(
expType
,
inv
.
type
());
List
<
Object
>
targetPlusVarArgs
=
new
ArrayList
<
Object
>(
targetPlusArgs
);
List
<
Object
>
targetPlusVarArgs
=
new
ArrayList
<>(
targetPlusArgs
);
List
<
Object
>
tailList
=
targetPlusVarArgs
.
subList
(
1
+
k
,
1
+
nargs
);
Object
[]
tail
=
tailList
.
toArray
();
tailList
.
clear
();
tailList
.
add
(
tail
);
...
...
@@ -2191,7 +2196,7 @@ public class MethodHandlesTest {
if
(
throwMode
==
THROW_NOTHING
)
{
assertSame
(
arg0
,
returned
);
}
else
if
(
throwMode
==
THROW_CAUGHT
)
{
List
<
Object
>
catchArgs
=
new
ArrayList
<
Object
>(
Arrays
.
asList
(
args
));
List
<
Object
>
catchArgs
=
new
ArrayList
<>(
Arrays
.
asList
(
args
));
// catcher receives an initial subsequence of target arguments:
catchArgs
.
subList
(
nargs
-
catchDrops
,
nargs
).
clear
();
// catcher also receives the exception, prepended:
...
...
@@ -2317,12 +2322,13 @@ public class MethodHandlesTest {
INT_IDENTITY
=
PRIVATE
.
findStatic
(
Surprise
.
class
,
"intIdentity"
,
MethodType
.
methodType
(
int
.
class
,
int
.
class
));
}
catch
(
Exception
ex
)
{
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
}
@SuppressWarnings
(
"ConvertToStringSwitch"
)
void
testCastFailure
(
String
mode
,
int
okCount
)
throws
Throwable
{
countTest
(
false
);
if
(
verbosity
>
2
)
System
.
out
.
println
(
"mode="
+
mode
);
...
...
@@ -2418,13 +2424,14 @@ public class MethodHandlesTest {
}
public
interface
Fooable
{
// overloads:
Object
foo
(
Object
x
,
String
y
);
List
foo
(
String
x
,
int
y
);
Object
foo
(
String
x
);
Object
foo
(
Object
x
,
String
y
);
List
<?>
foo
(
String
x
,
int
y
);
Object
foo
(
String
x
);
}
static
Object
fooForFooable
(
String
x
,
Object
...
y
)
{
return
called
(
"fooForFooable/"
+
x
,
y
);
}
@SuppressWarnings
(
"serial"
)
// not really a public API, just a test case
public
static
class
MyCheckedException
extends
Exception
{
}
public
interface
WillThrow
{
...
...
@@ -2453,7 +2460,7 @@ public class MethodHandlesTest {
{
countTest
();
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"Appendable"
);
ArrayList
<
List
>
appendResults
=
new
ArrayList
<
List
>();
ArrayList
<
List
<?>>
appendResults
=
new
ArrayList
<
>();
MethodHandle
append
=
lookup
.
bind
(
appendResults
,
"add"
,
MethodType
.
methodType
(
boolean
.
class
,
Object
.
class
));
append
=
append
.
asType
(
MethodType
.
methodType
(
void
.
class
,
List
.
class
));
// specialize the type
MethodHandle
asList
=
lookup
.
findStatic
(
Arrays
.
class
,
"asList"
,
MethodType
.
methodType
(
List
.
class
,
Object
[].
class
));
...
...
@@ -2475,11 +2482,11 @@ public class MethodHandlesTest {
formatter
.
format
(
fmt
,
fmtArgs
);
String
actual
=
""
;
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"appendResults="
+
appendResults
);
for
(
List
l
:
appendResults
)
{
for
(
List
<?>
l
:
appendResults
)
{
Object
x
=
l
.
get
(
0
);
switch
(
l
.
size
())
{
case
1
:
actual
+=
x
;
continue
;
case
3
:
actual
+=
((
String
)
x
).
substring
((
int
)
l
.
get
(
1
),
(
in
t
)
l
.
get
(
2
));
continue
;
case
3
:
actual
+=
((
String
)
x
).
substring
((
int
)
(
Object
)
l
.
get
(
1
),
(
int
)(
Objec
t
)
l
.
get
(
2
));
continue
;
}
actual
+=
l
;
}
...
...
@@ -2551,7 +2558,7 @@ public class MethodHandlesTest {
}
}
// Test error checking on bad interfaces:
for
(
Class
<?>
nonSMI
:
new
Class
[]
{
Object
.
class
,
for
(
Class
<?>
nonSMI
:
new
Class
<?>
[]
{
Object
.
class
,
String
.
class
,
CharSequence
.
class
,
java
.
io
.
Serializable
.
class
,
...
...
@@ -2579,7 +2586,7 @@ public class MethodHandlesTest {
}
}
// Test error checking on interfaces with the wrong method type:
for
(
Class
<?>
intfc
:
new
Class
[]
{
Runnable
.
class
/*arity 0*/
,
for
(
Class
<?>
intfc
:
new
Class
<?>
[]
{
Runnable
.
class
/*arity 0*/
,
Fooable
.
class
/*arity 1 & 2*/
})
{
int
badArity
=
1
;
// known to be incompatible
if
(
verbosity
>
2
)
System
.
out
.
println
(
intfc
.
getName
());
...
...
@@ -2657,7 +2664,7 @@ class ValueConversions {
Object
a8
,
Object
a9
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
static
MethodHandle
[]
makeArrays
()
{
ArrayList
<
MethodHandle
>
arrays
=
new
ArrayList
<
MethodHandle
>();
ArrayList
<
MethodHandle
>
arrays
=
new
ArrayList
<>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
arrays
.
size
();
...
...
@@ -2746,7 +2753,7 @@ class ValueConversions {
Object
a8
,
Object
a9
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
static
MethodHandle
[]
makeLists
()
{
ArrayList
<
MethodHandle
>
lists
=
new
ArrayList
<
MethodHandle
>();
ArrayList
<
MethodHandle
>
lists
=
new
ArrayList
<>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
lists
.
size
();
...
...
@@ -2769,7 +2776,7 @@ class ValueConversions {
static
{
try
{
AS_LIST
=
IMPL_LOOKUP
.
findStatic
(
Arrays
.
class
,
"asList"
,
MethodType
.
methodType
(
List
.
class
,
Object
[].
class
));
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
/** Return a method handle that takes the indicated number of Object
...
...
test/java/lang/invoke/MethodTypeTest.java
浏览文件 @
5bb0a44f
...
...
@@ -29,6 +29,7 @@
package
test.java.lang.invoke
;
import
java.io.IOException
;
import
java.lang.invoke.MethodType
;
import
java.lang.reflect.Method
;
...
...
@@ -378,7 +379,7 @@ public class MethodTypeTest {
public
void
testHashCode
()
{
System
.
out
.
println
(
"hashCode"
);
MethodType
instance
=
mt_viS
;
ArrayList
<
Class
<?>>
types
=
new
ArrayList
<
Class
<?>
>();
ArrayList
<
Class
<?>>
types
=
new
ArrayList
<>();
types
.
add
(
instance
.
returnType
());
types
.
addAll
(
instance
.
parameterList
());
int
expResult
=
types
.
hashCode
();
...
...
@@ -556,7 +557,7 @@ public class MethodTypeTest {
Object
decode
;
try
{
decode
=
readSerial
(
wire
);
}
catch
(
Exception
ex
)
{
}
catch
(
IOException
|
ClassNotFound
Exception
ex
)
{
decode
=
ex
;
// oops!
}
assertEquals
(
mt
,
decode
);
...
...
test/java/lang/invoke/PermuteArgsTest.java
浏览文件 @
5bb0a44f
...
...
@@ -45,7 +45,7 @@ import static java.lang.invoke.MethodHandles.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
public
class
PermuteArgsTest
{
private
static
final
Class
CLASS
=
PermuteArgsTest
.
class
;
private
static
final
Class
<?>
CLASS
=
PermuteArgsTest
.
class
;
private
static
final
int
MAX_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".MAX_ARITY"
,
8
);
private
static
final
boolean
DRY_RUN
=
Boolean
.
getBoolean
(
CLASS
.
getSimpleName
()+
".DRY_RUN"
);
private
static
final
boolean
VERBOSE
=
Boolean
.
getBoolean
(
CLASS
.
getSimpleName
()+
".VERBOSE"
)
||
DRY_RUN
;
...
...
@@ -99,12 +99,12 @@ public class PermuteArgsTest {
return
Arrays
.
asList
(
w
,
x
,
y
,
z
);
}
static
Object
listI_etc
(
int
...
va
)
{
ArrayList
<
Object
>
res
=
new
ArrayList
<
Object
>();
ArrayList
<
Object
>
res
=
new
ArrayList
<>();
for
(
int
x
:
va
)
res
.
add
(
x
);
return
res
;
}
static
Object
listIJL_etc
(
int
x
,
long
y
,
Object
z
,
Object
...
va
)
{
ArrayList
<
Object
>
res
=
new
ArrayList
<
Object
>();
ArrayList
<
Object
>
res
=
new
ArrayList
<>();
res
.
addAll
(
Arrays
.
asList
(
x
,
y
,
z
));
res
.
addAll
(
Arrays
.
asList
(
va
));
return
res
;
...
...
@@ -168,7 +168,7 @@ public class PermuteArgsTest {
mh1
=
adjustArity
(
mh
,
arity
);
}
catch
(
IllegalArgumentException
ex
)
{
System
.
out
.
println
(
"*** mh = "
+
name
+
" : "
+
mh
+
"; arity = "
+
arity
+
" => "
+
ex
);
ex
.
printStackTrace
();
ex
.
printStackTrace
(
System
.
out
);
break
;
// cannot get this arity for this type
}
test
(
"("
+
arity
+
")"
+
name
,
mh1
);
...
...
@@ -213,7 +213,7 @@ public class PermuteArgsTest {
}
static
void
testPermutations
(
MethodHandle
mh
)
throws
Throwable
{
HashSet
<
String
>
done
=
new
HashSet
<
String
>();
HashSet
<
String
>
done
=
new
HashSet
<>();
MethodType
mt
=
mh
.
type
();
int
[]
perm
=
nullPerm
(
mt
.
parameterCount
());
final
int
MARGIN
=
(
perm
.
length
<=
10
?
2
:
0
);
...
...
@@ -326,8 +326,8 @@ public class PermuteArgsTest {
Class
<?>
pt
=
ptypes
[
i
];
Object
arg
;
if
(
pt
==
Void
.
class
)
arg
=
null
;
else
if
(
pt
==
int
.
class
)
arg
=
(
int
)
i
+
101
;
else
if
(
pt
==
long
.
class
)
arg
=
(
long
)
i
+
10_000_000_001L
;
else
if
(
pt
==
int
.
class
)
arg
=
i
+
101
;
else
if
(
pt
==
long
.
class
)
arg
=
i
+
10_000_000_001L
;
else
arg
=
"#"
+
(
i
+
1
);
args
[
i
]
=
arg
;
}
...
...
test/java/lang/invoke/RicochetTest.java
浏览文件 @
5bb0a44f
...
...
@@ -40,7 +40,6 @@ import org.junit.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
import
static
java
.
lang
.
invoke
.
MethodHandles
.*;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
junit
.
Assume
.*;
/**
...
...
@@ -48,7 +47,7 @@ import static org.junit.Assume.*;
* @author jrose
*/
public
class
RicochetTest
{
private
static
final
Class
CLASS
=
RicochetTest
.
class
;
private
static
final
Class
<?>
CLASS
=
RicochetTest
.
class
;
private
static
final
int
MAX_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".MAX_ARITY"
,
40
);
public
static
void
main
(
String
...
av
)
throws
Throwable
{
...
...
@@ -148,7 +147,7 @@ public class RicochetTest {
for
(
int
nargs
=
0
;
nargs
<=
MAX
;
nargs
++)
{
if
(
nargs
>
30
&&
nargs
<
MAX
-
20
)
nargs
+=
10
;
int
[]
args
=
new
int
[
nargs
];
for
(
int
j
=
0
;
j
<
args
.
length
;
j
++)
args
[
j
]
=
(
int
)(
j
+
11
)
;
for
(
int
j
=
0
;
j
<
args
.
length
;
j
++)
args
[
j
]
=
j
+
11
;
//System.out.println("testIntSpreads "+Arrays.toString(args));
int
[]
args1
=
(
int
[])
id
.
invokeExact
(
args
);
assertArrayEquals
(
args
,
args1
);
...
...
@@ -388,6 +387,7 @@ public class RicochetTest {
java
.
util
.
Random
random
;
final
MethodHandle
[]
fns
;
int
depth
;
@SuppressWarnings
(
"LeakingThisInConstructor"
)
RFCB
(
int
seed
)
throws
Throwable
{
this
.
random
=
new
java
.
util
.
Random
(
seed
);
this
.
fns
=
new
MethodHandle
[
Math
.
max
(
29
,
(
1
<<
MAX_DEPTH
-
2
)/
3
)];
...
...
@@ -408,7 +408,7 @@ public class RicochetTest {
case
1
:
Throwable
ex
=
new
RuntimeException
();
ex
.
fillInStackTrace
();
if
(
VERBOSITY
>=
2
)
ex
.
printStackTrace
();
if
(
VERBOSITY
>=
2
)
ex
.
printStackTrace
(
System
.
out
);
x
=
"ST; "
+
x
;
break
;
case
2
:
...
...
@@ -467,7 +467,7 @@ public class RicochetTest {
return
mh
.
invokeWithArguments
(
args
);
}
catch
(
Throwable
ex
)
{
System
.
out
.
println
(
"threw: "
+
mh
+
Arrays
.
asList
(
args
));
ex
.
printStackTrace
();
ex
.
printStackTrace
(
System
.
out
);
return
ex
;
}
}
...
...
@@ -515,8 +515,8 @@ public class RicochetTest {
private
static
long
opJ
(
long
x
)
{
return
(
long
)
opI
((
int
)
x
);
}
private
static
Object
opL2
(
Object
x
,
Object
y
)
{
return
(
Object
)
opI2
((
int
)
x
,
(
int
)
y
);
}
private
static
Object
opL
(
Object
x
)
{
return
(
Object
)
opI
((
int
)
x
);
}
private
static
int
opL2_I
(
Object
x
,
Object
y
)
{
return
(
int
)
opI2
((
int
)
x
,
(
int
)
y
);
}
private
static
int
opL_I
(
Object
x
)
{
return
(
int
)
opI
((
int
)
x
);
}
private
static
int
opL2_I
(
Object
x
,
Object
y
)
{
return
opI2
((
int
)
x
,
(
int
)
y
);
}
private
static
int
opL_I
(
Object
x
)
{
return
opI
((
int
)
x
);
}
private
static
long
opL_J
(
Object
x
)
{
return
(
long
)
opI
((
int
)
x
);
}
private
static
final
MethodHandle
opI
,
opI2
,
opI3
,
opI4
,
opI_L
,
opJ
,
opJ2
,
opJ3
,
opL2
,
opL
,
opL2_I
,
opL_I
,
opL_J
;
static
{
...
...
@@ -570,8 +570,8 @@ public class RicochetTest {
INT_LISTERS
[
i
]
=
lister
;
LONG_LISTERS
[
i
]
=
llister
;
if
(
i
==
0
)
break
;
lister
=
insertArguments
(
lister
,
i
-
1
,
(
int
)
0
);
llister
=
insertArguments
(
llister
,
i
-
1
,
(
long
)
0
);
lister
=
insertArguments
(
lister
,
i
-
1
,
0
);
llister
=
insertArguments
(
llister
,
i
-
1
,
0L
);
}
}
...
...
test/java/lang/invoke/ThrowExceptionsTest.java
浏览文件 @
5bb0a44f
...
...
@@ -40,7 +40,7 @@ import static java.lang.invoke.MethodHandles.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
public
class
ThrowExceptionsTest
{
private
static
final
Class
CLASS
=
ThrowExceptionsTest
.
class
;
private
static
final
Class
<?>
CLASS
=
ThrowExceptionsTest
.
class
;
private
static
final
Lookup
LOOKUP
=
lookup
();
public
static
void
main
(
String
argv
[])
throws
Throwable
{
...
...
@@ -132,9 +132,9 @@ public class ThrowExceptionsTest {
int
tc
=
testCases
;
try
{
m
.
invoke
(
this
);
}
catch
(
Throwable
ex
)
{
}
catch
(
IllegalAccessException
|
IllegalArgumentException
|
InvocationTargetException
ex
)
{
System
.
out
.
println
(
"*** "
+
ex
);
ex
.
printStackTrace
();
ex
.
printStackTrace
(
System
.
out
);
}
if
(
testCases
==
tc
)
testCases
++;
}
...
...
test/javax/swing/JSplitPane/4885629/bug4885629.java
0 → 100644
浏览文件 @
5bb0a44f
/*
* 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4885629
* @summary With JSplitPane in VERTICAL_SPLIT, SplitPaneBorder draws bottom edge of divider
* @author Andrey Pikalev
*/
import
sun.awt.SunToolkit
;
import
javax.swing.*
;
import
javax.swing.border.Border
;
import
javax.swing.border.EmptyBorder
;
import
javax.swing.plaf.basic.BasicBorders
;
import
javax.swing.plaf.basic.BasicLookAndFeel
;
import
javax.swing.plaf.basic.BasicSplitPaneUI
;
import
java.awt.*
;
public
class
bug4885629
{
private
static
final
Color
darkShadow
=
new
Color
(
100
,
120
,
200
);
private
static
final
Color
darkHighlight
=
new
Color
(
200
,
120
,
50
);
private
static
final
Color
lightHighlight
=
darkHighlight
.
brighter
();
private
static
final
Color
BGCOLOR
=
Color
.
blue
;
private
static
JSplitPane
sp
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
UIManager
.
setLookAndFeel
(
new
BasicLookAndFeel
()
{
public
boolean
isSupportedLookAndFeel
(){
return
true
;
}
public
boolean
isNativeLookAndFeel
(){
return
false
;
}
public
String
getDescription
()
{
return
"Foo"
;
}
public
String
getID
()
{
return
"FooID"
;
}
public
String
getName
()
{
return
"FooName"
;
}
});
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
public
void
run
()
{
JFrame
frame
=
new
JFrame
();
JComponent
a
=
new
JPanel
();
a
.
setBackground
(
Color
.
white
);
a
.
setMinimumSize
(
new
Dimension
(
10
,
10
));
JComponent
b
=
new
JPanel
();
b
.
setBackground
(
Color
.
white
);
b
.
setMinimumSize
(
new
Dimension
(
10
,
10
));
sp
=
new
JSplitPane
(
JSplitPane
.
VERTICAL_SPLIT
,
a
,
b
);
sp
.
setPreferredSize
(
new
Dimension
(
20
,
20
));
sp
.
setBackground
(
BGCOLOR
);
Border
bo
=
new
BasicBorders
.
SplitPaneBorder
(
lightHighlight
,
Color
.
red
);
Border
ibo
=
new
EmptyBorder
(
0
,
0
,
0
,
0
);
sp
.
setBorder
(
bo
);
sp
.
setMinimumSize
(
new
Dimension
(
200
,
200
));
((
BasicSplitPaneUI
)
sp
.
getUI
()).
getDivider
().
setBorder
(
ibo
);
frame
.
getContentPane
().
setLayout
(
new
FlowLayout
());
frame
.
getContentPane
().
setBackground
(
darkShadow
);
frame
.
getContentPane
().
add
(
sp
);
frame
.
setSize
(
200
,
200
);
frame
.
setDefaultCloseOperation
(
JFrame
.
EXIT_ON_CLOSE
);
frame
.
setVisible
(
true
);
}
});
((
SunToolkit
)
SunToolkit
.
getDefaultToolkit
()).
realSync
();
final
Robot
robot
=
new
Robot
();
robot
.
delay
(
1000
);
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
public
void
run
()
{
Rectangle
rect
=
((
BasicSplitPaneUI
)
sp
.
getUI
()).
getDivider
().
getBounds
();
Point
p
=
rect
.
getLocation
();
SwingUtilities
.
convertPointToScreen
(
p
,
sp
);
for
(
int
i
=
0
;
i
<
rect
.
width
;
i
++)
{
if
(!
BGCOLOR
.
equals
(
robot
.
getPixelColor
(
p
.
x
+
i
,
p
.
y
+
rect
.
height
-
1
)))
{
throw
new
Error
(
"The divider's area has incorrect color."
);
}
}
}
});
}
}
test/javax/swing/JTextArea/4697612/bug4697612.java
0 → 100644
浏览文件 @
5bb0a44f
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4697612 6244705
* @author Peter Zhelezniakov
* @library ../../regtesthelpers
* @build Util
* @run main bug4697612
*/
import
java.io.*
;
import
java.awt.*
;
import
java.awt.event.*
;
import
javax.swing.*
;
import
javax.swing.text.BadLocationException
;
import
sun.awt.SunToolkit
;
public
class
bug4697612
{
static
final
int
FRAME_WIDTH
=
300
;
static
final
int
FRAME_HEIGHT
=
300
;
static
final
int
FONT_HEIGHT
=
16
;
private
static
volatile
int
frameHeight
;
private
static
volatile
int
fontHeight
;
private
static
JFrame
frame
;
private
static
JTextArea
text
;
private
static
JScrollPane
scroller
;
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
SunToolkit
toolkit
=
(
SunToolkit
)
Toolkit
.
getDefaultToolkit
();
Robot
robot
=
new
Robot
();
robot
.
setAutoDelay
(
100
);
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
createAndShowGUI
();
}
});
toolkit
.
realSync
();
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
text
.
requestFocus
();
}
});
toolkit
.
realSync
();
// 4697612: pressing PgDn + PgUp should not alter caret position
Util
.
hitKeys
(
robot
,
KeyEvent
.
VK_HOME
);
Util
.
hitKeys
(
robot
,
KeyEvent
.
VK_PAGE_DOWN
);
int
pos0
=
getTextCaretPosition
();
int
caretHeight
=
getTextCaretHeight
();
fontHeight
=
FONT_HEIGHT
;
// iterate two times, for different (even and odd) font height
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
public
void
run
()
{
text
.
setFont
(
text
.
getFont
().
deriveFont
(
fontHeight
));
}
});
frameHeight
=
FRAME_HEIGHT
;
for
(
int
j
=
0
;
j
<
caretHeight
;
j
++)
{
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
public
void
run
()
{
frame
.
setSize
(
FRAME_WIDTH
,
frameHeight
);
}
});
toolkit
.
realSync
();
Util
.
hitKeys
(
robot
,
KeyEvent
.
VK_PAGE_DOWN
);
Util
.
hitKeys
(
robot
,
KeyEvent
.
VK_PAGE_UP
);
toolkit
.
realSync
();
int
pos
=
getTextCaretPosition
();
if
(
pos0
!=
pos
)
{
throw
new
RuntimeException
(
"Failed 4697612: PgDn & PgUp keys scroll by different amounts"
);
}
frameHeight
++;
}
fontHeight
++;
}
// 6244705: pressing PgDn at the very bottom should not scroll
LookAndFeel
laf
=
UIManager
.
getLookAndFeel
();
if
(
laf
.
getID
().
equals
(
"Aqua"
))
{
Util
.
hitKeys
(
robot
,
KeyEvent
.
VK_END
);
}
else
{
Util
.
hitKeys
(
robot
,
KeyEvent
.
VK_CONTROL
,
KeyEvent
.
VK_END
);
}
toolkit
.
realSync
();
pos0
=
getScrollerViewPosition
();
Util
.
hitKeys
(
robot
,
KeyEvent
.
VK_PAGE_DOWN
);
toolkit
.
realSync
();
int
pos
=
getScrollerViewPosition
();
if
(
pos0
!=
pos
)
{
throw
new
RuntimeException
(
"Failed 6244705: PgDn at the bottom causes scrolling"
);
}
}
private
static
int
getTextCaretPosition
()
throws
Exception
{
final
int
[]
result
=
new
int
[
1
];
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
result
[
0
]
=
text
.
getCaretPosition
();
}
});
return
result
[
0
];
}
private
static
int
getTextCaretHeight
()
throws
Exception
{
final
int
[]
result
=
new
int
[
1
];
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
int
pos0
=
text
.
getCaretPosition
();
Rectangle
dotBounds
=
text
.
modelToView
(
pos0
);
result
[
0
]
=
dotBounds
.
height
;
}
catch
(
BadLocationException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
});
return
result
[
0
];
}
private
static
int
getScrollerViewPosition
()
throws
Exception
{
final
int
[]
result
=
new
int
[
1
];
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
result
[
0
]
=
scroller
.
getViewport
().
getViewPosition
().
y
;
}
});
return
result
[
0
];
}
private
static
void
createAndShowGUI
()
{
frame
=
new
JFrame
();
frame
.
setSize
(
FRAME_WIDTH
,
FRAME_HEIGHT
);
frame
.
setDefaultCloseOperation
(
JFrame
.
EXIT_ON_CLOSE
);
text
=
new
JTextArea
();
try
{
InputStream
is
=
bug4697612
.
class
.
getResourceAsStream
(
"bug4697612.txt"
);
text
.
read
(
new
InputStreamReader
(
is
),
null
);
}
catch
(
IOException
e
)
{
throw
new
Error
(
e
);
}
scroller
=
new
JScrollPane
(
text
);
frame
.
getContentPane
().
add
(
scroller
);
frame
.
pack
();
frame
.
setVisible
(
true
);
}
}
test/javax/swing/JTextArea/4697612/bug4697612.txt
0 → 100644
浏览文件 @
5bb0a44f
README
Java(TM) 2 SDK, Standard Edition
Version 1.4.2 Beta
For a more extensive HTML version of this file, see README.html.
Contents
* Introduction
* Release Notes
* Bug Reports and Feedback
* Java 2 SDK Documentation
* Redistribution
* Web Pages
Introduction
Thank you for downloading this release of the Java(TM) 2 SDK,
Standard Edition. The Java 2 SDK is a development environment for
building applications, applets, and components that can be
deployed on the Java platform.
The Java 2 SDK software includes tools useful for developing and
testing programs written in the Java programming language and
running on the Java platform. These tools are designed to be used
from the command line. Except for appletviewer, these tools do not
provide a graphical user interface.
Release Notes
See the Release Notes on the Java Software web site for additional
information pertaining to this release.
http://java.sun.com/j2se/1.4.2/relnotes.html
The on-line release notes will be updated as needed, so you should
check it occasionally for the latest information.
Bug Reports and Feedback
The Bug Parade Web Page on the Java Developer Connection(SM) web
site lets you search for and examine existing bug reports, submit
your own bug reports, and tell us which bug fixes matter most to you.
http://java.sun.com/jdc/bugParade/
To directly submit a bug or request a feature, fill out this form:
http://java.sun.com/cgi-bin/bugreport.cgi
You can also send comments directly to Java Software engineering
team email addresses.
http://java.sun.com/mail/
Java 2 SDK Documentation
The on-line Java 2 SDK Documentation contains API specifications,
feature descriptions, developer guides, tool reference pages, demos,
and links to related information. It is located at
http://java.sun.com/j2se/1.4.2/docs/
The Java 2 SDK documentation is also available in a download bundle
which you can install locally on your machine. See the
Java 2 SDK download page:
http://java.sun.com/j2se/1.4.2/download.html
Redistribution
The term "vendors" used here refers to licensees, developers,
and independent software vendors (ISVs) who license and
distribute the Java 2 Runtime Environment with their programs.
Vendors must follow the terms of the Java 2 SDK, Standard
Edition, Binary Code License agreement.
Required vs. Optional Files
The files that make up the Java 2 SDK, Standard Edition, are
divided into two categories: required and optional. Optional
files may be excluded from redistributions of the Java 2 SDK
at the vendor's discretion. The following section contains a
list of the files and directories that may optionally be
omitted from redistributions of the Java 2 SDK. All files not
in these lists of optional files must be included in
redistributions of the Java 2 SDK.
Optional Files and Directories
The following files may be optionally excluded from
redistributions:
jre/lib/charsets.jar
Character conversion classes
jre/lib/ext/
sunjce_provider.jar - the SunJCE provider for Java
Cryptography APIs
localedata.jar - contains many of the resources
needed for non US English locales
ldapsec.jar - contains security features supported
by the LDAP service provider
dnsns.jar - for the InetAddress wrapper of JNDI DNS
provider
bin/rmid and jre/bin/rmid
Java RMI Activation System Daemon
bin/rmiregistry and jre/bin/rmiregistry
Java Remote Object Registry
bin/tnameserv and jre/bin/tnameserv
Java IDL Name Server
bin/keytool and jre/bin/keytool
Key and Certificate Management Tool
bin/kinit and jre/bin/kinit
Used to obtain and cache Kerberos ticket-granting tickets
bin/klist and jre/bin/klist
Kerberos display entries in credentials cache and keytab
bin/ktab and jre/bin/ktab
Kerberos key table manager
bin/policytool and jre/bin/policytool
Policy File Creation and Management Tool
bin/orbd and jre/bin/orbd
Object Request Broker Daemon
bin/servertool and jre/bin/servertool
Java IDL Server Tool
src.zip
Archive of source files
In addition, the Java Web Start product may be excluded from
redistributions. The Java Web Start product is contained in a
file named javaws-1_2-solaris-sparc-i.zip,
javaws-1_2-solaris-i586-i.zip,
javaws-1_2-linux-i586-i.zip, or
javaws-1_2-windows-i586-i.exe, depending on the platform.
Unlimited Strength Java Cryptography Extension
Due to import control restrictions for some countries, the
Java Cryptography Extension (JCE) policy files shipped with
the Java 2 SDK, Standard Edition and the Java 2 Runtime
Environment allow strong but limited cryptography to be
used. These files are located at
<java-home>/lib/security/local_policy.jar
<java-home>/lib/security/US_export_policy.jar
where <java-home> is the jre directory of the Java 2
SDK or the top-level directory of the Java 2 Runtime
Environment.
An unlimited strength version of these files indicating
no restrictions on cryptographic strengths is available
on the Java 2 SDK web site for those living in eligible
countries. Those living in eligible countries may download
the unlimited strength version and replace the strong
cryptography jar files with the unlimited strength files.
Endorsed Standards Override Mechanism
An endorsed standard is a Java API defined through a standards
process other than the Java Community Process(SM) (JCP(SM)).
Because endorsed standards are defined outside the JCP, it is
anticipated that such standards will be revised between
releases of the Java 2 Platform. In order to take advantage of
new revisions to endorsed standards, developers and software
vendors may use the Endorsed Standards Override Mechanism to
provide newer versions of an endorsed standard than those
included in the Java 2 Platform as released by Sun Microsystems.
For more information on the Endorsed Standards Override
Mechanism, including the list of platform packages that it may
be used to override, see
http://java.sun.com/j2se/1.4.2/docs/guide/standards/
Classes in the packages listed on that web page may be replaced
only by classes implementing a more recent version of the API
as defined by the appropriate standards body.
In addition to the packages listed in the document at the above
URL, which are part of the Java 2 Platform, Standard Edition
(J2SE(TM)) specification, redistributors of Sun's J2SE
Reference Implementation are allowed to override classes whose
sole purpose is to implement the functionality provided by
public APIs defined in these Endorsed Standards packages.
Redistributors may also override classes in the org.w3c.dom.*
packages, or other classes whose sole purpose is to implement
these APIs.
Sun Java Web Pages
For additional information, refer to these Sun Microsystems pages
on the World Wide Web:
http://java.sun.com/
The Java Software web site, with the latest information on
Java technology, product information, news, and features.
http://java.sun.com/docs
Java Platform Documentation provides access to white papers,
the Java Tutorial and other documents.
http://java.sun.com/jdc
The Java Developer Connection(SM) web site. (Free registration
required.) Additional technical information, news, and
features; user forums; support information, and much more.
http://java.sun.com/products/
Java Technology Products & API
------------------------------------------------------------------------
The Java 2 SDK, Standard Edition, is a product of Sun Microsystems(TM),
Inc. This product includes code licensed from RSA Security.
Copyright 2003 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
California 95054, U.S.A. All rights reserved.
test/javax/swing/JTree/6505523/bug6505523.java
0 → 100644
浏览文件 @
5bb0a44f
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6505523
* @summary NullPointerException in BasicTreeUI when a node is removed by expansion listener
* @author Alexandr Scherbatiy
* @run main bug6505523
*/
import
java.awt.Point
;
import
java.awt.Rectangle
;
import
java.awt.Robot
;
import
java.awt.Toolkit
;
import
java.awt.event.InputEvent
;
import
javax.swing.JFrame
;
import
javax.swing.JScrollPane
;
import
javax.swing.JTree
;
import
javax.swing.SwingUtilities
;
import
javax.swing.event.TreeExpansionEvent
;
import
javax.swing.event.TreeExpansionListener
;
import
javax.swing.tree.DefaultMutableTreeNode
;
import
javax.swing.tree.DefaultTreeModel
;
import
javax.swing.tree.TreeNode
;
import
sun.awt.SunToolkit
;
public
class
bug6505523
{
private
static
JTree
tree
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
SunToolkit
toolkit
=
(
SunToolkit
)
Toolkit
.
getDefaultToolkit
();
Robot
robot
=
new
Robot
();
robot
.
setAutoDelay
(
50
);
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
createAndShowGUI
();
}
});
toolkit
.
realSync
();
Point
point
=
getRowPointToClick
(
2
);
robot
.
mouseMove
(
point
.
x
,
point
.
y
);
robot
.
mousePress
(
InputEvent
.
BUTTON1_MASK
);
robot
.
mouseRelease
(
InputEvent
.
BUTTON1_MASK
);
toolkit
.
realSync
();
}
private
static
Point
getRowPointToClick
(
final
int
row
)
throws
Exception
{
final
Point
[]
result
=
new
Point
[
1
];
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
Rectangle
rect
=
tree
.
getRowBounds
(
row
);
Point
point
=
new
Point
(
rect
.
x
-
5
,
rect
.
y
+
rect
.
height
/
2
);
SwingUtilities
.
convertPointToScreen
(
point
,
tree
);
result
[
0
]
=
point
;
}
});
return
result
[
0
];
}
private
static
void
createAndShowGUI
()
{
final
DefaultMutableTreeNode
root
=
new
DefaultMutableTreeNode
(
"Problem with NPE under JDK 1.6"
);
final
DefaultMutableTreeNode
problematic
=
new
DefaultMutableTreeNode
(
"Expand me and behold a NPE in stderr"
);
problematic
.
add
(
new
DefaultMutableTreeNode
(
"some content"
));
root
.
add
(
new
DefaultMutableTreeNode
(
"irrelevant..."
));
root
.
add
(
problematic
);
final
DefaultTreeModel
model
=
new
DefaultTreeModel
(
root
);
tree
=
new
JTree
(
model
);
tree
.
setRootVisible
(
true
);
tree
.
setShowsRootHandles
(
true
);
tree
.
expandRow
(
0
);
tree
.
collapseRow
(
2
);
// this is critical - without dragEnabled everything works
tree
.
setDragEnabled
(
true
);
tree
.
addTreeExpansionListener
(
new
TreeExpansionListener
()
{
@Override
public
void
treeExpanded
(
TreeExpansionEvent
event
)
{
TreeNode
parent
=
problematic
.
getParent
();
if
(
parent
instanceof
DefaultMutableTreeNode
)
{
model
.
removeNodeFromParent
(
problematic
);
}
}
@Override
public
void
treeCollapsed
(
TreeExpansionEvent
event
)
{
}
});
JFrame
frame
=
new
JFrame
(
"JTree Problem"
);
frame
.
add
(
new
JScrollPane
(
tree
));
frame
.
setSize
(
500
,
300
);
frame
.
setDefaultCloseOperation
(
JFrame
.
EXIT_ON_CLOSE
);
frame
.
setLocationRelativeTo
(
null
);
frame
.
setVisible
(
true
);
}
}
\ No newline at end of file
test/sun/invoke/util/ValueConversionsTest.java
浏览文件 @
5bb0a44f
...
...
@@ -27,11 +27,9 @@ import sun.invoke.util.ValueConversions;
import
sun.invoke.util.Wrapper
;
import
java.lang.invoke.MethodType
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandles
;
import
java.io.Serializable
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
...
...
@@ -52,7 +50,7 @@ import static org.junit.Assert.*;
* @author jrose
*/
public
class
ValueConversionsTest
{
private
static
final
Class
CLASS
=
ValueConversionsTest
.
class
;
private
static
final
Class
<?>
CLASS
=
ValueConversionsTest
.
class
;
private
static
final
int
MAX_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".MAX_ARITY"
,
40
);
private
static
final
int
START_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".START_ARITY"
,
0
);
private
static
final
boolean
EXHAUSTIVE
=
Boolean
.
getBoolean
(
CLASS
.
getSimpleName
()+
".EXHAUSTIVE"
);
...
...
@@ -165,7 +163,7 @@ public class ValueConversionsTest {
Object
expResult
=
box
;
Object
result
=
null
;
switch
(
w
)
{
case
INT:
result
=
boxer
.
invokeExact
(
(
int
)
n
);
break
;
case
INT:
result
=
boxer
.
invokeExact
(
/*int*/
n
);
break
;
case
LONG:
result
=
boxer
.
invokeExact
((
long
)
n
);
break
;
case
FLOAT:
result
=
boxer
.
invokeExact
((
float
)
n
);
break
;
case
DOUBLE:
result
=
boxer
.
invokeExact
((
double
)
n
);
break
;
...
...
@@ -361,6 +359,7 @@ public class ValueConversionsTest {
assert
(
stype
==
MethodType
.
methodType
(
arrayType
,
arrayType
));
if
(
nargs
<=
5
)
{
// invoke target as a spreader also:
@SuppressWarnings
(
"cast"
)
Object
res2
=
spreader
.
invokeWithArguments
((
Object
)
res
);
String
res2String
=
toArrayString
(
res2
);
assertEquals
(
Arrays
.
toString
(
args
),
res2String
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录